1

I'm in the process of learning OpenGL (3.3) with C++, I can draw simple polygons using Vertex Buffer Objects, Vertex Array Objects, and Index Buffers, but the way I code them still feels a little like magic, so I'd like to understand what's going on behind the scenes.

I have a basic understanding of the binding system OpenGL uses. I also understand that the VAO itself contains the bound index buffer (as specified here), and if I'm not mistaken the bound vertex buffer too.

By this logic, I first bind the VAO, then create my VBO (which behind the scenes is bound "inside" the VAO?), I can perform operations on the VBO, and it will all work. But then when I come to unbind the buffers I used after I'm done setting up things, it seems that I must unbind the VAO first, then the vertex & index buffers, so the unbinding occurs in the same order as the binding, and not in reverse order.

That is extremely counter intuitive. So my question is, why does the order of unbinding matter?

(to clarify, I am rebinding the VAO anyway before calling glDrawElements, so I don't think I even need to unbind anything at all. it's mostly for learning purposes)

Here's the relevant code:

GLuint VAO, VBO, IBO;

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

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

glBindVertexArray(0); //unbinding VAO here is fine
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//if I unbind VAO here instead, it won't render the shape anymore


while (!glfwWindowShouldClose(window)) {
    glfwPollEvents();

    glUseProgram(shaderProgram);
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0);

    glfwSwapBuffers(window);
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
aradarbel10
  • 435
  • 3
  • 10

1 Answers1

-2

I believe I might have figured it out. Looking at this unbinding order

glBindBuffer(GL_ARRAY_BUFFER, 0); //unbinding VBO
glBindVertexArray(0); //unbinding VAO

clearly "ruins" my polygons, because unbinding the VBO while my VAO is still bound means the VBO, which is supposed to "contain" references to the buffers it uses, is now not bound to a vertex buffer anymore. It doesn't know about the buffers.

Unbinding the VAO first allows me to then unbind any buffers without affecting it. This would be the correct order.

glBindVertexArray(0); //unbinding VAO
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbinding VBO

OpenGL's binding system is a little hard to grasp, especially when different things depend on one another, but I think my explanation is correct. Hopefully this could help some other learners in the future.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
aradarbel10
  • 435
  • 3
  • 10
  • 3
    The unbinding of a `GL_ARRAY_BUFFER` before the VAO shouldn't matter. A `GL_ELEMENT_ARRAY_BUFFER` may not be unbound before the VAO is unbound. The reason is that the connection between VAO and an array buffer is stored when `glVertexAttribPointer` is called, but for element array buffers there is no other explicit way of establishing the connection except for binding the buffer. – BDL Jul 21 '21 at 08:39
  • *" I think my explanation is correct."* - No, it is absolutely wrong. The VBO (`GL_ARRAY_BUFFER`) is **not** bound to the VAO. The VAO and VOB binding are global states, so the binding order (and "unbinding" order) doesn't matter. However, the element buffer binding (`GL_ELEMENT_ARRAY_BUFFER`) is not a global state the EBO is stated in the VAO. – Rabbid76 Jul 09 '22 at 13:48
  • In short, replacing `GL_ARRAY_BUFFER` with `GL_ELEMENT_ARRAY_BUFFER` would make your answer correct. (`GL_ARRAY_BUFFER` and `GL_ELEMENT_ARRAY_BUFFER` behave differently) – Rabbid76 Jul 09 '22 at 13:52
  • *"Hopefully this could help some other learners in the future."* - **For anyone reading this answer, please don't believe it, it's wrong!** – Rabbid76 Jul 09 '22 at 13:54