# Should I use a VBO if the vertex data changes from time to time?

If I have a very large number of vertices, but they're static for about 70% - 80% of their life time, should I use a VBO for them? If so, what usage should I specify? This doesn't sound like a case for GL_STATIC_DRAW.

With GL|ES, you have no choice - you must use VBOs.

With Direct3D, you have no choice - you must use vertex buffers.

With OpenGL Core Profile, you have no choice - you must use vertex buffers.

The only place where you have an option to avoid VBOs is in the old deprecated OpenGL API. Which internally is just inefficiently wrapping VBOs on all newer drivers.

The correct usage flag is likely DYNAMIC_DRAW for your needs. You can (and probably should) just test the different usage flags and see which one performs best for your particular needs. The results can sometimes be a bit surprising, depending on hardware and driver.

• GL|ES doesn't require usage of VBO. You can still use simple vertex arrays with contents from CPU allocated buffer. – Mārtiņš Možeiko May 15 '12 at 20:40
• Correct, VBOs aren't required in ES2: khronos.org/opengles/sdk/docs/man/xhtml/… - likely to be required in ES3 though, but that's future. – Maximus Minimus May 15 '12 at 20:55
• Ah, right right - I always immediately assume people mean immediate mode rendering when comparing to VBOs, since most often times they are. :) – Sean Middleditch May 16 '12 at 1:39

Personally I'd say try it and see. You may get better performance during that 70% to 80% of the object's lifetime, you may not, and much of that will depend on how well (or not so well) your driver and hardware handles VBOs used in this manner (and - of course - whether or not this part of the pipeline is actually a bottleneck for you; it may not be, in which cause you'll see minimal, if any, improvement).

Fortunately it doesn't involve major surgery to migrate a program from VBOs to client arrays and back, so it's something you can easily enough test and back out of if it's not working well for you.

Either of GL_STATIC_DRAW or GL_DYNAMIC_DRAW would be appropriate. Static might just work well because performance during the times when the buffer data doesn't need to be changed may be more important, and you may be able to time updates so that they don't affect performance during the times when it is changed so much.

Remember that they're just hints - your implementation can use them to select the appropriate storage for your buffer, but it is by no means obliged to abide by what you specify - some implementations may just completely ignore them.

Updating a second buffer on another thread while the first is drawing, then switching buffers, may be an option for you here - depending on the target hardware and whether or not you know (or can work out) the new contents in advance.

Looking through the ES2 help pages I see that it doesn't have glMapBufferRange, and that you are required to use glBufferSubData for updating. That's moderately unfortunate as with glMapBufferRange I'd unreservedly recommend it - it really is required to efficiently do just-in-time buffer updates. As it is, you just need to profile and find out - but I think it's worth profiling and finding out.

20-30% of frames is really high number. Remeber that this is realtime rendering so worst case scenario does matter. VBO are really great but only if you never or really rarely(like 0.01% of frames) update them. Just use vertex array and get better worst case scenario.

I literally gained 15ms when swapped from vbo's to va in scene where there was 25 skinned models with my adreno 205 gpu on my huawei.

Tldr: Use profiler.

• That's useful advice because sometimes there really are times when just letting the driver stream data itself from client-side arrays is the best approach. However, in your specific case I would have considered moving much of the skinning process to your vertex shader before junking VBOs altogether - that would have enabled your verts to stay static with just bone updates needed. I also think you're a mite over-pessimistic with your stats (glMapBufferRange really does resolve most of this, but I guess you're coming from an ES perspective). Your point remains valid despite that. – Maximus Minimus Jun 26 '12 at 19:31

Client-side vertex data storage is deprecated in all 3D APIs. Use Vertex Buffers.