Each mesh is the set of a VBO and an EBO, assuming you have multiple meshes with the same vertex format (ex: position, color), you could use the same VAO for each mesh, like this:
...
GLuint vao;
GLuint vbos[2];
GLuint ebos[2];
glGenBuffers(2, vbos);
glGenBuffers(2, ebos);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbos[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data_1), vertex_data_1, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbos[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data_2), vertex_data_2, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebos[0]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebos[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
while (!glfwWindowShouldClose((window))) {
...
glBindVertexArray(vao);
// Draw the first mesh
glBindBuffer(GL_ARRAY_BUFFER, vbos[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, (void*)0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24, (void*)12);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebos[0]);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
// Draw the second mesh
glBindBuffer(GL_ARRAY_BUFFER, vbos[1]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, (void*)0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24, (void*)12);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebos[1]);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
....
So whenever you need to draw a mesh you must first:
- Connect the vbo using
glBindBuffer()
- Associate the current VBO with each attribute of the VAO using
glVertexAttribPointer
- Connect and associate the EBO using glBindBuffer.
This mechanism works, but I think it is not optimal as you have to make many calls to draw each mesh, so I would like to know your opinion on the most efficient way, below are some solutions I have thought of:
-
Use one VAO for each mesh; each VAO would be identical to the others, except for the VBO and EBO attached to it, so before drawing a mesh you only need to call
glBindVertexArray
-
Put all vertex data in one VBO and all indexes in one EBO, and use only one VAO (we are basically talking about Batch rendering)
Is there some solution I missed?
Considering the three solutions, depending on the number of meshes (considering the case where there are few meshes and the case where there are many), what is the ranking for efficiency (speed, memory, security)?
Also in the case that I can use DSA architecture:
Is it possible to define a single VAO by specifying the attribute format once and change the associated VBO through the glBindVertexBuffer
function, or is it necessary to make multiple calls? if so which ones?
In this case how does the previously drafted ranking change?
Phoenix is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.