How can I manage multiple VBOs and shaders?

Started by
6 comments, last by Osbios 8 years ago

I just recently learned that it is actually possible to have more than one VBO, and actually quite normal to use a VBO per-object in game, as long as there aren't too many objects.

How would this actually work in practice? All the tutorials I've found only use a single VBO. Would I manually swap them during the drawing phase and call draw multiple times?

created Hell Loop - indie pixel art tower defense platformer

Advertisement

While swapping VBO is an "expensive" operation for AAA games, it's not that costly. On my computer, I can draw 125 000 times the same cube, while unbinding-rebinding it for EVERY draw call (It's stupid, but I did it for benchmarking purpose) with still 50 frames per second. So, that's the way to go. IDK how it runs on mobile devices though, but I don't think many games dynamically build a giant VBO holding everything, for skybox UVs to particle' position.

On my computer, I can draw 125 000 times the same cube, while unbinding-rebinding it for EVERY draw call (It's stupid, but I did it for benchmarking purpose) with still 50 frames per second.

The driver will detect you're rebinding it and ignore it. What you measured was the cost of the call instructions and checking if the VBO was bound, and not the actual cost of changing bound VBOs.
A modern computer can definitely not handle 125.000 swaps at 50hz at all.



How would this actually work in practice? All the tutorials I've found only use a single VBO. Would I manually swap them during the drawing phase and call draw multiple times?

You would bind a vbo and set it up, you would then bind another vbo and set that up and so on for each different vbo you have.

When it comes to rendering you would then bind the vbo and draw it, then bind the next vbo and draw that and so on. Another thing that might be of interest to you are vertex array objects, they can have multiple buffers and neatly wrap up and object. With just vbos you need to bind your vertex array and then (if you use one) your index array before rendering. VAOs take care of that as well as setting the vertex attributes.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

If you think about it. A restriction of a just a single VBO would be severely limiting in a great majority of cases. What happens when you have stuff that can be dynamically updated and you are running on hw that don't support features like persistent mapping. I would suggest instead of just poring over tutorials and code found online, download the OpenGL specification and find out a little more about how OpenGL works. I say OpenGL because you made reference to VBO, but the same would apply for DirectX.


How would this actually work in practice? All the tutorials I've found only use a single VBO. Would I manually swap them during the drawing phase and call draw multiple times?

Not much different, I do not get what confuses you. You create another vbo and bind it, along binding its vertex declarations, which are an ogl state that drops when you bind another vbo.

Shader and texture resource stays bound, you just have to make sure that new vbo you have bound gets bound with comforming vertex declaration for the bound shader- and issue draw call (wheather you use vao or vbo)

I just recently learned that it is actually possible to have more than one VBO, and actually quite normal to use a VBO per-object in game, as long as there aren't too many objects.

How would this actually work in practice? All the tutorials I've found only use a single VBO.

I watched the same tutorials as you and was having absolutely the same problem and I actually created a topic to ask how should I know when another VBO is needed and how many objects need to be stored in one VBO and what is better: many objects in 1 VBO or 1 object per VBO or even some other configurations. From what I've gathered, there is no definite answer. But basically:

If you aren't sure which way to do something, do it both ways and see which works better.". - John Carmack :wink:

The driver will detect you're rebinding it and ignore it. What you measured was the cost of the call instructions and checking if the VBO was bound, and not the actual cost of changing bound VBOs.
A modern computer can definitely not handle 125.000 swaps at 50hz at all.

What matters even more in real world is the driver (with APIs like OpenGL or DX11) doing validation (lots of pointer chasing) and that will cause cache trashing, which is the main bottleneck on any half modern CPU.

So tests where you only switch between two VBOs all the time or where you only push OpenGL to its limits but the actual test application is small and has a minimal footprint on the cache, do not show you real world performance.

The question of how many VBOs you want to use is easy to answer: Its just a cost/benefit of performance vs effort.

If your application is very small: put every object in its own VBO = easy and fast to develop

If your application gets bigger: Combine objects to a single VBO to minimize driver validation costs = more work to develop, better performance

Also I would recommend not to use VAOs (Excluding the single VAO you need if you run a core profile).

Use GL_ARB_vertex_attrib_binding (Core since 4.3) if available and otherwise old style glVertexAttribXFormat to emulate the same behavior where you have a clear cut between vertex layout and vertex data (VBOs).

This topic is closed to new replies.

Advertisement