Archived

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

ironballs

How many Vertex Buffers

Recommended Posts

This may sound like a stupid question, but anyhow: When working with DirectX, do you create only one vertex buffer, and each object in your world stores the position in the buffer of the vertices that it uses, or ... Do you have a separate vb for each object in the world? Sorry for the stupid question! Matt

Share this post


Link to post
Share on other sites
Matt,

It's not a stupid question. Basically, the answer, as far as I can tell, is "it depends."

You do want to have as few vertex buffers as possible, but you'll probably end up with more than one, depending on the complexity of your game.

You want to avoid having lots of VBs with small numbers of vertices in them. For example, let's say you're making a particle system that has 100 separate rectangles = 400 vertices. You would NOT want each rectangle to have its own VB. In such a case, you would put all 400 vertices in one VB.

But, on the other hand, if you have a space battle game with 10 separate fighter craft, each of which is a complex object with its own world matrix, you might as well give each craft its own VB. There's only ten of them and you have to make separate DrawPrimitive() or DrawIndexedPrimitive() calls for each craft's rendering anyway.

It's all in the balance. Hope that helps!

--Neil

----------------------
Check out my game demo and resume at
www.fivestory.com/projects/game.

(edit: grammar)

[edited by - HoozitWhatzit on November 5, 2002 2:06:46 AM]

Share this post


Link to post
Share on other sites
Hoozit, your game looks cool. I looked at the screenshots
and downloaded your beta.

Upon clicking "play" in the opening screen though,
my computer went bluescreen for the first time in about
8 months !

AMD 800
128MB RAM
Matrox G550 (Dualscreen Geforce 2)
Win XP

Share this post


Link to post
Share on other sites
A little OT but, If you dont wanna do locking and unlocking of the vertex buffers each time you don't have to.

Just DrawPrimativeUP. As all that needs is a pointer to your vertices, no vertex buffer unlocking, locking etc.

This fitted into my game quite nicely. Dunno about yours though.

example of call...

DrawPrimitiveUP(blar , numOfVertices , PointerToArrayOfVertices , sizeof ( YourVerticesStruct) ) ;

Hope this helps,
Aaron

[edited by - Weeks on November 5, 2002 7:47:00 AM]

Share this post


Link to post
Share on other sites
I agree with Hoozit. It all depends. Always keep in mind a few things when using vertex buffers
- locking and unlocking is expensive, and should be done as little as possible. so you should fill up a vertex buffer with as much data as u can in one call.
- you should try to "draw" as much primitives as you can in one render call.
- Dont use DrawPrimitiveUp because it''s terriblwe for performance issues. It creates a vertex buffer, fills it and drawis it with every call. where as if you lock and unlock yourself, you can fill the vertex buffer once (if its static), and just call drawPrimitive every frame without having to lock/unlock/fill/create/destroy a vertex buffer every call.

also another thing is try not to store the vertices positions in your vertex buffer. keep all the positions at origin, and move objects around with the world matrix using SetTransform(). If you kep positions in vertex buffers then say you had a ball that moves every frame. You would have to lock and unlock the vertex buffer that holds the ball''s vertices every frame to chegs the ball''s position.
Instead you create the vertices in the ball''s center at (0,0,0) and move the ball arounf using the world matrix instead.

there are many ways to optimize (even ways that havent been found out yet) so experiment as much as you can. Make yourself a font engine, and have statistics displayed for everything you do. That way when you make a change that makes you app faster, you''ll notice the speed increase, and it''s helpful.

Also try writing statistics to a log filem and compare different instances of your program or something. There are many things you can do. And if you are using MS VC++ enable profiling
goto Menu->Project->Settings click on the link tab and check Enable Profiling. Then go to Menu->Build->Profile and you get a lot of useful information on your application.



"I know sometimes I ask stupid questions...but i mean well "
[Triple Buffer-My home]|[SCRIPTaGAME]|[My Old Site]

Share this post


Link to post
Share on other sites
quote:

Hoozit, your game looks cool. I looked at the screenshots
and downloaded your beta.

Upon clicking "play" in the opening screen though,
my computer went bluescreen for the first time in about
8 months !



Crap...

Thanks for the kind words, bratsj, and for trying out my game. The bluescreen error is a bit alarming, though!!

If you wouldn''t mind, could I notify you in a couple of days by e-mail and ask you to try downloading the game again?

Thanks,
--Neil.

----------------------
Check out my game demo and resume at
www.fivestory.com/projects/game.

Share this post


Link to post
Share on other sites
quote:
Original post by Weeks
Just DrawPrimativeUP. As all that needs is a pointer to your vertices, no vertex buffer unlocking, locking etc.

This fitted into my game quite nicely. Dunno about yours though.

example of call...

DrawPrimitiveUP(blar , numOfVertices , PointerToArrayOfVertices , sizeof ( YourVerticesStruct) ) ;



