Optimizing with Vertex Buffers

Started by
13 comments, last by HanSoL0 21 years ago
I''ve got a great playable demo of a multiplayer space combat game that looks good and runs at a silky-smooth 60 fps....as long as you''re running a P4 2.26GHz with 512MB RAM and a GeForce 3....not so great, obviously. I''ve been doing some research on how to get my framerate up on lower-end computers, and I found that it''s apparently not the smartest thing to have a separate vertex buffer for each object in your scene (20 starfighters plus about 800 asteroids). How would one concatenate all those individual vertex buffers from the .x files into one vertex buffer? And after you do that, how do you transform the individual objects independently of each other? Or am I completely misunderstanding and it _IS_ the best thing to do individual vertex buffers? Please help! Ryan Buhr Reactor Interactive, LLC. http://www.reactorinteractive.net

Ryan Buhr

Technical Lead | Sector 13

Reactor Interactive, LLC

Facebook | Twitter

Advertisement
Are you doing any sort of culling? If not there are good tutorials at gametutorials.
Yeah, I''m doin'' some simple backface culling. That''s not my problem though. I need to know about vertex buffers.

Ryan Buhr
Reactor Interactive, LLC.
www.reactorinteractive.net

Ryan Buhr

Technical Lead | Sector 13

Reactor Interactive, LLC

Facebook | Twitter

I don''t have the answer to you question but, when you lock your vertexbuffer, can''t you specify the offset to start writing to you vertex buffer. That way, you can memcpy your second set of verticies after your first set. I don''t know how that''s going to affect transforming though (i''m a little behind in your talents... nice site BTW)
Thanks! Yeah, I know how to play with the content of a VB, but I don''t know how to transform individual pieces of it, or if you even can.

Ryan Buhr
Reactor Interactive, LLC.
www.reactorinteractive.net

Ryan Buhr

Technical Lead | Sector 13

Reactor Interactive, LLC

Facebook | Twitter

if your asteroids, for example, are using the same class type, instead of having a vertexbuffer for each object you can have a static one for a class. Say your asteroid class looks something like this:


  class CAsteroid{     D3DXVECTOR3 position;     D3DXVECTOR3 velocity;     .....     IDirect3DVertexBuffer[8/9]* asteroidVB;};  


If every asteroid uses the same .x model, "asteroid.x" or the like, you can make the asteroidVB a static vertex buffer.


  class CAsteroid{     D3DXVECTOR3 position;     D3DXVECTOR3 velocity;     .....     static IDirect3DVertexBuffer[8/9]* asteroidVB;     static int numInstances;};  


The numInstances variable is so that you know how many CAsteroids you have initialized. Your constructor/initialization function and destructor can look something like this:


  CAsteroid::CAsteroid(char* filename, ...){     ...     if (numInstances == 0)     {         // whatever you use to initialize the VB         LoadMeshToVB(filename);     }     numInstances++;     ...}CAsteroid::~CAsteroid(){     ...     numInstance--;     if (numInstance == 0)     {          asteroidVB->Release();     }     ...}  


This way, you only load the data once and only need one copy of it, but all of your asteroids can access it for rendering. Using this, you save a lot of memory and you don''t have to change the stream source for every asteroid.

As for transforming each object, you can do something like this in your asteroid render function:


  void CAsteroid::Render(){     D3DXMATRIX trans;     D3DXMatrixTranslation(&trans, position.x, position.y, position.x);     DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, numVertices, 0, numTrinagles);}  


hope this helps

''There''s something out there....something stupid...''
''I think I''m going to be ill. Is that a problem for you?''
''[You] overestimate my conscience by assuming that I have one.''
- Daria
Right, thanks for the reply. I already do most of what you said. I only have one copy of each of about 10 asteroids and I just re-render more instances of each asteroid about 80 times or so. I''m not usin'' too much memory. I just want to reduce the number of DrawIndexedPrimitive() calls. Can this be done by putting all asteroid vertices into one vertex buffer, transforming individual groups of vertices, and rendering the whole vertex buffer with one call to DrawIndexedPrimitive()? Or am I thinking too far outside the box? Your help is much appreciated....

Ryan Buhr
Reactor Interactive, LLC.
www.reactorinteractive.net

Ryan Buhr

Technical Lead | Sector 13

Reactor Interactive, LLC

Facebook | Twitter

I just had a thought. What if I transformed the models individually every frame, and then ripped all the vertex buffers into one big one after all the transformations, and then draw the big VB with one call to DrawIndexedPrimitive()? Would there be a greater performance bonus to performing one VB lock and one call to DrawIndexedPrimitive() than to simply not lock any VBs, but call DrawIndexedPrimitive() 1000 times? In this case, would the individual transformations transfer to the final large vertex buffer?

Ryan Buhr
Reactor Interactive, LLC.
www.reactorinteractive.net

Ryan Buhr

Technical Lead | Sector 13

Reactor Interactive, LLC

Facebook | Twitter

The individual transformations would transfer, but I don''t think that the you would gain too much, if any speed. It''s a lot slower to transform a mesh in software probably than it is to make numerous calls ot DrawIndexedPrimitive. Besides, if your vertex buffer is too large that would also decrease the speed.

''There''s something out there....something stupid...''
''I think I''m going to be ill. Is that a problem for you?''
''[You] overestimate my conscience by assuming that I have one.''
- Daria
So should I just simply use a nice vertex shader to do all this and forget about it? I''m just lookin'' for the fastest way to render. Thanks for all the helpful replies, folks.

Ryan Buhr
Reactor Interactive, LLC.
www.reactorinteractive.net

Ryan Buhr

Technical Lead | Sector 13

Reactor Interactive, LLC

Facebook | Twitter

This topic is closed to new replies.

Advertisement