0
votes

For some reason, this program only works when I bind the IBO/EBO again, after I create the VAO. I read online, and multiple SO posts, that glBindBuffer only binds the current buffer, and that it does not attach it the the VAO. I thought the glVertexAttribPointer is the function that attached the data to the VAO.

float points[] = {

   -0.5f,  0.5f, 0.0f, // top left      = 0
    0.5f,  0.5f, 0.0f, // top right     = 1
    0.5f, -0.5f, 0.0f, // bottom right  = 2
   -0.5f, -0.5f, 0.0f, // bottom left   = 3

};

GLuint elements[] = {

    0, 1, 2,
    2, 3, 0,
};

// generate vbo (point buffer)
GLuint pb = 0;
glGenBuffers(1, &pb);
glBindBuffer(GL_ARRAY_BUFFER, pb);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);

// generate element buffer object (ibo/ebo)
GLuint ebo = 0;
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

// generate vao
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);


glBindBuffer(GL_ARRAY_BUFFER, pb);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);


glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); // when I bind buffer again, it works


glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

If I did not have the second glBindBuffer, the program crashes. All I want to know is why I have to call glBindBuffer again, after I create the VAO, when calling glBindBuffer only makes the buffer the active buffer for other functions.

Pastebin (FULL CODE)

2

2 Answers

2
votes

The problem is with the order of your initial calls. The GL_ELEMENT_ARRAY_BUFFER binding is part of the VAO state. Look at this sequence:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

Since the GL_ELEMENT_ARRAY_BUFFER binding is part of the VAO state, the glBindVertexArray() call at the end of the sequence will establish the GL_ELEMENT_ARRAY_BUFFER buffer binding that is part of the VAO vao you're binding. Which, since you just created vao, is 0. So at the end of this sequence, you have no element array buffer bound.

Or, looking at it from a different direction, when you make the glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo) call at the start, VAO 0 is bound. So this binding becomes part of the state of VAO 0. Then, when you bind a different VAO vao, you lose the binding, and it is replaced with the binding that is part of the state of VAO vao.

To make this work as you expected, you need to make the initial GL_ELEMENT_ARRAY_BUFFER binding after you bind the VAO. It then becomes part of the VAO state, and will be established again every time you bind the VAO later:

GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
-2
votes

If you look at the specification, the Vertex Array Object state does not include the Element Buffer Object.

Indeed, enabling the VAO does not set the element bindibg point.