Archived

This topic is now archived and is closed to further replies.

Multitexturing HELP! Engine Performance Issue This is stupid

This topic is 5700 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

take a look at the following screenshot. Everything is done the EXACT same in code. If you notice there is a 10 fps drop between screenshots and in one screen the ground is flat and the other the ground has a slight curve to it. From my timing I know that the lost framerate is coming from the actual rendering process. Everything else remains the same. The lighting, textures, and world transformations are precalculated and I know that none of that is causing the slow down. Edit: (This is not accurate, read below for more discriptions of the anomaly) Can anyone tell me why I am loosing 10 fps over something so trivial as changing the color of the vertices. I am doing my own lighting and passing the color values to the vertices via glColor3fv. Any help would be greatly appreciated. Edited by - Xanthen on February 18, 2002 11:54:59 AM

Share this post


Link to post
Share on other sites
I''m just hypothesizing here...

When you change the color, you''re changing your opengl state, which means that you have to pause the pipeline & upload the new color to the graphics card. Thus whenever you change the color you reduce performance slightly because you stall the pipeline on the graphics card.

Of course that''s just a guess.

Share this post


Link to post
Share on other sites
Are you also calling glColor3fv() with constant values in the faster case ? If not, well you have extra function calls...
Are you using the color to modulate the texture ?
Have you looked into vertex/color/normal arrays and glDrawElements() ?
Have you tried display lists ?

Exactly WHAT do you have in your render loop ?

Share this post


Link to post
Share on other sites
Hmmm, alright,
I am really confused about whats going on, I've been working on this for a hour. After writing my question I had a few more ideas to try and they just confused me more.

I changed the function in the precalculated lighting so that all vertices have the same lighting, however that did not change the 10 fps loss, so ... well I'm so lost I don't even know where to begin to look for an answer

Edit:
To answer your questions,
I am calling glColor3fv the exact same number of times and in the same manner in both scenarios.

Yes I am using the color to modulate the texture
I am currently using vertex arrays in both screenshots.
Nothing special was written in the second screenshot.

Edited by - Xanthen on February 17, 2002 12:14:15 AM

Share this post


Link to post
Share on other sites
The problem is amplified when I change the field of view back to normal. The screen is then filled with the terrain and instead of 80 and 90, at 1024x768 is 30 and 40

I removed code that doesnt' run

        
glDisable(GL_BLEND);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_TRUE);
float tslope;

glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_INTERPOLATE_EXT);

glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PRIMARY_COLOR_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);

glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, GL_SRC_ALPHA);

glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, GL_SRC_ALPHA);

glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, GL_SRC_ALPHA);

// TEXTURE-UNIT #1

TexH.SetTextureUnit(1);
glEnable(GL_TEXTURE_2D);

glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_INTERPOLATE_EXT);

glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, GL_SRC_COLOR);

glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_TEXTURE);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, GL_SRC_COLOR);

glTexEnvf (GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, GL_PREVIOUS_EXT);
glTexEnvf (GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, GL_SRC_ALPHA);


glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3,GL_FLOAT,0,RendVert);
TexH.SetTextureUnit(1);
glDisable(GL_TEXTURE_2D);
glFlush();
stime(stimer6);
if (TrisExist1==1)
{
TexH.BindTex(0,16);

glBegin(GL_TRIANGLES);

for (x=0;x<VisX;x++)
for (y=0;y<VisY;y++)
if (VisWorldVisible[x+y*VisX]==1)
if (valt[x][y]==1)
{
tslope=0;
Vert=&RendVert2[x][y];
glTexCoord2f(Vert->s1,Vert->t1);
glColor3fv(&RendVert2[x][y].r);
glArrayElement(y*VisX+x);

glTexCoord2f(Vert->s2,Vert->t1);
glColor3fv(&RendVert2[x+1][y].r);
glArrayElement(y*VisX+x+1);

glTexCoord2f(Vert->s2,Vert->t2);
glColor3fv(&RendVert2[x+1][y+1].r);
glArrayElement((y+1)*VisX+x+1);

glTexCoord2f(Vert->s1,Vert->t1);
glColor3fv(&RendVert2[x][y].r);
glArrayElement(y*VisX+x);

glTexCoord2f(Vert->s2,Vert->t2);
glColor3fv(&RendVert2[x+1][y+1].r);
glArrayElement((y+1)*VisX+x+1);

glTexCoord2f(Vert->s1,Vert->t2);
glColor3fv(&RendVert2[x][y+1].r);
glArrayElement((y+1)*VisX+x);

WorldTriRen+=2;
}
glEnd();
}




