我有一个网格类如下
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);
}
我需要更新顶点数据。如果我删除网格并使用构造函数加载顶点数据,一切正常。
如果我使用第一个构造函数初始化它并使用setData
函数加载顶点数据,则此类的多个实例仅渲染最后一个调用setData
的实例。
我做错了什么?
答案 0 :(得分:2)
glGenBuffers仅在调用方法时返回可用的缓冲区名称,它不保留这些名称。因此,下次你调用glGenBuffers而不将任何东西绑定到glGenBuffers调用的第一个缓冲区时,你会得到相同的名字,因为它们还没有被使用过。当您稍后调用glBindBuffers时,您会发现所有实例的VBO都使用相同的名称,因此它们会相互覆盖。
您还尝试将元素数组缓冲区绑定为顶点属性,但这并非如此 有意义,因为索引被用作glDrawElements的一部分(除非你使用 出于某种原因,它们在你的着色器中。)
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_SHORT, GL_FALSE, 0, NULL);
// ^~~~~ but your indices are GL_UNSIGNED_SHORT
在相关的说明中:在使用VAO绘制之前,每次都不需要绑定索引缓冲区,因为索引缓冲区是VAO state的一部分。使用glVertexPointer *函数绑定指定的顶点数据,因此顶点 - >属性绑定及其相应的VBO也是状态的一部分,但GL_ARRAY_BUFFER不是。