I'm aware it's not a simple yes/no question and for the moment I can't tell if it can be simply answered, or is it topic for a long discussion which is not suitable for our Q&A format.
I want to do some VBO management in order to reduce calls to GL for the sake of improving performance.
I have one set of VBO objects for all the meshes, the set is made of 4 VBOs:
- one for static draws
- one for dynamic draws
- one for stream draws
- one for indices
As I said, I want these four to handle my whole scene - this is going to reduce calls to glBindBuffer.
My mesh object consists respectively of static part, dynamic part and stream part, each of the part is specified by vertex specificator that is created without templates at runtime, just by pushing back attribute objects containing size/type/offset to a member vector.
Based on the vertex specificators you can fill the parts with interleaved data, you don't have to do this for all the parts though. As I read here, separating vertex parts with different usage modes is good as it allows you to update all the dynamic/stream data at once without ever touching the static data. For example, doing particle simulation I may not be necessarily interested in streaming texture coordinates - changing vertex positions may be enough.
What's going to happen next:
- sort all mesh objects by the vertex specificator of its static part
- upload all the meshes' static parts' vertex data in obtained order to the static VBO
- sort all mesh objects by the vertex specificator of its dynamic part
- upload all the meshes' dynamic parts' vertex data in obtained order to the dynamic VBO
... and so on.
In short, static/dynamic/stream chunks (each in one of the 3 VBO's to which it belongs) with the same vertex types will be next to each other, and this is going to reduce calls to glVertexAttribPointer. Here I will need to smartly organize meshes that may want to use various parts, and then implement kind of lazy binds, probably if mesh needs to call gl*Pointer for two different VBOs (separate static and stream parts for example), check if one of them is not already bound and call corresponding gl*Pointer first.
Of course, each of the big batch obtained that way will then be sorted inside on the level of draw calls to reduce switches of shaders, textures and so on.
In short, this is my idea:
Although such a case may be uncommon, it's just to illustrate what should my mesh organizer be able to deal with.
Well, now it's only a plan and I haven't yet implemented it but..
How do the modern, high performance engines do their VBO and gl*Pointer state management ? Is there something wrong with my concept, or am I totally misguided ? Google results for VBO management and similiar tend to give me topics where people are asking for help because their programs crash, or just usage examples that tell nothing about optimizing my rendering procedures on VBO level but just "avoid redundant calls to GL", or some actual one-line tips (like glBufferData with NULL). So what I've described above is what I've concluded myself using those informations and I'm not sure if I am even on the right path.
Could somebody show me some good and actually proven practises managing VBOs in big 3D scenes, or maybe guide me a bit if I am actually reasoning right ?