My code is working as it should but it might be a coincidence and I don't want to dwell on a bug later so I'm trying to keep it as clean as possible:
I do the following for initializing a mesh:
- Gen and bind VBO and buffer data
- Gen and bind IBO and buffer data
- Gen and bind VAO
- Bind same VBO as before, generated in 1.
- Enable Vertex Attribute Arrays that I need and set the Vertex Attribute Pointers
- Bind the IBO again (don't exactly know why)
- BindVertexArray back to 0 so that I don't mess up the VAO I just created
From my understanding, the VAO will store the state of the vertex attribute arrays that I enabled. It will also store both the VBO and the IBO that I bound. Since I "closed" all actions on the VAO by binding the Vertex Array back to 0, I make sure no other code is going to mess my VAO. So if this is all right, all I need to render is:
- Bind VAO
- Draw Elements
- Unbind VAO (Binding to 0)
And this should bring both the AttribArray states as well as the VBO and IBO stored. My questions are:
A. Do I need to bind the IBO after I set the VertexAttribPointers? If so, why?
B. Does the VAO really store both the VBO and the IBO? I've heard it only stores the last buffer that was bound, meaning I have to render like this:
- Bind VAO
- Bind VBO
- Draw Elements
- Unbind VAO
But this makes no sense, why use VAOs when they don't store both buffer objects? Wouldn't it be just the same as binding VBO and IBO and then drawing elements without ever binding the VAO?
Thank you in advance for helping.
Code is as follows:
Initialisation
// generate VBO
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, m_vertices.size()*sizeof(GLfloat), m_vertices.data(), GL_STATIC_DRAW);
// generate IBO
glGenBuffers(1, &m_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size()*sizeof(unsigned short), m_indices.data(), GL_STATIC_DRAW);
// generate VAO
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
// set the vertex attribute pointer
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,vertexSize,reinterpret_cast<const GLvoid*>(0));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glBindVertexArray(0);
Drawing
glBindVertexArray(m_vao);
glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_SHORT,reinterpret_cast<const GLvoid*>(0));
glBindVertexArray(0);
Also, isn't it cleaner if I put it like this:
- Gen and bind VAO
- Gen and bind IBO and BufferData
- Gen and bind VBO and BufferData
- EnableVertexAttribArrays that I need and set VertexAttribPointers
- Unbind VAO (binding to 0)
Seems cleaner, but I don't know if the result is the same, specially for the lack of a IBO binding between steps 4 and 5.