0
votes

I've encountered something really annoying regarding vertex array objects and vertex buffer objects.

Here's the code:

float vertex_data[] = 
{
     0.f,   0.5f,    0.f, 0.f, 1.f,
     0.5f, -0.5f,    0.f, 1.f, 0.f,
    -0.5f, -0.5f,    1.f, 0.f, 0.f
};
float vertex_data_2[] =
{
     0.f,   0.5f,    1.f, 0.f, 0.f,
     0.5f, -0.5f,    1.f, 0.f, 0.f,
    -0.5f, -0.5f,    1.f, 0.f, 0.f
};

unsigned int indices[] =
{
    0, 1, 2
};

unsigned int vertex_array, vertex_array_2;
glGenVertexArrays(1, &vertex_array);
glGenVertexArrays(1, &vertex_array_2);


IndexBuffer index_buffer(3 * sizeof(unsigned int), 3, GL_UNSIGNED_INT, indices);


glBindVertexArray(vertex_array);
VertexBuffer vertex_buffer(3 * 5 * sizeof(float), vertex_data);
vertex_buffer.Bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(0));

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(2 * sizeof(float)));
index_buffer.Bind();


glBindVertexArray(vertex_array_2);
VertexBuffer vertex_buffer_2(3 * 5 * sizeof(float), vertex_data_2);
vertex_buffer_2.Bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(0));

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), reinterpret_cast<void*>(2 * sizeof(float)));
index_buffer.Bind();


Shader shader(Shader::FromFile("rescources/shaders/basic.vs"), 
    Shader::FromFile("rescources/shaders/basic.fs"));

shader.Bind();

// main loop
while (!glfwWindowShouldClose(glfw_window))
{
    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.f, 0.f, 0.f, 1.f);

    // problem is here
    glBindVertexArray(vertex_array);
    vertex_buffer_2.Bind();
    glDrawElements(GL_TRIANGLES, index_buffer.GetCount(), index_buffer.GetType(), nullptr);


    glfwSwapBuffers(glfw_window);
    glfwPollEvents();
}

Sidenote: Bind() just calls glBindBuffer()

So basically I'm binding the second vertex buffer but glDrawElements() is still using the first vertex buffer for whatever reason. It's as if it is completely ignoring which vertex buffer is bound and only caring about which vertex array is bound. I found this strange since I was under the impression that vertex array objects don't bind vertex buffers. What's even stranger is that even if the vertex array object did bind the vertex buffer object it wouldn't matter in this case since Im binding the vbo after I bind the vao. Any help or clarifications?

1
@Cristy it's not an uint, it's a VertexBuffer which is a small wrapper class for vertex buffer objectsjono

1 Answers

1
votes

The binding between an attribute in the shader and the buffer to read from is done at glVertexAttribPointer with the current bound buffer (i.e., after yourBuffer.Bind()).

Those bindings (attribute-buffer) are stored in the VAO.

Thus, before calling glDrawXXX call glBindVertexArray and the right buffers are used. Binding a buffer after binding the VAO has no effect.