Is only one VAO is enough for all VBO?

Is only one VAO is enough for all VBO?

You only need one. And only if you use OpenGL 3.3 or higher as a Core profile. You may also want to use GL_ARB_vertex_attrib_binding if available.

Before OpenGL 3, you effectively only had one VAO. But creating one VAO and continually changing its state defeats the point of having VAOs. They allow you to encapsulate all of the state related to vertex attributes in an object so that you can change all of that state with a single glBindVertexArray() call.

IOW, if you change the state of a VAO then change it back to some previous state, you’re doing it wrong. You should create separate VAOs for each combination and switch between them.

The more VBO binds you have, the more you’re going to want to use VAOs or NVidia bindless to reduce this bind overhead.

On the other hand, if you stream everything into one big streaming VBO, in practice you’re rarely (if ever) changing the bound VBO, so you have little bind cost to avoid. VAOs and bindless net you less here.

I’m asking for clarification. I have N objects, and for this N object, 1 VAO is enough. And 1 object consist from Vertex Buffer Object (Vertices), Index Buffer object (Indices), Normals and Textures. Textures and Normal are confusing me, how we can store them, how we can use them? If i have objects more than 1, how i can draw them?

[QUOTE=antos1;1283561]I’m asking for clarification. I have N objects, and for this N object, 1 VAO is enough.

And 1 object consist from Vertex Buffer Object (Vertices), Index Buffer object (Indices), Normals and Textures.

Textures and Normal are confusing me, how we can store them, how we can use them? If i have objects more than 1, how i can draw them?[/QUOTE]

Ok, put VAOs aside a second. They’re confusing you. Let’s just talk about vertex attributes and indices.

These are all vertex attributes: vertex position (V), vertex normal (N), vertex texture coordinate(s) (T), etc. You store these in buffer objects. Often, these are called vertex buffer objects (VBOs). Same thing.

You also have indices. These are also stored in buffer objects (VBOs).

As far as how to store the data for vertex attributes, you have options. If the vertex attribute data for your object is static (unchanging), just “interleave” all the vertex attributes for each vertex and store them in the same VBO. For instance, VNTVNTVNTVNT… However, if you wanted, you could insteadstore each attribute sequentially for all vertices and then string all these attribute lists together end-to-end, again storing all of this vertex attribute data in one VBO. For instance, VVVV…NNNN…TTTT… Or if you wanted, you could store each vertex attribute in its own separate VBO (e.g. VBO #1 = “VVVV…”, VBO #2 = “NNNN…”, VBO #3 = “TTTT…”). You can mix-and-match these to get other possibilities.

Ok, please re-read the above and make sure your comfortable with it. This is how you store vertex attribute and index data in buffer objects.

Now, given this vertex data already stored in buffer objects, how does OpenGL know which buffer objects to look in, where in them to look, and what data formats to expect when it needs to pull this vertex attribute and index data into the GPU to render? That is captured in the vertex attribute and index “bindings”. You tell it this through calls to glBindBuffer, glVertexAttribPointer*, and gl{Enable,Disable}VertexAttribArray. You’ve probably done this, or seen it done.

All vertex array objects (VAOs) do is “cache” these bindings. That’s it! They have nothing to do with the actual storage of the vertex attibute or index data. They just cache pointers to “where” this data is and what format it’s stored in.

So to your question, you can use just 1 VAO or your can use as many as you have batches (draw calls) that you need to submit. They’re just a cache of the bindings needed to render a batch (draw call). Like any cache, if you never reuse the values, you’ll see little benefit from them. In fact, you may see an additional performance cost.

[QUOTE=Dark Photon;1283562]Ok, put VAOs aside a second. They’re confusing you. Let’s just talk about vertex attributes and indices.

These are all vertex attributes: vertex position (V), vertex normal (N), vertex texture coordinate(s) (T), etc. You store these in buffer objects. Often, these are called vertex buffer objects (VBOs). Same thing.

You also have indices. These are also stored in buffer objects (VBOs).

As far as how to store the data for vertex attributes, you have options. If the vertex attribute data for your object is static (unchanging), just “interleave” all the vertex attributes for each vertex and store them in the same VBO. For instance, VNTVNTVNTVNT… However, if you wanted, you could insteadstore each attribute sequentially for all vertices and then string all these attribute lists together end-to-end, again storing all of this vertex attribute data in one VBO. For instance, VVVV…NNNN…TTTT… Or if you wanted, you could store each vertex attribute in its own separate VBO (e.g. VBO #1 = “VVVV…”, VBO #2 = “NNNN…”, VBO #3 = “TTTT…”). You can mix-and-match these to get other possibilities.

Ok, please re-read the above and make sure your comfortable with it. This is how you store vertex attribute and index data in buffer objects.

Now, given this vertex data already stored in buffer objects, how does OpenGL know which buffer objects to look in, where in them to look, and what data formats to expect when it needs to pull this vertex attribute and index data into the GPU to render? That is captured in the vertex attribute and index “bindings”. You tell it this through calls to glBindBuffer, glVertexAttribPointer*, and gl{Enable,Disable}VertexAttribArray. You’ve probably done this, or seen it done.

All vertex array objects (VAOs) do is “cache” these bindings. That’s it! They have nothing to do with the actual storage of the vertex attibute or index data. They just cache pointers to “where” this data is and what format it’s stored in.

So to your question, you can use just 1 VAO or your can use as many as you have batches (draw calls) that you need to submit. They’re just a cache of the bindings needed to render a batch (draw call). Like any cache, if you never reuse the values, you’ll see little benefit from them. In fact, you may see an additional performance cost.[/QUOTE]

Thanks, i got.



glBindBuffer(GL_ARRAY_BUFFER, VerticesOfObject1_);
glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, NULL);

glBindBuffer(GL_ARRAY_BUFFER, VerticesOfObject2_);
glVertexAttribPointer (0, 4, GL_FLOAT, GL_FALSE, 0, NULL);


So, i can do this (?)