Перемеженный буфер вершин не отображается правильно
Я нахожусь в процессе написания небольшого кода для загрузки некоторых моделей, в качестве части этого я хочу добавить чередующиеся данные вершин в VBO, однако я заметил странное поведение, когда пытаюсь добавить данные в Vertex Buffer, пара подрешеток не рендерится. Сами вершины и индексы прекрасно работают, когда я использую один VBO для каждого элемента (vvv, tt, nnn). Тем не менее, с чередованным VBO, если я использую трехмерный вектор для std:: vector данных моего VBO, полная сетка будет отображаться правильно (хотя с испорченными текстурами, вероятно, из-за использования трехмерного, а не двухмерного вектора). Чтобы нарисовать сетку, я зацикливаю каждую из подсетей и использую 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);
}
1 ответ
Вы добавляете новые сетки, но используете те же индексы
{
p_indices.push_back(m_face.mIndices[k]);
g_vertexBuffer[1].AddData(&(m_face.mIndices[k]), sizeof(GLuint));
}
Скажем, у вас есть две сетки, каждая из которых состоит из одного треугольника... ваш буфер вершин выглядит так:
[ V0, V1, V2, V3, V4, V5 ]
И ваш индексный буфер выглядит так:
[ 0, 1, 2, 0, 1, 2 ]
Но вы хотите, чтобы это выглядело так:
[ 0, 1, 2, 3, 4, 5 ]
Это означает, что когда вы добавляете индексы в буфер массива элементов, вы должны увеличивать их на счетчик всех уже увиденных индексов, иначе они будут указывать на предыдущие сетки.