Reputation: 4452
I have a mesh class as follows
Mesh_PTI::Mesh_PTI(bool dynamic) : m_dynamic(dynamic), m_drawCount(0)
{
glGenVertexArrays(1, m_vertexArrays);
glBindVertexArray(m_vertexArrays[0]);
glGenBuffers(NUM_BUFFERS, m_buffers);
glBindVertexArray(0);
}
Mesh_PTI::Mesh_PTI(glm::vec3 positions[], glm::vec2 texCoords[], unsigned short indices[], unsigned short numVertices, unsigned int numIndices, bool dynamic) :
m_dynamic(dynamic)
{
glGenVertexArrays(1, m_vertexArrays);
glBindVertexArray(m_vertexArrays[0]);
glGenBuffers(NUM_BUFFERS, m_buffers);
createBuffers(positions, texCoords, indices, numVertices, numIndices, false);
glBindVertexArray(0);
m_drawCount = numIndices;
}
Mesh_PTI::~Mesh_PTI()
{
glDeleteBuffers(NUM_BUFFERS, m_buffers);
glDeleteVertexArrays(1, m_vertexArrays);
}
void Mesh_PTI::draw()
{
if(m_drawCount > 0)
{
glBindVertexArray(m_vertexArrays[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffers[INDEX_VB]);
glDrawElements(GL_TRIANGLES, m_drawCount, GL_UNSIGNED_SHORT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
}
void Mesh_PTI::setData(glm::vec3 positions[], glm::vec2 texCoords[], unsigned short indices[], unsigned short numVertices, unsigned int numIndices)
{
glBindVertexArray(m_vertexArrays[0]);
createBuffers(positions, texCoords, indices, numVertices, numIndices, false);
glBindVertexArray(0);
m_drawCount = numIndices;
}
void Mesh_PTI::createBuffers(glm::vec3 positions[], glm::vec2 texCoords[], unsigned short indices[], unsigned short numVertices, unsigned int numIndices, bool dynamic)
{
glBindBuffer(GL_ARRAY_BUFFER, m_buffers[POSITION_VB]);
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(positions[0]), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, m_buffers[TEXCOORD_VB]);
glBufferData(GL_ARRAY_BUFFER, numVertices * sizeof(texCoords[0]), texCoords, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffers[INDEX_VB]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(indices[0]), indices, GL_STATIC_DRAW);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_SHORT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
I need to update the vertex data. If I delete the mesh and load the vertex data using the constructor, everything works fine.
If I initialize it with the first constructor and use the setData
function to load vertex data, multiple instances of this class only render the last one that had setData
called.
What am I doing wrong?
Upvotes: 0
Views: 194
Reputation: 1499
glGenBuffers only returns available buffer names at the time at which the method is called, it does not reserve those names. So the next time you call glGenBuffers without binding anything to the first buffers from the call of glGenBuffers, you will get the same names since they haven't been used yet. When you later call glBindBuffers, you will find all your instances are using the same names for their VBOs, so they are overwriting each other.
You are also trying to bind an element array buffer as a vertex attribute, which doesn't make any sense because indices are used as part of glDrawElements (unless you are using them in your shader for some reason).
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_SHORT, GL_FALSE, 0, NULL);
// ^~~~~ but your indices are GL_UNSIGNED_SHORT
On a related note: you don't need to bind your index buffer every time before you draw with a VAO, since the index buffer is part of the VAO state. Specified vertex data is bound using the glVertexPointer* functions, so the vertex->attribute bindings and their appropriate VBO is part of state as well, but GL_ARRAY_BUFFER isn't.
Upvotes: 2