I'm trying to draw a textured cube in OpengL. At first, I initialize VBO and VAO in the class constructor as follows.
Block::Block(...)
{
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
//glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VAO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(3 *
sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)(6 *
sizeof(float)));
glEnableVertexAttribArray(2);
}
and in the method called renderBlock(), I render the cube like this
void Block::renderBlock()
{
setMatrix();
shader.use();
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindVertexArray(VAO);
glActiveTexture(GL_TEXTURE0);
shader.setInt("tex", 0);
shader.use();
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_2D, texture);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
and if I call the block.renderBlock(), the program will crash at glDrawArrays(GL_TRIANGLES, 0, 6);
. The error message says that 0xC0000005: Access conflict occurred at read position 0x0000000000000000.
. But if I uncomment the //glBindBuffer(GL_ARRAY_BUFFER, VBO);
in constructer, the program will run successfully. It's very confusing to me. Why should I bind the VBO before I edit the VAO. Is there any connection between them?Any advice would be greatly appreciated.
CodePudding user response:
You must bind the VBO before calling glVertexAttribPointer
. When glVertexAttribPointer
is called, the buffer currently bound to the GL_ARRAY_BUFFER target
is associated with the specified attribute index and the ID of the buffer object is stored in the state vector of the currently bound VAO. Therefore, the VAO and the VBO must be bound before calling glVertexAttribPointer
.