I'm developing a small project and I'm using VBO, IBO and VAO, I have an array of vertices, and its respective array indices, I do the same with the materials (since the same vertex can have a different material other side ) but this link in a VAO same does not display anything. For every single VAO must be an IBO?
Attached is my code in which sending data to the gpu and render respectively!
I would appreciate your help, greetings :)
void Upload(){
GLuint ibo[2], vbo[3];
glGenBuffers(3, vbo);
glGenBuffers(2, ibo);
glGenVertexArrays(1, vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); //Vertices
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vec3), vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); //Normales
glBufferData(GL_ARRAY_BUFFER, vertex_normal.size()*sizeof(vec3), vertex_normal.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, v_indices.size()*sizeof(GLuint), v_indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[2]); //Material
glBufferData(GL_ARRAY_BUFFER, materials.size()*sizeof(Material), materials.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size()*sizeof(GLuint), m_indices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(vao[0]);
//Vertices:
glEnableVertexAttribArray(attrib_vertex);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(attrib_vertex, 3, GL_FLOAT, GL_FALSE, 0, 0);
//Normales:
glEnableVertexAttribArray(attrib_normal);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, 0, 0);
//IBO:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
//Materiales:
for(int i=0; i<5; ++i)
glEnableVertexAttribArray(attrib_material+i);
glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
glVertexAttribPointer(attrib_material, 4, GL_FLOAT, GL_FALSE, sizeof(Material), NULL);
glVertexAttribPointer(attrib_material+1, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, diffuse));
glVertexAttribPointer(attrib_material+2, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, specular));
glVertexAttribPointer(attrib_material+3, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, emission));
glVertexAttribPointer(attrib_material+4, 1, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, shininess));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]);
//Desactivando todo:
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glDisableVertexAttribArray(attrib_vertex);
glDisableVertexAttribArray(attrib_normal);
for(int i=0; i<5; ++i)
glDisableVertexAttribArray(attrib_material+i);
}
void Draw(){
glBindVertexArray(vao[0]);
glDrawElements(GL_TRIANGLES, v_indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
Each VAO stores the value of the current GL_ELEMENT_ARRAY_BUFFER_BINDING
.
That stored value is set when you call glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0])
and glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1])
.
The problem with your code is that your second call to glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...)
is overwriting the value stored by the first call. This happens because each VAO can only store a single value for GL_ELEMENT_ARRAY_BUFFER_BINDING
. That is, there is only 1 IBO allowed per VAO.
Some solutions I propose:
glVertexAttribDivisor
if your data fits the pattern.Either way, the central issue is that you can only have 1 IBO per VAO. You'll have to be creative to find a solution that fits your use. Good luck!