One or multiple VAO/VBO's

Hi there,

Let’s say I have 10 objects (e.g. houses), all having a different kind of mesh and I want to render some of them including a terrain.
What’s the best way to set this up?
Should I use a different VAO/VBO for each object and the terrain or should i put everything in one big VAO/VBO?


Short answer: if you use bindless, it doesn’t really matter much. If you don’t, then you pay performance the more buffer binds you have (so prefer fewer VBOs).

I am not a very advanced OpenGL-Programmer, so what I say may not be a 100% correct.
As far as I know VBO’s / VAO’s have hardly any overhead. Just having more of them is not a big deal.
The problem is only when binding a different VBO / VAO. The more often you have to bind the worse the performance gets. So having fewer might make things faster.
The other thing is the number of draw calls. Just having all your meshes in a single VBO is not going to speed anything up if you still make a separate draw-call for each mesh.
So if any of your meshes need different textures / shaders and you have to split them up across different draw-calls then having everything in a single VBO / VAO is not going to help you.

Furthermore someone told me once that having too big VBO’s is not too good either because some hardware may have problems with that. But I have no specifics.

This is one of those things you’re going to have to benchmark in your own program.

For 10 objects, and if you can take each object in a single draw call, it’s really not going to matter much. Your primary bottlenecks will be elsewhere and you’re better off putting more effort into optimizing around those. If you can hit 60fps/16mspf and with some headroom to spare, your job is done. Your program may not even be performance-critical and that’s something that only you know.

As the number of objects scale up you’ll need to think more about how you organise things, but there is no precise cut-off point beyond which a single VAO/VBO is going to be the only reasonable option. It will differ for different hardware and drivers, so you also need to be aware of your target platforms and what kind of performance they can get.

A further consideration is that a single VAO/VBO can lead to more complex loading code. Because you need to know the total buffer size in advance you may need to make two passes over your objects, one to figure the size and one to actually do the loading. If you ever need to unload an object you won’t find it so easy - you’ll very probably end up needing to unload and reload absolutely everything.

Complex code paths have a cost beyond mere time to implement. You’re going to need to maintain this code too. You’re going to need bug fixes, extra functionality, and to lift it over to the great version 2.0. Be certain that the cost you’re paying is worth it.

My advice is to go with the simpler code first and only optimize once you’ve actually determined that it is a problem you need to solve.