🔒 Locked
Optimize model rendering
Advertisement
Original Post
I'm building a demo that is rendering a bunch of md2 models running around, and I'm looking for a way to speed up the rendering. Currently I'm interpolating between key frames every frame so I'm constantly recalculating vertices and normals and then just using immediate mode calls to draw. The two common methods for optimization are to use display lists and/or vertex arrays right? It doesn't seem like either of these is really applicable to my situation though because I would have to recompile the display list every frame as all the gl calls have changed and the same goes for using a vertex array which I would have to rebuild each frame. Actually using the arrays seemed like it might help but I've implemented it and it actually makes my framerate worse. Is there anything else I might try? I've heard people talk about VBOs, is that my only likely option? Thanks for the help as usual.
VBOs have to be used through an extension, correct?
Another pretty effective way is to have a few buffer slots (2 or 3) and assign these to a specific vertex attrib, then have the VS happily interpolate those vertex keyframes depending on a uniform weight.
This turns out a bit faster on a few systems I've tested but your mileage may vary according to your drivers and memory.
This turns out a bit faster on a few systems I've tested but your mileage may vary according to your drivers and memory.
i made a guantlet game last century, from memory it ran @ ~20fps with ~200 md2's onscreen this is with a nvidia tnt1, amd k6-300.
moral of the story, md2's contain very few verts ~500 max i think. with plain VAs u should get good framerates even with old hardware, ie look elsewhere for the bottleneck
moral of the story, md2's contain very few verts ~500 max i think. with plain VAs u should get good framerates even with old hardware, ie look elsewhere for the bottleneck
That's the thing, generating the vertex array each frame (I'm not reallocating the memory each frame don't worry) actually seems to be slower than just using immediate mode. I'm testing with about 100 models right now and the framerate is dipping down to around 15 fps. When I comment out the immediate mode calls, so it's still performing all the interpolation calculations the framerate jumps up to like 140-150. This is all on my laptop (1.5GHz Turion) which is pretty weak but not horribly outdated or anything, should be faster than a K6 I would think.
edit: Just checked, this model has 670 triangles so that's 2010 vertices plus the weapon model adds another 366.
[Edited by - My_Mind_Is_Going on August 2, 2007 9:02:16 AM]
edit: Just checked, this model has 670 triangles so that's 2010 vertices plus the weapon model adds another 366.
[Edited by - My_Mind_Is_Going on August 2, 2007 9:02:16 AM]
Quote:
Just checked, this model has 670 triangles so that's 2010 vertices
theres a problem right there
the number of triangles should be quite close to the number of verts ie with 20percent
ie a triangle does have 3 verts but the neighbouring triangles share 2 of these verts
ie 2 triangles
<|>
have 4 different verts not 6
No offense to zeds but that calculation he came up with doesn't matter. Because either way, the GPU draws the same amount of triangles.
VBO's are in the GL 1.5 specification, you should have it even on a 5000 series nvidia card (no idea about ATI).
Seriously VBO's are the way to go. But first:
How many frames of animation do you have?
One frame of animation will cost you 2010*3(coordinates)*3(normals), which isn't that bad. If you have alot of textures/models/etc, then static frames are going to eat your GPU memory fast.
Another thing, are you interpolating for each model? If so , thats probably eating your CPU like mad.
VBO's are in the GL 1.5 specification, you should have it even on a 5000 series nvidia card (no idea about ATI).
Seriously VBO's are the way to go. But first:
How many frames of animation do you have?
One frame of animation will cost you 2010*3(coordinates)*3(normals), which isn't that bad. If you have alot of textures/models/etc, then static frames are going to eat your GPU memory fast.
Another thing, are you interpolating for each model? If so , thats probably eating your CPU like mad.
I eliminated all the unnecessary vertices but using a vertex array is still slower than immediate mode which seems pretty stange.
I have to calculate all the interpolated quantities with either method so the difference between the two is that in one I have ~2000 glVertex calls and in the other I write ~350 vertices to a vertex array and then send an index array of ~2000 values, the latter being the (slightly) slower of the two. Does this sound wrong it anyone else?
Edit: I thought it might be the CPU but just commenting out the glVertex,glNormal, and glTexCoord calls in the inner loop causes the frame rate to jump by like 80-90 fps. I am interpolating for each model but it seems like I have to since I don't don't have any way to know which models are in which animation state (especially since they can have variable interpolation rates), they're all pretty much doing their own thing.
As for VBOs being part of the GL 1.5 specification, I've never used extensions before for anything but don't I have to use them to access any features beyond GL 1.1 or something? I'm really not clear on how the whole windows drivers vs. vendor drivers business works.
I have to calculate all the interpolated quantities with either method so the difference between the two is that in one I have ~2000 glVertex calls and in the other I write ~350 vertices to a vertex array and then send an index array of ~2000 values, the latter being the (slightly) slower of the two. Does this sound wrong it anyone else?
Edit: I thought it might be the CPU but just commenting out the glVertex,glNormal, and glTexCoord calls in the inner loop causes the frame rate to jump by like 80-90 fps. I am interpolating for each model but it seems like I have to since I don't don't have any way to know which models are in which animation state (especially since they can have variable interpolation rates), they're all pretty much doing their own thing.
As for VBOs being part of the GL 1.5 specification, I've never used extensions before for anything but don't I have to use them to access any features beyond GL 1.1 or something? I'm really not clear on how the whole windows drivers vs. vendor drivers business works.
Quote:GF4Ti supported it, as well as GF4MX and very probably all NV1x (but I'm not sure here). I have seen some R200/8500 sporting them but I'm not sure how much is widespread (I've seen some really outdated drivers still around for those cards).
Original post by dpadam450
VBO's are in the GL 1.5 specification, you should have it even on a 5000 series nvidia card (no idea about ATI).
So, it's even better than this.
Not using VBO is simply pointless.
Quote:none
No offense to zeds but that calculation he came up with doesn't matter. Because either way, the GPU draws the same amount of triangles.
taken, but the most important thing is the num of vertices transformed not the num of tris drawn
ala in my example
<|>
the card is smart enuf not to recalculate the same vertice position that it had just calculated again, thus sharing verts is often a big win performance wise.
transformingwise -> drawing 2000 tris with 2000 verts is always slower (by a large amount) than 2000 tris with 500 verts
to My_Mind_Is_Going ive found if the framerate is ~60 or greater lerping doesnt really matter to much (which is a pity)
with your VA stuff cooment out the glDrawElements(..) line if the framerate doesnt markedly improve then its your cpu work thats slowing it down, if so post that code, someone could help
With glDrawElements commented out the frame rate is approximately as it was with the immediate mode calls commented out. So it's not the CPU then? It's not that I'm surprised that my laptop's integrated graphics are weak it's just that there should be a difference between these two rendering methods right?
for ( int i = 0 ; i < ModelData->numVertices ; i++ ) { x1 = vList.point[0] ; y1 = vList.point[1] ; z1 = vList.point[2] ; x2 = nextVList.point[0] ; y2 = nextVList.point[1] ; z2 = nextVList.point[2] ; vertexArray.point[0] = x1 + (x2-x1)*interpol ; vertexArray.point[1] = y1 + (y2-y1)*interpol ; vertexArray.point[2] = z1 + (z2-z1)*interpol ; x1 = normals[ nList ].point[0] ; y1 = normals[ nList ].point[1] ; z1 = normals[ nList ].point[2] ; x2 = normals[ nextNList ].point[0] ; y2 = normals[ nextNList ].point[1] ; z2 = normals[ nextNList ].point[2] ; normalArray.point[0] = x1 + (x2-x1)*interpol ; normalArray.point[1] = y1 + (y2-y1)*interpol ; normalArray.point[2] = z1 + (z2-z1)*interpol ; Normalize(normalArray.point) ; } glVertexPointer(3,GL_FLOAT,0,vertexArray) ; glNormalPointer(GL_FLOAT,0,normalArray) ; glTexCoordPointer(2,GL_FLOAT,0,ModelData->textureCoords) ; glDrawElements(GL_TRIANGLES,ModelData->numTriangles*3, GL_UNSIGNED_INT,vertexIndices) ;Quote:
Original post by zedz
My_Mind_Is_Going thats not ideal
eg
x1 = vList.point[0];
copys the float over, is it necessary?
(ild ignore the normals for now, also normalize aint cheap stick it in a vertexshader if possible or use the gl normalize normal function)
Well I can eliminate the intermediate x1 and x2 stuff it was just to make the code look cleaner. But this and the normalization issue are only going to free up the CPU correct? The OpenGL calls seem to be the cause of the slowdown, because I can make those same CPU optimizations to my immediate mode routine as well.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement