Jump to content
  • Advertisement
Sign in to follow this  
RuneLancer

Handling static meshes

This topic is 2829 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

Let's suppose I'm building a 2D sprite-based game engine and wish to proceed in one of two ways...

1- I create a large dynamic VB and dump all of my sprites into it each frame with their absolute screen position as their coordinates. (1 draw call total)
2- I create a static buffer and use model transformations to position the sprites. (1 draw call per buffer)

The research I've done seems to show that creating a large dynamic VB would be the best way to go. Would this also hold true if, instead of a 2D engine, I were dealing with static models in a 3D engine? (I don't really see why not but I figure other things may play into this...) And is there some "tradeoff point" where exceeding a certain arbitrary amount of vertices would make the other solution better, or something similare?

Thanks!

Edit: Actually, now that I think of it, what constitutes a "static" mesh? I can't seem to find a better explanation than "vertices that don't change very often at all", but how permissive is that? Would a mesh that changes once every couple of seconds (like the score display in a game) be better suited for a dynamic VB, for instance, or is that infrequent enough to use a static VB?

Share this post


Link to post
Share on other sites
Advertisement
A dynamic vertex buffer is a good solution for quads, as only four vertices are updated per sprite. You can update the vertex buffer for all sprites in one transfer, which often makes it better than updating a position once for each sprite in a separate call.
If you have a 3D object it often has from hundreds to several thousand vertices per model, in which case it's better to update a matrix once per object instead of updating all those vertices on the CPU.

There's also the matter of CPU calculations. A 3D model can be rotated etc, which requires that you calculate all those transformations on the CPU if you don't want to update a matrix for each model. Those calculations can quickly get expensive on the CPU.

For a score display it doesn't matter either way. I would use a dynamic vertex buffer for everything that changes, unless it's a large buffer. It's usually better to let the driver know when a buffer is dynamic so it can optimize for having it change without notice at any frame, even if those frames are far apart. For static buffers you should prefer to change them several frames before you actually use the changed version.

Share this post


Link to post
Share on other sites
Thanks for the reply! :)

That pretty much answers my questions - I think I've got this thing figured out. My current graphic engine handles 2D only at the moment but I'm planning on reusing it in other projects and wasn't too sure if I was going the right way with things. I'm getting pretty darn good performance out of it as it is but there's still a bit of work to be done. Still, so far so good!

I'm not sure I understand what you mean by changing static buffers several frames before using them. I'm assuming from that that I should favor creating static buffer in a game's "loading" phase, and that I should (generally) favor using dynamic buffers for any object likely to change its vertices (regardless of how frequently it does so)?

Share this post


Link to post
Share on other sites
I'm currently busy with writing a 2D / 2.5D extension to my engine (OpenGL). One aspect is obviously rendering of sprites. I'm doing it so that texture clips denote an area in a texture atlas. The current texture clip (as chosen by the animation system) is used to build co-planar triangles at runtime. They are transformed to lie on the sprite's "canvas" (what is in fact the cardinal x-y plane of a placement's co-ordinate frame), including rotation and scaling (as is used sometimes for a gameplay). This is all done on the CPU. The vertices (x,y,z,u,v) in world space are written to a VB, and the corresponding indices into a IB. This is streamed to the GPU. (So I use a variant of way 1.)

Things are more complex when considering batching although various render modes are in use (alpha blending, additive blending, subtractive blending), more than a single texture atlas is needed, the environment is actually 3D, not all sprites are mapped onto planes, and OpenGL ES 1.x should be supported... but the principle still holds.

Share this post


Link to post
Share on other sites

I'm not sure I understand what you mean by changing static buffers several frames before using them. I'm assuming from that that I should favor creating static buffer in a game's "loading" phase, and that I should (generally) favor using dynamic buffers for any object likely to change its vertices (regardless of how frequently it does so)?


Overall I would say that when updating something for use right away, prefer dynamic buffers, if the change is small enough that it shouldn't stall the normal order of drawing. This is the case for things changing every frame, or small things that can change suddenly. I'm not sure on the inner workings, which can probably vary between drivers, but when changing a buffer in video memory, some buffered commands might require flushing before continuing to the next commands. For dynamic buffers the driver knows to expect this and can optimize for doing it smoothly.
If you need to update a large buffer that will take some time anyway, it can be better with a static buffer since efficiency in future use is probably more important than having it be immediately accessible.

For example the following pages mentions this, for D3D10:
Creating Buffer Resources
D3D10_CPU_ACCESS_FLAG

If you have something large that should be readable at maximum efficiency by the GPU, unchanged over several frames, use a static buffer. If you need something relatively small to be updated fast and without stalling, use a dynamic buffer.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!