Skip to main content
GameDev.net gamedev.net
🔒 Locked

Handling dynamic vertex buffer

Started by RuneLancer Oct 4, 2010 at 11:03 PM 4 replies 2.1k views
Original Post
RuneLancer
RuneLancer
I've recently started refactoring my renderer to use dynamic vertex buffers instead of creating a static vertex buffer per mesh and destroying/recreating it everytime the object is changed. I'm not sure why, but I think that should improve the renderer's performance slightly. ;)

I do want to write something efficient rather than just having "dynamic vertex bufferz loel!!" in my games, though. What I understand is that I'm to create a large dynamic VB, write vertices into it, dump it once it's full, and then flush the contents and start over. So that means I need to have a local copy of my meshes at all times.

I'm under the impression it'd be better to keep any mesh in the scene loaded in the buffer and for the object to store an index to its vertices. That way, the overhead of copying the vertices into the buffer each frame wouldn't be incurred and all updating could be done by locking the buffer only once. But somehow this doesn't feel right (I understand a dynamic VB's contents are intended to be regularly discarded...) and I feel like I'd run into unpleasant problems (such as dealing with buffer "fragmentation" as objects are moved in and out of it)...

So, I suppose I'm just looking for some advice as to how to proceed, really.
remigius
remigius

Quote:
Original post by RuneLancer
I've recently started refactoring my renderer to use dynamic vertex buffers instead of creating a static vertex buffer per mesh and destroying/recreating it everytime the object is changed. I'm not sure why, but I think that should improve the renderer's performance slightly. ;)


It might [smile] As a rule of thumb, the best performance comes from not touching the vertex buffer at all. Of course, if it can't be avoided that's no good advice, but it depends on how your object is changing. If the vertices stay the same and it's mainly transformations/deformations, a creative vertex shader might be a good alternative.

Quote:
I do want to write something efficient rather than just having "dynamic vertex bufferz loel!!" in my games, though. What I understand is that I'm to create a large dynamic VB, write vertices into it, dump it once it's full, and then flush the contents and start over. So that means I need to have a local copy of my meshes at all times.


Having the local copy of the vertices around can be useful indeed (and is -in my experience- typical), but again depending on the changes you might be able to stick to a static index buffer. This might not be a huge performance saver, but it's something to keep in mind. I'm not sure what you mean by "a large dynamic VB ... dump it once it's full", but it calls to mind that 1) re-using an object is nearly always faster than creating a new one and 2) unless you're purposefully doing any batching, having a huge buffer with the vertices for multiple meshes in it probably isn't the best idea; it'll increase stalls due to extended locking times and should be generally unpleasant to work with.

It also *might* be an option to use the DrawPrimUP functions if the vertices are changing every frame, but I wouldn't worry about that yet and if you think you should, profile first!

Quote:
I'm under the impression it'd be better to keep any mesh in the scene loaded in the buffer and for the object to store an index to its vertices. That way, the overhead of copying the vertices into the buffer each frame wouldn't be incurred and all updating could be done by locking the buffer only once. But somehow this doesn't feel right (I understand a dynamic VB's contents are intended to be regularly discarded...) and I feel like I'd run into unpleasant problems (such as dealing with buffer "fragmentation" as objects are moved in and out of it)...


I'm getting the impression that you mean to have a copy of the mesh around for each object. If that's correct, this is probably something you want to avoid. Suppose you have 5 trees, you can render them all with the same static mesh (same buffer, same vertices etc) using different world matrices. I apologize if I got the wrong idea here and this is obvious to you, but as a rule of thumb I typically wouldn't stick all mesh instances in one huge dynamic buffer (for reasons mentioned above) unless you're looking at 500+ draw calls per frame.
RuneLancer
RuneLancer
Thanks, that was highly informative!

After doing a bit more research and with your post, I'm starting to think I may have overestimated the purpose of a dynamic vertex buffer - a lot of my meshes rarely change much (ex, windows, text labels, background images... most of my games are 2D and mainly alter texture coordinates rather than manipulating the mesh). Assuming I try to handle everything without having to touch the buffer as much as possible, it seems like a static buffer might be preferable in my case.

Aside from locking the buffer, is there any way of modifying the texture coordinates and the vertices' colors? If so, I could get away with never having to touch the buffer again once it has been created. I'm guessing tbat's what you meant when you were talking about creative use of shaders?
remigius
remigius
Quote:
Original post by RuneLancer
Thanks, that was highly informative!


Glad to hear my verbose ramblings were of use [smile]

Quote:

Assuming I try to handle everything without having to touch the buffer as much as possible, it seems like a static buffer might be preferable in my case.


That's correct. A dynamic buffer is only useful when you're also using it dynamically. The driver/runtime will make certain provisions for this case, so updating the buffer will be more efficient. If you don't update the buffer (much) a static buffer should be more efficient in terms of memory usage & to a lesser degree performance.

Quote:
Aside from locking the buffer, is there any way of modifying the texture coordinates and the vertices' colors? If so, I could get away with never having to touch the buffer again once it has been created. I'm guessing tbat's what you meant when you were talking about creative use of shaders?


Yep, by employing shaders these vertex properties can be relatively easily changed. Vertex color and texture coordinates can be easily assigned in a vertex shader and you can use the colors & coordinates however you see fit in a pixel shader. The catch is that it's up to you to decide where this would be appropriate though. In terms of raw performance the shaders might -generally speaking- be king, but it might not always be the easiest route to take. You can't for example easily say "I want such-and-such vertex to be red", since all vertices will be processed 'simultaneously' (as far as your application code is concerned) by the same vertex shader. So shaders should mainly be considered for operating on all vertices/pixels in a draw call. Examples where this would work are scrolling a background texture or animating a texture by offsetting texture coordinates.

Without knowing exactly what the needs of your game are it's hard to advice what the best route would be, but in general I think that for 2D games using the D3DXSprite (or XNA SpriteBatch) is typically the best option in terms of usability and performance. These take care of your vertex needs behind the scenes, go about this pretty efficiently and offer a decent API to handle 2D rendering. If you purposefully decided to forego sprites and roll your own vertices, this is obviously not the best advice, but I thought I'd mention this to be complete.
DieterVW
DieterVW
Which D3D version are you using?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.