OpenGL 2.x スタイルの頂点配列を使用して OpenGL 3.x で動作するエンジンを更新しようとしています。これは、VAO/VBO への更新を意味します。私は VBO に適切にバインドしていないと思います。詳細については以下を読むか、コードにスキップして、私が間違っていることを見つけてください。
私のメッシュ クラスの簡単な概要は次のようになります。
メッシュ
- ルート MeshNode
MeshNode
- 変身
- VAO 指数
- インデックス VBO インデックス
- 子 MeshNode の配列
- MeshObject の配列
メッシュ オブジェクト
- メッシュ全体の 1 つの部分について、ファイルからロードされたすべての頂点およびインデックス データ
- 頂点 VBO インデックス
MeshObject を 1 つだけ使用して MeshNode を描画すると、うまく描画されるようです。複数の MeshObject を使用して MeshNode を描画すると、描画しようとしているモデルの全体的な形状が得られますが、文字化けしています。
Visual Studio デバッガーで頂点データを確認し、gDEbugger を使用して VBO データを確認したところ、すべて問題ないように見えたので、ファイルからの読み込みと VBO への読み込みが機能していると確信しています。
gDEbugger を使用して、三角形ではなくすべての頂点のポイントを描画するように強制しました。これは単一の MeshObject の形状をしているため、さまざまな VBO に適切にバインドしていないだけだと思います。異なるインデックスで描画しようとしているかのようですが、毎回同じ頂点です。
VertexData は次のようになります。
struct VertexData
{
enum
{
NUM_TEXCOORDS = 1,
};
vector3 vertex;
vector3 normal;
vector2 texCoord[NUM_TEXCOORDS];
};
関連する MeshNode コード:
void MeshNode::initVAO(void)
{
closeVAO();
unsigned int scan;
//init index data
if (m_meshObjects.size() > 0)
{
glGenVertexArrays(1, &m_meshVAO);
glBindVertexArray(m_meshVAO);
{
//add up the total index count for all the mesh objects in this node
unsigned int indexCount = 0;
for (scan = 0; scan < m_meshObjects.size(); ++scan)
{
indexCount = indexCount + m_meshObjects[scan].getIndices()->size();
}
//make the actual index buffer
glGenBuffers(1, &m_indexVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexVBO);
{
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexCount * sizeof(unsigned short), NULL, GL_STATIC_DRAW);
//set up VBOs and fill the index buffer with the index data from each mesh object
unsigned int offset = 0;
for (scan = 0; scan < m_meshObjects.size(); ++scan)
{
m_meshObjects[scan].initVBOs(offset);
}
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
glBindVertexArray(0);
}
for (scan = 0; scan < m_childMeshNodes.size(); ++scan)
{
m_childMeshNodes[scan]->initVAO();
}
}
void MeshNode::closeVAO(void)
{
if (m_meshVAO != 0)
{
glBindVertexArray(m_meshVAO);
{
glDeleteBuffers(1, &m_indexVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
glBindVertexArray(0);
glDeleteVertexArrays(1, &m_meshVAO);
m_meshVAO = 0;
m_indexVBO = 0;
}
}
void MeshNode::render(const matrix4 &_parentTransform)
{
matrix4 transform = _parentTransform * m_transform;
if (m_meshObjects.size() > 0)
{
glBindVertexArray(m_meshVAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexVBO);
{
for (unsigned int objectScan = 0; objectScan < m_meshObjects.size(); ++objectScan)
{
m_meshObjects[objectScan].render(transform);
}
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
for (unsigned int childScan = 0; childScan < m_childMeshNodes.size(); ++childScan)
{
m_childMeshNodes[childScan]->render(transform);
}
}
関連する MeshObject コード:
void MeshObject::initVBOs(unsigned int& _indexOffset)
{
//sub in this section of the index data
m_indexOffset = _indexOffset;
_indexOffset = _indexOffset + m_indices.size();
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, m_indexOffset * sizeof(unsigned short), m_indices.size() * sizeof(unsigned short), &(m_indices[0]));
//init vertex data
glGenBuffers(1, &m_vertexVBO);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexVBO);
{
glBufferData(GL_ARRAY_BUFFER, m_data.size() * sizeof(VertexData), &(m_data[0]), GL_STATIC_DRAW);
glVertexAttribPointer(Shader::POSITION, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (char*)0);
glEnableVertexAttribArray(Shader::POSITION);
glVertexAttribPointer(Shader::NORMAL, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), (char*)12);
glEnableVertexAttribArray(Shader::NORMAL);
glVertexAttribPointer(Shader::TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexData), (char*)24);
glEnableVertexAttribArray(Shader::TEXCOORD0);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void MeshObject::closeVBOs(void)
{
glDeleteBuffers(1, &m_vertexVBO);
m_vertexVBO = 0;
}
void MeshObject::render(const matrix4& _transform)
{
m_material->bind(_transform);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexVBO);
{
glEnableVertexAttribArray(Shader::POSITION);
glEnableVertexAttribArray(Shader::NORMAL);
glEnableVertexAttribArray(Shader::TEXCOORD0);
glDrawRangeElements(GL_TRIANGLES, m_indexOffset, m_indexOffset + m_indices.size(), m_indices.size(), GL_UNSIGNED_SHORT, (char*)0);
glDisableVertexAttribArray(Shader::POSITION);
glDisableVertexAttribArray(Shader::NORMAL);
glDisableVertexAttribArray(Shader::TEXCOORD0);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
}