Low FPS and texture problems

Started by
20 comments, last by brucesinner 20 years, 10 months ago
Hi folks, I'm currently developing some sort of human animation and i'm using old Quake 2 animation style. (based on keyframes and linear interpolating between them). The problem is that when I only render the animated model i'm getting only 15 fps on a Geforce 4 MX440. Then i started to draw some other models like table, lamps, couch...but then the frame rate dropped to 9. I've applied a TGA texture to the floor and backwalls and so my fps is now 1-2 !!! My model is a hi-poly one, it has kind of 15000 verts and about 24000-25000 faces...Below is the code how I'm drawing the models.

void CSMFModel::RenderModel()
{

	float t;

	CSMFFrame *pCurrentFrame; /// this holds the current frame of the animation

	CSMFFrame *pNextFrame;	/// this holds the next frame (the one we will interpolate to)


	/// gets next frame of animation

	int nextFrame = (this->currentFrame + 1) % this->numOfFrames;

	/// gets the current frame

	pCurrentFrame = &(this->pFrames[this->currentFrame]);
	/// gets next frame (the one we will interpolate to)

	pNextFrame	  = &(this->pFrames[nextFrame]);

	t = ReturnCurrentTime(nextFrame);	

	/// iterate through all the nodes rendering its triangles

	for (int n=0; n<pCurrentFrame->numOfNodes; n++)
	{

		/// tests to see if the node list isn't empty

		if (pCurrentFrame->pNodes.size() <= 0) break;

		/// gets the current node

		CSMFNode *pCurrentNode = &pCurrentFrame->pNodes[n];
		CSMFNode *pNextNode = &pNextFrame->pNodes[n];

		/// go through all the faces rendering its associated vertices

		for (int j=0; j<pCurrentNode->numOfFaces; j++)
		{
			glBegin(GL_TRIANGLES);
			for (int vIndex=0; vIndex < 3; vIndex++)
			{
				long index  = pCurrentNode->pFaces[j].vertIndex[vIndex]-1;
				long nindex = pCurrentNode->pFaces[j].vertIndex[vIndex]-1;

				glNormal3f( pCurrentNode->pNormals[ index ].x + t * (pNextNode->pNormals[ nindex ].x - pCurrentNode->pNormals[ index ].x),	
					        pCurrentNode->pNormals[ index ].y + t * (pNextNode->pNormals[ nindex ].y - pCurrentNode->pNormals[ index ].y), 
							pCurrentNode->pNormals[ index ].z + t * (pNextNode->pNormals[ nindex ].z - pCurrentNode->pNormals[ index ].z));
				glVertex3f( pCurrentNode->pVertex[ index ].x + t * (pNextNode->pVertex[ nindex ].x - pCurrentNode->pVertex[ index ].x), 	
					        pCurrentNode->pVertex[ index ].y + t * (pNextNode->pVertex[ nindex ].y - pCurrentNode->pVertex[ index ].y), 
							pCurrentNode->pVertex[ index ].z + t * (pNextNode->pVertex[ nindex ].z - pCurrentNode->pVertex[ index ].z));
			}
			glEnd();
		}

	}


}
Here is a screenshot of the rendered scene. One thing I'm with doubts is about texturing... When I've glBinded the texture then draw the floor, the following triangles I've drawn later had "absorbed" the texture's color (brown)...so I put this after the glBegin/glEnd that draws the floor: glBindTexture(GL_TEXTURE_2D, 0); It looked like i've reset the texture bind... So its the correct way of doing this? Thanks people... Bruce [edited by - brucesinner on June 4, 2003 3:51:21 PM]
"Steel and Fire,Spreading the Holy Word,Dirty Liars,The truth has never been told" - Primal Fear
Advertisement
The first thing is to call glBegin/glEnd only once. Just call glBegin when you start rendering your model and glEnd when ou finish. This will save you a lot of function call overhead. The next thing you should do is lear how to use vertex arrays. This will simplify this whole code to about 10 lines. It will also give you a nice FPS boost.

About texture "unbinding" : glBindTexture(GL_TEXTURE_2D, 0); is one way but it's considerd bad practice. Much better way is to call glDisable( GL_TEXTURE_2D );

SKSlayer : Those 2 variables in inner loop will not be any problem as compiler will optimize the code to only store them in registers. And the fact they are defined only in inner loop scope gives compiler a bit more hints whare thoes two variables are even needed.

You should never let your fears become the boundaries of your dreams.

[edited by - _DarkWIng_ on June 4, 2003 4:46:47 PM]
You should never let your fears become the boundaries of your dreams.
1st, you are sending your whole model through the AGP port at every frame. You may not render high poly models that way or it will for sure be slow.
2nd, you init 2 vars in a loop which is called several times per seconds, which has a major impact on performance
Those are the 2 major reasons for slowness.

