Rendering REALLY slowly?

Started by
10 comments, last by Seroja 18 years, 10 months ago
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...
Advertisement
If the code is small enough maybe you can post it?

That is ridiculous I agree... Sounds like it's running in software mode
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 :)
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; j++)		{			glBegin(GL_QUADS);				glTexCoord2f(0.55f, 0.05f); glVertex3f(PolyXa[j], PolyYa[j], PolyZa[j]);				glTexCoord2f(0.55f, 0.45f); glVertex3f(PolyXb[j], PolyYb[j], PolyZb[j]);				glTexCoord2f(0.95f, 0.45f); glVertex3f(PolyXc[j], PolyYc[j], PolyZc[j]);				glTexCoord2f(0.95f, 0.05f); glVertex3f(PolyXd[j], PolyYd[j], PolyZd[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. :)
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. ;)
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; 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.
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.
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.
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.
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.


This topic is closed to new replies.

Advertisement