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. |
|||||||||
|
|
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. |
|||
|
|
Client-side vertex data storage is deprecated in all 3D APIs. Use Vertex Buffers. |
|||
|
|