Edit:

I have found a major cause but I don't know why this is a problem:

once this code runs once, this problem occurs. If this code never runs it will work fine and then the moment it runs, everything gets screwy again:
this code is located right after glVertexPointer
but doesn't run except in certain circumstances. It does not run when in the scenes that I took the screenshots but it was running in a different scene before that.

        
if (TrisExist2==1)
{
TexH.BindTex(0,0); //Changes to Tex Unit 0 and binds a texture

TexH.BindTex(1,16); //Changes to Tex Unit 1 and binds a texture


glBegin(GL_TRIANGLES);

for (x=0;x<VisX;x++)
for (y=0;y<VisY;y++)
if (VisWorldVisible[x+y*VisX]==1)
if (valt[x][y]==2)
{
tslope=0;
if ((Editor==1) && (DisplayVertices==0))
tslope=TileSlope(Pos.x+x-(VisX/2),Pos.y+y-VisY);
if (tslope<800)
{
Vert=&RendVert2[x][y];
tx=Vert->u1;
ty=Vert->v1;

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,tx+s,ty+s);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s1,Vert->t1);
glColor4fv(&RendVert2[x][y].r);
glArrayElement(y*VisX+x);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,tx+ind-s,ty+s);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s2,Vert->t1);
glColor4fv(&RendVert2[x+1][y].r);
glArrayElement(y*VisX+x+1);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,tx+ind-s,ty+ind-s);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s2,Vert->t2);
glColor4fv(&RendVert2[x+1][y+1].r);
glArrayElement((y+1)*VisX+x+1);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,tx+s,ty+s);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s1,Vert->t1);
glColor4fv(&RendVert2[x][y].r);
glArrayElement(y*VisX+x);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,tx+ind-s,ty+ind-s);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s2,Vert->t2);
glColor4fv(&RendVert2[x+1][y+1].r);
glArrayElement((y+1)*VisX+x+1);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,tx+s,ty+ind-s);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s1,Vert->t2);
glColor4fv(&RendVert2[x][y+1].r);
glArrayElement((y+1)*VisX+x);

WorldTriRen+=2;
}
}
glEnd();
}





Edited by - Xanthen on February 18, 2002 1:27:15 AM

Share this post


Link to post
Share on other sites
I''d tend to agree with sjelkjd. Most GL implementations don''t modify the GFX card state when you call glColor repeatedly with the same parameters.

From your code I can tell you are not using vertex/color/texture arrays properly: use glDrawElements instead of glDrawElement : build an array with all your triangles, associated color and texture coordinates, then do one (1) single call to glDrawElements.

The way you are doing it is even less efficient than calls to glVertex.

Share this post


Link to post
Share on other sites
>>glDrawElements and glDrawElement is used when doing display list<<
aye?

if youre doing mipmapping (or even if u are not)
a drop could be cause the hill is using say 64x64sized textures (cause its closer) + the flat stuff is using 32x32

http://uk.geocities.com/sloppyturds/gotterdammerung.html

Share this post


