【发布时间】:2014-10-01 06:28:23
【问题描述】:
我正在编写一些代码来加载一些模型,作为其中的一部分,我想将交错的顶点数据添加到 VBO,但是当我尝试添加数据到顶点缓冲区,几个子网格不渲染。当我为每个元素(vvv、tt、nnn)使用单个 VBO 时,顶点和索引本身就非常好。但是,对于交错的 VBO,如果我为我的 VBO 的 std::vector 数据使用 3D 矢量,则完整的网格将正确绘制(尽管纹理搞砸了,可能是使用 3D 而不是 2D 矢量)。为了绘制网格,我循环每个子网格并因此使用 glDrawElementsBaseVertex:
glDrawElementsBaseVertex(GL_TRIANGLES,
g_submeshes[i].numIndices,
GL_UNSIGNED_INT,
(void*)(sizeof(uint)* g_submeshes[i].baseIndex),
g_submeshes[i].baseVertex);
你能发现我做错了什么吗?
模型加载函数:
void Sprite::InitMesh(uint p_meshIndex,
const aiMesh* p_mesh,
vector<aiVector3D>& p_posVec,
vector<aiVector3D>& p_normVec,
vector<aiVector2D>& p_uvVec,
vector<VertexBoneData>& p_bones,
vector<uint>& p_indices)
{
const aiVector3D m_zero(0.0f, 0.0f, 0.0f);
const int m_totalSize = sizeof(aiVector3D)* 2 + sizeof(aiVector2D);
int m_totalVerts = 0;
int m_totalIndices = 0;
for (uint i=0; i < g_scene->mNumMeshes; ++i)
{
aiMesh* m_mesh = g_scene->mMeshes[i];
int m_numFaces = m_mesh->mNumFaces;
g_matIndices.push_back(m_mesh->mMaterialIndex);
int m_prevSize = g_vertexBuffer[0].GetCurrentSize();
g_meshIndices.push_back(m_prevSize / m_totalSize);
g_submeshes[i].materialIndex = m_mesh->mMaterialIndex;
g_submeshes[i].numIndices = m_mesh->mNumFaces * 3;
g_submeshes[i].baseVertex = m_totalVerts;
g_submeshes[i].baseIndex = m_totalIndices;
for (unsigned int m = 0; m < m_mesh->mNumVertices; ++m) //Initialise the meshes in the scene
{
const aiVector3D* m_pos = &(m_mesh->mVertices[m]);
const aiVector3D* m_normal = &(m_mesh->mNormals[m]);
const aiVector3D* m_tex = m_mesh->HasTextureCoords(0) ? &(m_mesh->mTextureCoords[0][m]) : &m_zero;
p_posVec.push_back(aiVector3D(m_pos->x, m_pos->y, m_pos->z));
p_normVec.push_back(aiVector3D(m_normal->x, m_normal->y, m_normal->z));
p_uvVec.push_back(aiVector2D(m_tex->x, m_tex->y));
g_vertexBuffer[0].AddData(&p_posVec[m], sizeof(p_posVec[m]));
g_vertexBuffer[0].AddData(&p_uvVec[m], sizeof(p_uvVec[m]));
g_vertexBuffer[0].AddData(&p_normVec[m], sizeof(p_normVec[m]));
}
for (uint j = 0; j < m_numFaces; ++j)
{
const aiFace& m_face = m_mesh->mFaces[j];
assert(m_face.mNumIndices == 3);
for (uint k = 0; k < 3; ++k)
{
p_indices.push_back(m_face.mIndices[k]);
g_vertexBuffer[1].AddData(&(m_face.mIndices[k]), sizeof(GLuint));
}
}
int m_meshVerts = m_mesh->mNumVertices;
m_totalVerts += m_meshVerts;
g_meshSizes.push_back((g_vertexBuffer[0].GetCurrentSize() - m_prevSize) / m_totalSize);
m_totalIndices += g_submeshes[i].numIndices;
}
}
AddData 函数:
void VertexBufferObject::AddData(void* p_ptr_data, UINT p_dataSize)
{
g_data.insert(g_data.end(), static_cast<BYTE*>(p_ptr_data), static_cast<BYTE*>(p_ptr_data) + p_dataSize);
g_dataSize += p_dataSize;
}
上传到 GPU
void Sprite::FinalizeVBO()
{
glGenVertexArrays(1, &g_VAO);
glBindVertexArray(g_VAO);
g_vertexBuffer[0].BindVBO();
g_vertexBuffer[0].UploadDataToGPU(GL_STATIC_DRAW);
glEnableVertexAttribArray(POSITION_LOCATION);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 2 * sizeof(aiVector3D)+sizeof(aiVector2D), 0);
// Texture coordinates
glEnableVertexAttribArray(TEX_COORD_LOCATION);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(aiVector3D)+sizeof(aiVector2D), (void*)sizeof(aiVector3D));
// Normal vectors
glEnableVertexAttribArray(NORMAL_LOCATION);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 2 * sizeof(aiVector3D)+sizeof(aiVector2D), (void*)(sizeof(aiVector3D)+sizeof(aiVector2D)));
g_vertexBuffer[1].BindVBO(GL_ELEMENT_ARRAY_BUFFER);
g_vertexBuffer[1].UploadDataToGPU(GL_STATIC_DRAW);
glBindVertexArray(0);
}
【问题讨论】:
标签: c++ opengl vector casting vertex-buffer