I have been playing around with OpenGL for a while now and wanted to get familiar with Vertex Array Objects(VAO's). I am using the cube example here to test with. First of all I verified that I could draw a cube by manually binding the two Vertex Buffers and Element Array Buffer and Vertex Attribs for each call of the render function Here is my code
void Project::initTest(void)
{
GLfloat cube_vertices[] = {
// front
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// back
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0,
};
glGenBuffers(1, &vbo[0]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);
GLfloat cube_colors[] = {
// front colors
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 1.0,
// back colors
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 1.0,
};
glGenBuffers(1, &vbo[1]);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_colors), cube_colors, GL_STATIC_DRAW);
GLushort cube_elements[] = {
// front
0, 1, 2,
2, 3, 0,
// top
3, 2, 6,
6, 7, 3,
// back
7, 6, 5,
5, 4, 7,
// bottom
4, 5, 1,
1, 0, 4,
// left
4, 0, 3,
3, 7, 4,
// right
1, 5, 6,
6, 2, 1,
};
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_elements), cube_elements, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glBindBuffer(GL_ARRAY_BUFFER,0);
}
And here is the draw function
void Project::drawTest()
{
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0, 3,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 1);
glVertexAttribPointer(1,3,GL_FLOAT,GL_FALSE,0,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
}
The result is a cube as expected.
Using Vertex Array Object This is my implementation of the buffers being packed into a VAO. The initTest() with the following code:
void Project::initTest()
{
//Upload Vertex Data into VBO's
//Upload Index Data into Element Array Buffer
//...
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER,vbo[0]);//Position Buffer
glBindBuffer(GL_ARRAY_BUFFER,vbo[1]);//Colour Buffer
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);
glBindVertexArray(0);
//Unbind ARRAY and ELEMENT_ARRAY Buffers like before
}
Then in my draw function I just call the VAO like this
void Project::drawDebug()
{
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES,36, GL_UNSIGNED_SHORT, 0);
glBindVertexArray(0);
}
However the result is this:
Ultimately, I would like to know where I am going wrong with this. I also would like to know if you bind an ELEMENT_ARRAY_BUFFER within the currently bound VAO, do you need to explicity rebind that ELEMENT_ARRAY_BUFFER before calling glDraw* or does the VAO detect that it has an index buffer and renders using indices.