10
$\begingroup$

I'm reading through Learn OpenGL to refresh the basic concepts as I haven't touched in quite some time.

Specifically I still think I cannot quite understand the meaning of VAO and VBO, the book mainly proceeds through examples it doesn't really give rigorous definitions.

About the VBO:

With the vertex data defined we’d like to send it as input to the first process of the graphics pipeline: the vertex shader. This is done by creating memory on the GPU where we store the vertex data, configure how OpenGL should interpret the memory and specify how to send the data to the graphics card. The vertex shader then processes as much vertices as we tell it to from its memory. We manage this memory via so called vertex buffer objects (VBO) that can store a large number of vertices in the GPU’s memory. The advantage of using those buffer objects is that we can send large batches of data all at once to the graphics card, and keep it there if there’s enough memory left, without having to send data one vertex at a time. Sending data to the graphics card from the CPU is relatively slow, so wherever we can we try to send as much data as possible at once. Once the data is in the graphics card’s memory the vertex shader has almost instant access to the vertices making it extremely fast

So my understanding of VBO they're essentially Buffer objects (bunch of bytes to be sent to the GPU) with the difference that VBO are specifically dedicated to Vertex Data. Is this correct?

About the VAO:

Here instead I don't really understand.

A vertex array object (also known as VAO) can be bound just like a vertex buffer object and any subsequent vertex attribute calls from that point on will be stored inside the VAO.

What does it mean any subsequent vertex attribute calls from that point on will be stored inside the VAO, I don't understand the "call be stored" bit, does it mean somewhere in the opengl context created we store like some data related to the vertex attribute calls (like the pair input output of the call? the output of the call? something related to the call?).

This has the advantage that when configuring vertex attribute pointers you only have to make those calls once and whenever we want to draw the object, we can just bind the corresponding VAO. This makes switching between different vertex data and attribute configurations as easy as binding a different VAO. All the state we just set is stored inside the VAO.

I don't understand the advantage here. I understand the "call made once", because they're stored in the VAO (whatever the "stored part means"). The switching part does maybe mean I can create multiple VAO each one capturing different Vertex Attributes calls and I can just bind each one of these when I need without calling again the vertex attribute?

For reference I've also found this question which I thought had an interesting answer.

$\endgroup$

3 Answers 3

16
$\begingroup$

So my understanding of VBO they're essentially Buffer objects (bunch of bytes to be sent to the GPU) with the difference that VBO are specifically dedicated to Vertex Data. Is this correct?

A "VBO" is not really a thing, and I really wish tutorials would stop pretending that they are.

You are correct in that there exist buffer objects. These are linear arrays of unformatted data that the GPU stores and can access for various processes. One of those "various processes" that the GPU can use them for is providing array data for vertex rendering operations.

But the buffer itself isn't special. It doesn't become a different thing just because you use it for vertex data, and there is no rule that says that a buffer you're currently using for vertex data cannot be used for other buffer usages too.

Note that this is different from how textures work. When you create a texture object and bind it as a 2D texture, that texture object forever becomes a 2D texture. You cannot later bind it as a 1D or a cubemap or whatever. Buffer objects aren't like that; where you bind them defines only how you're currently using them.

What does it mean "any subsequent vertex attribute calls from that point on will be stored inside the VAO"

This is yet another annoying tutorial trope: that objects "store calls" or are macros or other such nonsense.

Objects in OpenGL don't store calls; they store state. They're like structs; they have data members. Binding an object to the OpenGL context allows OpenGL operations that access certain state to find that state within the bound object. So if you call a function that modifies certain state that is from a bound object, that function will modify the state within the object.

When you bind a VAO, you are binding an object that stores the state used for vertex arrays. When you call a function that modifies the state for vertex arrays, that function will modify the state stored in the VAO currently bound. When you render, the rendering system will use the vertex array state found in the currently bound VAO.

$\endgroup$
5
  • $\begingroup$ I'm reading through your second link and slowly it's becoming a bit clearer. However the bit "* ... allows OpenGL operations that access certain state to find that state within the bound object. So if you call a function that modifies certain state that is from a bound object, that function will modify the state within the object."* isn't totally clear. $\endgroup$ Commented Oct 23, 2020 at 17:30
  • $\begingroup$ First of all why is the "binding" relevant (namely why is having the object state the same as the context important?) and second if I bind the object to have the same state as the context I guess this is important but why would I want to modify the state only within the object? I guess this actually comes down to what the meaning of these states are. $\endgroup$ Commented Oct 23, 2020 at 17:31
  • $\begingroup$ @user8469759: Binding the object to the context means that state that references those locations will get their data from the object. And they're not "states"; they're state. As I analogized, they're like member variables for objects. $\endgroup$ Commented Oct 23, 2020 at 18:14
  • $\begingroup$ What do you do you mean with "They're not states, they're state", probably something stupid I know... $\endgroup$ Commented Oct 23, 2020 at 21:29
  • $\begingroup$ "states" (plural) implies that you're talking about an assortment of values ("red/green/blue/yellow, awake/asleep, wearing socks or not, ..." those are "values"), whereas "the state" is the current value of a scalar/struct/array/whatever (think "the smurf is blue, awake, wearing socks") $\endgroup$ Commented Apr 21 at 21:04
7
$\begingroup$

In short words, VBO is an array of raw data, when VAO is an array of ATTRIBUTES - an instruction for shader program how to use the data.

Before, in OpenGL ES 2.0 for example, VAO wasn't introduced yet at all and VBO was optional. You still could pass to your shader your data RAM addresses. Still this data had to pass CPU-to-GPU "bridge" on each call, but this process wasn't exposed to you. VBO allows to keep data on GPU side, which saves transfer time, you just need to know VBO's id.

But VBO by itself is not enough. You have to instruct GPU how to use it. You have to define "Vertex Attribute Pointers" (command glVertexAttribPointer) for each attribute (input data variable) of your shader. Before VAO you had to define attributes for each glDrawArrays call (it's a lot), in every frame (like 30+ times per second). VAO allows to attach an entire array of attributes by just VAO's id. So, when VBO is relatively independent, the VAO is VBO+shader-specific.

$\endgroup$
6
$\begingroup$

A VBO is a buffer of memory which the gpu can access. That's all it is.

A VAO is an object that stores vertex bindings. This means that when you call glVertexAttribPointer and friends to describe your vertex format that format information gets stored into the currently bound VAO. And when you draw it will use the vertex bindings in the currently bound VAO.

Pretending it replays the binding calls is misleading. It is a relic from why the VAO were created because prior to VAOs you did need to redo the vertex bindings every time you changed which mesh you were drawing. A VAO lets you do that in a single call.

$\endgroup$
1
  • 1
    $\begingroup$ what do you mean with A VAO is an object that stores vertex bindings, what do you mean with store vertex bindings? $\endgroup$ Commented Oct 23, 2020 at 17:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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