0
\$\begingroup\$

I'm currently building a game engine renderer but I got stuck when I had to separate engine and client code.

I had been following OpenGL tutorials to learn about buffer creation, etc so all my code for rendering was in a single place and was tied to that specific example.

I created a VBO, a IBO/EBO, a VAO and a shader, then set the VertexAttribPointers for that VAO (and VBO layout) and rendered it. Everything worked fine.

Then I created C++ abstractions for all of those "objects" and recreated the example; that also worked.

So what I wanted to do know is to have each of my game objects create a VBO and an IBO, create a global VAO in my renderer (since all my objects share the same layout) submit them to the renderer and have them rendered. But I discovered I could not setup vertex attribute pointers without having a VBO bound (I have none bound since they get created after the renderer starts up).

So my question is:

How should I set up the VAOs and VBOs for the renderer to work?

I read in some places that what I have to do is to set up few VBOs (so as to have little binding calls and draw calls) and then store every object inside that one giant buffer. (Of course while still creating different buffers for objects with different vertex layouts and different shaders). I also know that to do that you have to allocate a big buffer and then call buffer sub data to store the new data inside that one buffer, but what I don't know is how to store that data if it must be offset (because of its position in the world and how to update its position)

So if that's the case my next question is:

How do I create one giant buffer and then store different objects inside that one giant buffer and then render those stored objects with their respective positions? (For both static and dynamic objects).

\$\endgroup\$
0
\$\begingroup\$

In my engine I create a VAO and VBO for each model (not each object) I have in my game.

Aggregating models into a single VBO seems unnecessary to me. Binding a VBO is not an expensive operation.

Having too many drawcalls, on the other hand, can be expensive, so if you draw many instances of a single model you should look into instanced rendering.

The idea of instanced rendering is that some vertex attributes are shared between instances, like the regular stuff: vertex, normal, uv, etc. But in the same VBO, you also put per-instance data, typically a transformation matrix, one for each instance.

For instanced rendering, look into glVertexAttribDivisor, glDrawArraysInstanced (or glDrawElementsInstanced.)

\$\endgroup\$
  • \$\begingroup\$ Thanks for the great answer. Okay. So I have to create different VAOs for every different Mesh. Isn't there a way to have only one for every type of Mesh. (Static Mesh, Skinned Mesh, Terrain Mesh, etc). Maybe it's impossible, but I just think it seems kind of redundant to create one for every mesh. What do you think? \$\endgroup\$ – Facundo Villa Feb 15 at 6:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.