3

VAO being Vertex Array Object and VBO being Vertex Buffer Object. The calls for creating and binding/unbinding VAOs and VBOs have a general format as given below:

GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
            glBufferData(GL_ARRAY_BUFFER, 
                            sizeof(GLfloat)* 9,
                            vertices,
                            GL_STATIC_DRAW);
            glVertexAttribPointer(0,
                    3, GL_FLOAT, GL_FALSE,
                    0, 0);
            glEnableVertexAttribArray(0);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);    

I've followed some tutorials on the internet, and they say that the VBO is bound to the VAO, but in the above code, I don't get how the "connection" or "binding" is established between the VBO and the VAO? I mean how do we know which VBO is bound to which VAO and what if a VBO is to be bound to multiple VAOs?

So, the basic question is: what does VBO is bound to VAO mean, how do we know which VBO is bound to which VAO and how is this binding established?

Nicol Bolas
  • 378,677
  • 53
  • 635
  • 829
juztcode
  • 481
  • 7
  • 25

1 Answers1

12

how does a VBO get attached to a VAO

It is attached when glVertexAttribPointer is called.

Each attribute which is stated in the Vertex Array Objects state vector may refer to a different Vertex Buffer Object. This reference is stored when glVertexAttribPointer is called. Then the buffer which is currently bound to the target ARRAY_BUFFER is associated to the attribute and the name (value) of the object is stored in the state vector of the VAO. The ARRAY_BUFFER binding is a global state.

This behaves different to the Index Buffer (ELEMENT_ARRAY_BUFFER). The index buffer binding is stated within the Vertex Array Object. When a buffer is bound to the target ELEMENT_ARRAY_BUFFER, then this buffer is associated to the vertex array object which is currently bound.


That means when you call glBindBuffer(GL_ARRAY_BUFFER, VBO);, then a global state is set that stores VBO. glVertexAttribPointer retrieves VBO from the global state and assoicates it to VAO. When glBindBuffer(GL_ARRAY_BUFFER, ...) is called again, then the previous binding is lost, but of course it does not change any state of the VAO.

glBindVertexArray(VAO);              # bind VAO (global state)

glBindBuffer(GL_ARRAY_BUFFER, VBO1); # bind VBO1 (global state)
glVertexAttribPointer(0, ...);       # associate VBO1 to attribute 0 in VAO

glBindBuffer(GL_ARRAY_BUFFER, VBO2); # bind VBO2 (change global state, VBO1 binding is lost)
glVertexAttribPointer(1, ...);       # associate VBO2 to attribute 1 in VAO
Rabbid76
  • 142,694
  • 23
  • 71
  • 112
  • As far I understand with my poor technical literature capabilities: when you call the `glBindBuffer(GL_ARRAY_BUFFER, VBO);` , the buffer that bound to the target i.e. `GL_ARRAY_BUFFER` is associated with the currently active VAO? Did I correctly get this? And associating multiple VBO to a VAO is done by binding more VBO to the same target without unbinding the VAO? Did I get this part correctly as well ? – juztcode Jan 24 '20 at 08:01
  • And this association is done with the code internal to `glVertexAttribPointer` ? Can you perhaps include a hint or pseudocode(if not the actual code) as to how this association is done? I mean it's really unsatisfying that the function signature does not contain either of the VAO or VBO but it somehow associates one with the other. – juztcode Jan 24 '20 at 08:02
  • 2
    @juztcode No. When `glVertexAttribPointer` is called then the VBO is associated to the VAO. When `glBindBuffer(GL_ARRAY_BUFFER, VBO)` is called the a global state is set. `glVertexAttribPointer` gets the VBO from the global state and associates it to the VAO. I've add some explanation to the answer. – Rabbid76 Jan 24 '20 at 08:04
  • but if there is more than one call to glBindBuffer(GL_ARRAY_BUFFER, VBO) with multiply generated VBO then are there multiple global states or something? – juztcode Jan 24 '20 at 08:09
  • 1
    @juztcode No, just the last one is stated. You have to bind the proper VBO before `glVertexAttribPointer`. The VAO can store one VBO for each attribute. – Rabbid76 Jan 24 '20 at 08:10
  • 1
    okay, so If I have a line of code containing `glBindBuffer(...); glBindBuffer(...); ` then the first buffer is lost since no call to `glVertexAttribPointer` was made? – juztcode Jan 24 '20 at 08:11
  • 1
    okay, I finally got it thanks. But, the binding is lost, but the generated VBO isn't deleted right? How do we delete it? – juztcode Jan 24 '20 at 08:15
  • @juztcode No it is not deleted. You have to call [`glDeleteBuffers`](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDeleteBuffers.xhtml) explicitly, to delete a buffer object. OpenGL is a state engine. The global state just names the object which is used for operations (such as `glVertexAttribPointer`) – Rabbid76 Jan 24 '20 at 08:17