Sign in to follow this  
RuneLancer

Rendering REALLY slowly?

Recommended Posts

RuneLancer    253
First some basic specs: I'm coding this on a PIV 3.0Ghz in C++ with an ATI RADEON 9800 Pro. Although my engine is still in its first stages, I'm getting ridiculously slow speeds. Things run somewhere in the 5-8 FPS range. The scene I'm rendering looks like this... 1 texture (128x128) ~45 polygones Smoothshading enabled Backface culling enabled Lighting enabled (no normals yet) I still haven't implanted anything much, so every frame I render the scene via an array in a glBegin()/glEnd() set. Basically I clear the depth and color buffers, set my light's position, bind my texture, and then render my ~45 quads in a for() loop. This occures every frame (as well as the buffers being swapped.) What could be causing such terrible performance? Without the texture it runs at a much more decent speed, but even so, I'd expect at least a reasonably smooth framerate for such a small scene. I understand a display list would be faster, but does it make THAT much of a difference? Seems rather extreme to me...

Share this post


Link to post
Share on other sites
Seroja    280
Check if you have anti-aliasing on. That could bring you from 100FPS down to 1FPS. (That what it does on my good old GeForce2)

Other than that, disable V-Sync, comment out all of the objects and features (to see the black screen). You should get enormous FPS. Then start removing comments, step by step, to see what reaaly slows that down.

Oh, and update drivers :)

Share this post


Link to post
Share on other sites
RuneLancer    253
Well, the code is a little too heavy to post it all, but I'll post the relevant bits.

This is the main rendering bit. Most of it should be pretty obvious; the Poly arrays are just positions and stuff; I intend to have a single 1D array instead of this, but that's another matter. ;)
{
int i,j;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear the screen and the depth buffer.

glLoadIdentity(); // Reset the view to 0,0,0.
glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
gluLookAt(xPos, yPos, zPos,
xRot, yRot, zRot,
0.0f, 1.0f, 0.0f);

glLightfv(GL_LIGHT0, GL_POSITION, lPos);

for(i = 0; i < nTexture; i++)
{
glBindTexture(GL_TEXTURE_2D, Texture[0]);
for(j = 0; j < nPolySet[i]; j++)
{
glBegin(GL_QUADS);
glTexCoord2f(0.55f, 0.05f); glVertex3f(PolyXa[i][j], PolyYa[i][j], PolyZa[i][j]);
glTexCoord2f(0.55f, 0.45f); glVertex3f(PolyXb[i][j], PolyYb[i][j], PolyZb[i][j]);
glTexCoord2f(0.95f, 0.45f); glVertex3f(PolyXc[i][j], PolyYc[i][j], PolyZc[i][j]);
glTexCoord2f(0.95f, 0.05f); glVertex3f(PolyXd[i][j], PolyYd[i][j], PolyZd[i][j]);
glEnd();

}
}

return 0;
}


This is my game loop. f_active is a boolean that is set to false when the game window loses focus or gets minimized, or doesn't need to be updated anymore in any way whatsoever. doXRot() is a function that rotates the camera; right now it just sets up the camera's position. DrawGLScene is, well, the above bit of code.
while(!f_done)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT) f_done = true;
else { TranslateMessage(&msg); DispatchMessage(&msg); }
}
if(f_active)
{
if(!HandleKeys()) return 0;
mEng.doXRot(0.0f);
mEng.DrawGLScene(cPositio);
SwapBuffers(hDC);
}
}


Any other bit of code, I'll gladly provide. :)

Share this post


Link to post
Share on other sites
RuneLancer    253
Holy sh*t! :D

Seems my drivers REALLY weren't up to date. It's running at full speed now. :D

Well, so much for that. Good god, I was SURE they were up to date. Wow. I'm terribly AMAZED at all the stuff I can do with my new drivers. Hehe. :D

Well, thanks to everyone who tried to help. Turns out the code wasn't quite at fault, but rather, the coder. ;)

Share this post