Link to post
Share on other sites
Oops, a braino, sorry. Yet I really meant glDrawElements (or glDrawArrays if you'd rather use that one).

glArrayElement is meant to be used with combined vertex/color/texture/normal arrays, saving separate function call overhead*. Since you're really only using the vertex arrays, you could as well call glVertex3fv();

* And that's not even guaranteed, cf Red Book p73.

Edited by - Fruny on February 18, 2002 1:45:54 AM

Share this post


Link to post
Share on other sites
from what I understand, the benefit I am gaining is that the vertices are only transformed once. Instead of 6 times if I called each triangle seperately. And since the majority of the processor time lost is in vertex transformation this would be the greatest gain with the least amount of work.

No I do not have mipmapping enabled yet. Keep in mind my new discovery. Before that code runs both scenes run at the same framerate.... in fact 10 fps faster than ever!, but as soon as it runs I loose 10 fps in the flat screen, and 20 fps in a scene with the slow hill.

It has something to do with multitexturing, but my card has the 2 tmus so that shouldn't make a difference, and even stranger that code isn't even running in either of the scenes shown above. although it does run in a previous scene.

Edited by - Xanthen on February 18, 2002 1:59:09 AM

Share this post


Link to post
Share on other sites
Get your documenation right.

glDrawArrays/glDrawElements/glArrayElement are ALL concerned with vertex arrays.

glCallList(s) is display lists.

Also, on your performance views. glArrayElement will generally not save vertex processing time. Primarily because the transform cache is very small. The driver needs to be smart as to reliaise you are calling glArrayElement with the same vertex. Generally i wouldn''t rely on the driver too much. The real optimisation you can do, is before rendering a chunk of verticies that shares the same textures, lock that series of verticies (CVA''s glLockArraysEXT). Then, call glDrawArrays/Elements multiple times changing only the needed texture states and whatever color settings inbetween layers. This is only the tip of a very big iceberg, and i am tired so some of what i said may be wrong.

Share this post


Link to post
Share on other sites
Red Book pp74, 76, 77.

this is also all in MSDN, cept they use glVertexPointerEXT descriptions oddly enough.



Edited by - Smoogle on February 18, 2002 2:27:40 AM

Share this post


Link to post
Share on other sites
I wouldnt be worried about that 10fps, id be worried about getting such a low fps (92.5fps with only 1360 tris???) with so little being rendered (especially with it all precalculated like you said)!

-----------------------
"When I have a problem on an Nvidia, I assume that it is my fault. With anyone else''s drivers, I assume it is their fault" - John Carmack

Share this post


Link to post
Share on other sites
Well, the 10 fps isn't as much at 90 fps, but I'm afraid its much worse than that

When I run at 1024x768, it drops 30 fps and 40 fps, and until i run the second part of the code above it runs at 50 fps
so thats a drop from 50 to 30 fps. And yes it does scale like that.

The reason its only running at 90 fps above is a multitexturing issue which is what I am trying to resolve now. Also those textures are 128x128 with no mipmapping so that is another burden on the fillrate. But normally I run at 1024x768, and from only 1 angle so mipmapping isn't that big of a requirement for this program.

Edit:
Ok I have done some further analysis and have determined the entire problem to be somehow related to these 6 lines of code seen in the second part of code above:

glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s1,Vert->t1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s2,Vert->t1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s2,Vert->t2);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s1,Vert->t1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s2,Vert->t2);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s1,Vert->t2);

If I rem out these lines of code the issue does not occur.
however once they run the performance sucks. However I have found that I can correct the performance by doing this:

glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s1,Vert->t1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s2,Vert->t1);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,Vert->s2,Vert->t2);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0,0);

So its like the remnants of setting the second set of texture coordinates are sticking around even though the second texture units texturing is disabled. However since I have multiple tmus on the video card why would this cause an issue at all?
I can get around the problem by just drawing a really small triangle when I'm all done here, but that doesn't really help me understand what is going on. Anybody have any insight?

Edit:
Even stranger still, I have noticed that the loss of framerate is not immediate but occurs over a period of time, with loss of 7 fps in a matter of seconds but continouosly loses more and more approaching a limit of about 10-12 fps.

And yet more strangeness, once the code above runs again, (the ones without the 0's) The fps loss is reset and again it starts at 53 fps and begins its approach to 30 fps.



Edited by - Xanthen on February 18, 2002 12:04:18 PM

Share this post


Link to post
Share on other sites
mate looking at your code youre doing some strange things, check out documents about vertex arrays + multitexture or look at other ppls code

http://uk.geocities.com/sloppyturds/gotterdammerung.html

Share this post


Link to post
Share on other sites
quote:
Original post by Xanthen
So its like the remnants of setting the second set of texture coordinates are sticking around even though the second texture units texturing is disabled. However since I have multiple tmus on the video card why would this cause an issue at all?
I can get around the problem by just drawing a really small triangle when I''m all done here, but that doesn''t really help me understand what is going on. Anybody have any insight?



You''re making unnecessary GL calls and you''re surprised that the driver is penalizing you? Don''t supply tex coords you aren''t using. Simple as that.


quote:

Edit:
Even stranger still, I have noticed that the loss of framerate is not immediate but occurs over a period of time, with loss of 7 fps in a matter of seconds but continouosly loses more and more approaching a limit of about 10-12 fps.

And yet more strangeness, once the code above runs again, (the ones without the 0''s) The fps loss is reset and again it starts at 53 fps and begins its approach to 30 fps.



Track your memory usage. Sounds like you''ve written a memory leak somewhere.


Share this post


Link to post
Share on other sites