As Fuzztrek suggests, try and stay away from using the DrawPrimitiveUP / DrawIndexPrimitiveUP methods. Using these methods can, and very often *will*, cause stalling in your nice, fast rendering pipeline. These methods actually ''hide'' the process of creating / handling the buffers for you and, as a result, can result in a significant hit where performance is concerned.

Regards,
Sharky

Share this post


Link to post
Share on other sites
I''m a bit new to DirectX, and I''m a bit confused about a few things.

Say for example a game has several instances of a character, each using the same character model, but the game uses keyframe interpolation, and not all instances of the character are guaranteed to have the same geometry at one time. (say they were all in different stages of their animation)

Would it be inefficient to give each instance of the character its own vertex buffer? Even if there may be many many instances of this character, or are there a better solutions to issues such as this?

Also, say the game has deformable terrain, but events capable of deforming the terrain are guaranteed to happen very very rarely. Is this a situation where static buffers could be used? Or are static buffers reserved for completely static geometry?

Share this post


Link to post
Share on other sites
quote:
Original post by Oxyacetylene
I''m a bit new to DirectX, and I''m a bit confused about a few things.



Yeah - these things can get you like that sometimes...

quote:

Say for example a game has several instances of a character, each using the same character model, but the game uses keyframe interpolation, and not all instances of the character are guaranteed to have the same geometry at one time. (say they were all in different stages of their animation)



If you are using keyframe interpolation then this requires you calculate the vertex positions/normals/etc. at a predetermined rate - such as every game loop. As a result you will need to store this information and copy it into a vertex/index buffer manually after each update (and prior to rendering). As this suggests you will need to implement some sort of scheme that makes use of dynamic vertex buffers. You may decide to have a dynamic vertex buffer per character, or have several characters placed in a larger vertex buffer into which you index when rendering. The method that is best suited a particular situation is generally determined by the format of the source data, and the amount of geometry you are sending to the card per frame. I won''t go into more detail about efficient usage of vertex and index buffers as there are lots of docs around here and the Internet that do a far better job of explaining that I can!!

Also take a look at the Dolphin SDK example and maybe this will provide some answers to your particular solution. It uses a different method of interpolating frames using vertex shaders, and is a little more inherently complicated.

quote:

Would it be inefficient to give each instance of the character its own vertex buffer? Even if there may be many many instances of this character, or are there a better solutions to issues such as this?



Possibly - this depends on how many characters you have, and how complex they are. If you have a character modelled in very few polys then perhaps a more efficient method would be to fill a larger buffer with several of the same characters before rendering.

quote:

Also, say the game has deformable terrain, but events capable of deforming the terrain are guaranteed to happen very very rarely. Is this a situation where static buffers could be used? Or are static buffers reserved for completely static geometry?



Static buffers are for static geometry. You shouldn''t be attempting to lock/unlock/modify the contents of static buffers or Direct3D will likely complain

If you wish to have deformable terrain a method would, perhaps, be to implement a LOD algorithm and use a dynamic vertex buffer into which you feed the terrain geometry. Again there are a lot of docs around on this subject so take a look around and see what''s available.

Regards,
Sharky

Share this post


Link to post
Share on other sites
how about this idea
which isn't something new or anything all you gurus out there. =P

try some class structure something like the following:
class Model
{
// x is basicly someway to let this thing populate its
// vertex buffer. if you want to pass in a path or
// a memory location for something.. whatever...
void init( 'x' );

VertexBuffer vb;
void Render();
}

class Character
{
Model *model;
void SetBody( Model *mdl ) { model = mdl; }
Matrix pos;
void Render() { return model->render; }
}
// keep in mind this is all psedo code

so as you can see... you create a model and give a character a body... in this case... you could create something like 10 characters... and they all reference the same vertexbuffer. via
something like

Character *player1;
Model *model;

model = new Model();
player1 = new Character();

model->init( "quakeguy.mdl" ); // in this case path. (see above)
player1->SetBody( model );
player1->Render( );

er something or something.. kinda at work.
soo
lemme know if that helps
Andy

[edited by - skillfreak on November 5, 2002 4:39:20 PM]

Share this post


Link to post
Share on other sites
Thanks, that''s all I needed to know.

I''ve got a lot of documentation on the subject, but needed a bit of clarification to get on the right track, as a lot of it seems to be aimed at people more experienced with DirectX.

Share this post


Link to post
Share on other sites
I''m not really experienced in this area, but I was thinking of implementing it, such that when a game object is created, it obtains a handle of some sort to a class that abstracts the vertex buffer.

Depending on how the 3D model is animated, the vertex buffer object may refer to a buffer specifically allocated for that object, part of a large buffer, or in the case of static geometry, it may refer to a buffer shared by every instance of the object.

Share this post


Link to post
Share on other sites