Link to post
Share on other sites
Seroja    280
You have use alpha of 0 in the color, use 1. If you use GL_BLEND and GL_MODULATE (sometime you'll probably have to), your quads should turn transparent.

Now, what causes your problem is your for loop. 45 times glBegin is a really bad idea. Either put glBegin outside of the inner loop:

for(i = 0; i < nTexture; i++)
{
glBindTexture(GL_TEXTURE_2D, Texture[0]);
glBegin(GL_QUADS);
for(j = 0; j < nPolySet[i]; j++)
{
glTexCord2f; glVertex3f;
glTexCord2f; glVertex3f;
glTexCord2f; glVertex3f;
glTexCord2f; glVertex3f;
}
glEnd();
}

Or, event better, put all of that in a display list and every loop call glCallList.

Share this post


Link to post
Share on other sites
Ysaneya    1383
Quote:
Original post by Seroja
Now, what causes your problem is your for loop. 45 times glBegin is a really bad idea.


I generally don't answer this kind of post but really.. if you don't know what you're talking about, don't post. 45 times a glBegin/glEnd pair is nothing for the CPU. If he had millions, maybe. Not 45 calls. Please don't spread misinformations.

Y.

Share this post


Link to post
Share on other sites
Seroja    280
Quote from Red Book -> Programming Tips -> OpenGL Performance Tips:
Quote:

Use a single call to glBegin(GL_TRIANGLES) to draw multiple independent triangles, rather than calling glBegin(GL_TRIANGLES) multiple times, or calling glBegin(GL_POLYGON). Even if only a single triangle is to be drawn, use GL_TRIANGLES rather than GL_POLYGON. Use a single call to glBegin(GL_QUADS) in the same manner, rather than calling glBegin(GL_POLYGON) repeatedly. Likewise, use a single call to glBegin(GL_LINES) to draw multiple independent line segments, rather than calling glBegin(GL_LINES) multiple times.

So that is not nothing. I agree it isn't that much of difference, but still. And it's better to avoid wasted performance, as it sums up, and might cause a great difference with V-Sync enabled.

Share this post


Link to post
Share on other sites
Yann L    1802
Quote:
Original post by Seroja
So that is not nothing. I agree it isn't that much of difference, but still. And it's better to avoid wasted performance, as it sums up, and might cause a great difference with V-Sync enabled.

Don't bother optimizing this, it doesn't matter. In practice, if you draw that many triangles to actually see a difference between individual vs. grouped glBegin() calls, then you shouldn't be using immediate mode anyway.

For something as low as 45 triangles, the difference is infinitesimal for any practically relevant purpose. When drawing GUIs for example - a good candidate for IM use - you'll have tons of redundant glBegin/glEnd pairs. And unless you draw hundreds of windows, they won't matter at all. As soon as you come into polycount regions where it would be noticeable, switch to VBOs or DLs.

Share this post


Link to post
Share on other sites
kburkhart84    3182
Quote:
Original post by Yann L
Quote:
Original post by Seroja
So that is not nothing. I agree it isn't that much of difference, but still. And it's better to avoid wasted performance, as it sums up, and might cause a great difference with V-Sync enabled.

Don't bother optimizing this, it doesn't matter. In practice, if you draw that many triangles to actually see a difference between individual vs. grouped glBegin() calls, then you shouldn't be using immediate mode anyway.

For something as low as 45 triangles, the difference is infinitesimal for any practically relevant purpose. When drawing GUIs for example - a good candidate for IM use - you'll have tons of redundant glBegin/glEnd pairs. And unless you draw hundreds of windows, they won't matter at all. As soon as you come into polycount regions where it would be noticeable, switch to VBOs or DLs.


**The truth, the whole truth, and nothing but the truth**
Immediate mode is the slowest way to draw in OpenGL, but use the right tool for the job. If you only have 45 tris, IM is fine. You said this was for an engine, so I'm assuming you are going to have more polys pretty quickly, so I recommend you get that set up with the VBOs since you already know that you'll need them later. Otherwise, you'll have to change it later when you do get more tris on the screen.

Share this post


Link to post
Share on other sites
zedzeek    528
a reasonable machine can do > 10,000,000 quads a sec in immediate mode (i forget what i tested)
10,000,000/45 = 222,222 fps, obviously youre not gonna get that framerate cause the bottleneck is elsewhere, eg clearing the screen drawing the pixels etc

Share this post


Link to post
Share on other sites
Seroja    280
It's not me coding the game engine, I was just trying to help RuneLancer :)

And well, if there is something not performing the best way it could, and it is EASY to fix it, so why not? On my own experience, if I start neglecting little things I'll end up neglecting serius stuff.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this