Fix mesh rendering for meshes with more than one submesh

The buffer offset was encoded in the VAO which would be shared across all
submeshes. Instead, don't encode the buffer offset into the VAO but apply it
with glDrawElementsBaseVertex().
objectmenu
Armin Burgmeier 2016-01-17 11:34:14 -08:00
parent fd61ac7ebe
commit d387fdb270
1 changed files with 16 additions and 8 deletions

View File

@ -753,17 +753,23 @@ namespace
if (!has_vao)
{
// Bind the vertex data of the mesh
// Note this relies on the fact that all vertex
// attributes for all shaders are at the same
// locations.
// TODO: And this fails if the mesh changes
// from a material with texture to one without
// or vice versa.
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
#define VERTEX_OFFSET(field) reinterpret_cast<const uint8_t *>(offsetof(StdMeshVertex, field))
glVertexAttribPointer(shader->GetAttribute(C4SSA_Position), 3, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), vertex_buffer_offset + VERTEX_OFFSET(x));
glVertexAttribPointer(shader->GetAttribute(C4SSA_Normal), 3, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), vertex_buffer_offset + VERTEX_OFFSET(nx));
glVertexAttribPointer(shader->GetAttribute(C4SSA_Position), 3, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), VERTEX_OFFSET(x));
glVertexAttribPointer(shader->GetAttribute(C4SSA_Normal), 3, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), VERTEX_OFFSET(nx));
if (shader->GetAttribute(C4SSA_TexCoord) != -1)
glVertexAttribPointer(shader->GetAttribute(C4SSA_TexCoord), 2, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), vertex_buffer_offset + VERTEX_OFFSET(u));
glVertexAttribPointer(shader->GetAttribute(C4SSA_BoneWeights0), 4, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), vertex_buffer_offset + VERTEX_OFFSET(bone_weight));
glVertexAttribPointer(shader->GetAttribute(C4SSA_BoneWeights1), 4, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), vertex_buffer_offset + VERTEX_OFFSET(bone_weight) + 4 * sizeof(std::remove_all_extents<decltype(StdMeshVertex::bone_weight)>::type));
glVertexAttribPointer(shader->GetAttribute(C4SSA_BoneIndices0), 4, GL_SHORT, GL_FALSE, sizeof(StdMeshVertex), vertex_buffer_offset + VERTEX_OFFSET(bone_index));
glVertexAttribPointer(shader->GetAttribute(C4SSA_BoneIndices1), 4, GL_SHORT, GL_FALSE, sizeof(StdMeshVertex), vertex_buffer_offset + VERTEX_OFFSET(bone_index) + 4 * sizeof(std::remove_all_extents<decltype(StdMeshVertex::bone_index)>::type));
glVertexAttribPointer(shader->GetAttribute(C4SSA_TexCoord), 2, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), VERTEX_OFFSET(u));
glVertexAttribPointer(shader->GetAttribute(C4SSA_BoneWeights0), 4, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), VERTEX_OFFSET(bone_weight));
glVertexAttribPointer(shader->GetAttribute(C4SSA_BoneWeights1), 4, GL_FLOAT, GL_FALSE, sizeof(StdMeshVertex), VERTEX_OFFSET(bone_weight) + 4 * sizeof(std::remove_all_extents<decltype(StdMeshVertex::bone_weight)>::type));
glVertexAttribPointer(shader->GetAttribute(C4SSA_BoneIndices0), 4, GL_SHORT, GL_FALSE, sizeof(StdMeshVertex), VERTEX_OFFSET(bone_index));
glVertexAttribPointer(shader->GetAttribute(C4SSA_BoneIndices1), 4, GL_SHORT, GL_FALSE, sizeof(StdMeshVertex), VERTEX_OFFSET(bone_index) + 4 * sizeof(std::remove_all_extents<decltype(StdMeshVertex::bone_index)>::type));
glEnableVertexAttribArray(shader->GetAttribute(C4SSA_Position));
glEnableVertexAttribArray(shader->GetAttribute(C4SSA_Normal));
if (shader->GetAttribute(C4SSA_TexCoord) != -1)
@ -834,7 +840,9 @@ namespace
}
size_t vertex_count = 3 * instance.GetNumFaces();
glDrawElements(GL_TRIANGLES, vertex_count, GL_UNSIGNED_INT, reinterpret_cast<void*>(index_buffer_offset));
assert (vertex_buffer_offset % sizeof(StdMeshVertex) == 0);
size_t base_vertex = vertex_buffer_offset / sizeof(StdMeshVertex);
glDrawElementsBaseVertex(GL_TRIANGLES, vertex_count, GL_UNSIGNED_INT, reinterpret_cast<void*>(index_buffer_offset), base_vertex);
glBindVertexArray(0);
call.Finish();