Your screenshot link is dead, make sure to get it alive again
(you can find me on IRC : #opengl on undernet)
_Darkwing_: thanks for the tips, but when I do glDisable(GL_TEXTURE_2D), then the texture doesn''t show at all...

About the vertex arrays...even if I need to do on-the-fly calculations as I''m doing (interpolating I mean), I can use it?

"Steel and Fire,Spreading the Holy Word,Dirty Liars,The truth has never been told" - Primal Fear
I''ve put the glBeing/glEnd out of my loops and I''ve got a gain of 2 FPS. Not bad for a so simple modification.

And about the loss of performance when I draw the textures on screen ? It''s lowering too much...
"Steel and Fire,Spreading the Holy Word,Dirty Liars,The truth has never been told" - Primal Fear
quote:Original post by brucesinner
_Darkwing_: thanks for the tips, but when I do glDisable(GL_TEXTURE_2D), then the texture doesn''t show at all...

About the vertex arrays...even if I need to do on-the-fly calculations as I''m doing (interpolating I mean), I can use it?



I think you misunderstood DarkWing, by glBegin he ment the glBegin(GL_TRIANGLES); call. That call should be out side of the loops.

The texture is all wrong to. When you use glBindTexture(GL_TEXTURE_2D, 0); or glBindTexture(GL_TEXTURE_2D, NULL); no textures will show up. A texture ID has to be a non-zero unique identifier. Use glGenTextures() to get a valid texture ID. The way you have it now it won''t apply a texture, so DarkWing was saying glDisable(GL_TEXTURE_2D); is the same thing, which it is.
Sorry Ultima X, but I think you misundestood it all! :-D

I''m using glBindTexture(GL_TEXTURE_2D, 0) to unbind the texture, of course, I''ve bind it to an ID generate with glGenTextures(), before.

And I do put the glBegin outside my loops now.
I''ve already told that in the last post.

Something like

glBegin(GL_TRIANGLES)
for(...
my loops goes here with calls to glVertex3f
glEnd()

Thats it! I gained 2 fps!
"Steel and Fire,Spreading the Holy Word,Dirty Liars,The truth has never been told" - Primal Fear
After looking at the screen shot I'm curious about something... What your FPS without the actor? The lamps, couch, etc, seem to have a high poly count to. That could be a problem there to.

EDIT: The reason I brought up the texture stuff is because of what you said...

"_Darkwing_: thanks for the tips, but when I do glDisable(GL_TEXTURE_2D), then the texture doesn't show at all..."

So I didn't know you were trying to disable them, from that quote it sounded the other way around?

My bad

-UltimaX-

"You wished for a white christmas... Now go shovel your wishes!"

[edited by - UltimaX on June 4, 2003 5:36:44 PM]
Without the woman:
With the floor and wall textures: only 4-5 FPS
Without textures: 33 FPS

I think if I optimize the woman display with vertex arrays or other thing I''ll get high FPS with her on screen.

I have another thing to mention:

All the models you can see on the screenshot were exported from 3ds MAX to a proprietary format of my own. But when I exported that, the coordinates were so huge... Some vertex were like (200, 80, 430) for example. So my frustum had to be big too.
Something like 1 -> 4000 to accomodate all the models...

The room for example, I had to draw a single cube with all dimensions ranging from 0 to 1 and then scaled to simulate a room. But the glScalef() function was so huge...(2500, 1100, 1500). This can be the reason for the bad performance I''m getting?

But, how can I fix it? My models coordinates already come BIG from the 3ds MAX exporter...
"Steel and Fire,Spreading the Holy Word,Dirty Liars,The truth has never been told" - Primal Fear
If you are using glBindTexture(GL_TEXTURE_2D, 0) to unbind the texture, what are you using to bind it - hopefully glBindTexture(GL_TEXTURE_2D, 1) - not glLoadTexture2D.
You should be doing something like:

if (pCurrentNode->texture_id)   {   glEnable(GL_TEXTURE_2D);   glBindTexture(GL_TEXTURE_2D, pCurrentNode->texture_id);   }else   {   glDisable(GL_TEXTURE_2D);   ... set up object colours here ...   } ... Draw all the object triangles ...// Nice to do this at the end, so textures don't leak// into other graphics ...if (pCurrentNode->texture_id)   glDisable(GL_TEXTURE_2D);


You should not be getting a slowdown with texture, unless you
have an ancient graphics card, ot you load the texture every frame.

[edited by - ChookMaster on June 4, 2003 9:52:35 PM]

This topic is closed to new replies.

Advertisement