使用 Assimp 和 OpenGL ES 绘制的骨架网格不正确
Incorrect skeleton mesh drawn using Assimp and OpenGL ES
我正在尝试使用 ASSIMP 绘制骨架动画网格(模型 boblampclean.md5mesh),但网格绘制不正确。网格已正确加载 我正在按照 ogld 教程加载和绘制网格。下面是我的一些代码和输出:
这是填充缓冲区以及最初生成 VAO、VBO 和 EBO 的方式:
GLCall(glBufferData(GL_ARRAY_BUFFER, m_Positions.size() * sizeof(m_Positions[0]),&m_Positions[0],GL_STATIC_DRAW))
GLCall(glEnableVertexAttribArray(POSITION_LOCATION))
GLCall(glVertexAttribPointer(POSITION_LOCATION, 3, GL_FLOAT, GL_FALSE, 0,nullptr))
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[TEXCOORD_VB]))
GLCall(glBufferData(GL_ARRAY_BUFFER, m_TexCoords.size() * sizeof(m_TexCoords[0]),&m_TexCoords[0],GL_STATIC_DRAW))
GLCall(glEnableVertexAttribArray(TEX_COORD_LOCATION))
GLCall(glVertexAttribPointer(TEX_COORD_LOCATION, 2, GL_FLOAT, GL_FALSE, 0, nullptr))
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[NORMAL_VB]))
GLCall(glBufferData(GL_ARRAY_BUFFER, m_Normals.size() * sizeof(m_Normals[0]), &m_Normals[0], GL_STATIC_DRAW))
GLCall(glEnableVertexAttribArray(NORMAL_LOCATION))
GLCall(glVertexAttribPointer(NORMAL_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, nullptr))
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[BONE_VB]))
GLCall(glBufferData(GL_ARRAY_BUFFER, m_Bones.size() * sizeof(m_Bones[0]), &m_Bones[0],GL_STATIC_DRAW))
GLCall(glEnableVertexAttribArray(BONE_ID_LOCATION))
GLCall(glVertexAttribIPointer(BONE_ID_LOCATION, MAX_NUM_BONES_PER_VERTEX, GL_INT,sizeof(VertexBoneData), nullptr))
GLCall(glEnableVertexAttribArray(BONE_WEIGHT_LOCATION))
GLCall(glVertexAttribPointer(BONE_WEIGHT_LOCATION, MAX_NUM_BONES_PER_VERTEX, GL_FLOAT, GL_FALSE,sizeof(VertexBoneData),(const GLvoid *) (MAX_NUM_BONES_PER_VERTEX * sizeof(int32_t))))
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Buffers[INDEX_BUFFER]))
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(m_Indices[0]), &m_Indices[0],GL_STATIC_DRAW))
绘图调用:
GLCall(glUseProgram(meshProgram))
glm::mat4 projection = glm::perspective(45.0f,
(float) windowWidth / (float) windowHeight,
0.1f,
100.0f);
glm::mat4 translate = glm::translate(glm::mat4(1.0), glm::vec3(0.0f, 0.0f, 50.0f));
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(120.0f),
glm::vec3(0.0f, 1.0f, 1.0f));
glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.2, 0.2, 0.2));
glm::mat4 model = translate * rotation * scale;
GLCall(GLuint projectionLocation = meshShader->getUniformLocation("projection"))
GLCall(GLuint modelLocation = meshShader->getUniformLocation("model"))
meshCamera->useCamera();
std::vector<Matrix4f> boneMatrix;
mesh->GetBoneTransforms(mesh->getAnimationSecond(), boneMatrix);
GLuint mBoneLocation[100];
for (unsigned int i = 0; i < ARRAY_SIZE_IN_ELEMENTS(mBoneLocation); i++) {
char Name[128];
memset(Name, 0, sizeof(Name));
snprintf(Name, sizeof(Name), "gBones[%d]", i);
GLCall(mBoneLocation[i] = meshShader->getUniformLocation(Name))
}
for (int i = 0; i < boneMatrix.size(); ++i) {
if (i >= 100) {
break;
}
Matrix4f matrix = boneMatrix[i];
GLCall(glUniformMatrix4fv(mBoneLocation[i], 1, GL_TRUE, (const GLfloat *) matrix))
}
// GLCall(GLuint meshTextureLocation = meshShader->getUniformLocation("texture"))
GLCall(meshShader->setUniformMatrix4fv(projectionLocation, 1, glm::value_ptr(projection)))
GLCall(meshShader->setUniformMatrix4fv(modelLocation, 1, glm::value_ptr(model)))
Vector3f localPos = mesh->GetWorldTransform().WorldPosToLocalPos(meshCamera->getCameraPos());
GLCall(GLuint localCameraPosLocation = meshShader->getUniformLocation("gCameraLocalPos"))
GLCall(glUniform3f(localCameraPosLocation, localPos.x, localPos.y, localPos.z))[![enter image description here][1]][1]
GLCall(glBindVertexArray(m_VAO))
for (auto &m_Meshe : m_Meshes) {
unsigned int MaterialIndex = m_Meshe.MaterialIndex;
if (m_Materials[MaterialIndex].pDiffuse) {
Texture *texture = m_Materials[MaterialIndex].pDiffuse;
GLCall(texture->bind())
GLCall(GLuint diffuseLocation = glGetUniformLocation(program, "gSampler"))
GLCall(glUniform1i(diffuseLocation, texture->getSlot()))
}
if (m_Materials[MaterialIndex].pSpecularExponent) {
Texture *texture = m_Materials[MaterialIndex].pSpecularExponent;
GLCall(GLuint specularLocation = glGetUniformLocation(program,
"gSamplerSpecularExponent"))
GLCall(texture->bind())
GLCall(glUniform1i(specularLocation, texture->getSlot()))
}
GLCall(glDrawElementsBaseVertex(GL_TRIANGLES, m_Meshe.NumIndices, GL_UNSIGNED_INT,
(GLvoid *) (sizeof(unsigned int) * m_Meshe.BaseIndex),
m_Meshe.BaseVertex))
}
GLCall(glBindVertexArray(0))
输出:
我设法通过正确存储法线、顶点和 Texchord 来修复它。
我正在尝试使用 ASSIMP 绘制骨架动画网格(模型 boblampclean.md5mesh),但网格绘制不正确。网格已正确加载 我正在按照 ogld 教程加载和绘制网格。下面是我的一些代码和输出:
这是填充缓冲区以及最初生成 VAO、VBO 和 EBO 的方式:
GLCall(glBufferData(GL_ARRAY_BUFFER, m_Positions.size() * sizeof(m_Positions[0]),&m_Positions[0],GL_STATIC_DRAW))
GLCall(glEnableVertexAttribArray(POSITION_LOCATION))
GLCall(glVertexAttribPointer(POSITION_LOCATION, 3, GL_FLOAT, GL_FALSE, 0,nullptr))
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[TEXCOORD_VB]))
GLCall(glBufferData(GL_ARRAY_BUFFER, m_TexCoords.size() * sizeof(m_TexCoords[0]),&m_TexCoords[0],GL_STATIC_DRAW))
GLCall(glEnableVertexAttribArray(TEX_COORD_LOCATION))
GLCall(glVertexAttribPointer(TEX_COORD_LOCATION, 2, GL_FLOAT, GL_FALSE, 0, nullptr))
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[NORMAL_VB]))
GLCall(glBufferData(GL_ARRAY_BUFFER, m_Normals.size() * sizeof(m_Normals[0]), &m_Normals[0], GL_STATIC_DRAW))
GLCall(glEnableVertexAttribArray(NORMAL_LOCATION))
GLCall(glVertexAttribPointer(NORMAL_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, nullptr))
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[BONE_VB]))
GLCall(glBufferData(GL_ARRAY_BUFFER, m_Bones.size() * sizeof(m_Bones[0]), &m_Bones[0],GL_STATIC_DRAW))
GLCall(glEnableVertexAttribArray(BONE_ID_LOCATION))
GLCall(glVertexAttribIPointer(BONE_ID_LOCATION, MAX_NUM_BONES_PER_VERTEX, GL_INT,sizeof(VertexBoneData), nullptr))
GLCall(glEnableVertexAttribArray(BONE_WEIGHT_LOCATION))
GLCall(glVertexAttribPointer(BONE_WEIGHT_LOCATION, MAX_NUM_BONES_PER_VERTEX, GL_FLOAT, GL_FALSE,sizeof(VertexBoneData),(const GLvoid *) (MAX_NUM_BONES_PER_VERTEX * sizeof(int32_t))))
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Buffers[INDEX_BUFFER]))
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_Indices.size() * sizeof(m_Indices[0]), &m_Indices[0],GL_STATIC_DRAW))
绘图调用:
GLCall(glUseProgram(meshProgram))
glm::mat4 projection = glm::perspective(45.0f,
(float) windowWidth / (float) windowHeight,
0.1f,
100.0f);
glm::mat4 translate = glm::translate(glm::mat4(1.0), glm::vec3(0.0f, 0.0f, 50.0f));
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(120.0f),
glm::vec3(0.0f, 1.0f, 1.0f));
glm::mat4 scale = glm::scale(glm::mat4(1.0), glm::vec3(0.2, 0.2, 0.2));
glm::mat4 model = translate * rotation * scale;
GLCall(GLuint projectionLocation = meshShader->getUniformLocation("projection"))
GLCall(GLuint modelLocation = meshShader->getUniformLocation("model"))
meshCamera->useCamera();
std::vector<Matrix4f> boneMatrix;
mesh->GetBoneTransforms(mesh->getAnimationSecond(), boneMatrix);
GLuint mBoneLocation[100];
for (unsigned int i = 0; i < ARRAY_SIZE_IN_ELEMENTS(mBoneLocation); i++) {
char Name[128];
memset(Name, 0, sizeof(Name));
snprintf(Name, sizeof(Name), "gBones[%d]", i);
GLCall(mBoneLocation[i] = meshShader->getUniformLocation(Name))
}
for (int i = 0; i < boneMatrix.size(); ++i) {
if (i >= 100) {
break;
}
Matrix4f matrix = boneMatrix[i];
GLCall(glUniformMatrix4fv(mBoneLocation[i], 1, GL_TRUE, (const GLfloat *) matrix))
}
// GLCall(GLuint meshTextureLocation = meshShader->getUniformLocation("texture"))
GLCall(meshShader->setUniformMatrix4fv(projectionLocation, 1, glm::value_ptr(projection)))
GLCall(meshShader->setUniformMatrix4fv(modelLocation, 1, glm::value_ptr(model)))
Vector3f localPos = mesh->GetWorldTransform().WorldPosToLocalPos(meshCamera->getCameraPos());
GLCall(GLuint localCameraPosLocation = meshShader->getUniformLocation("gCameraLocalPos"))
GLCall(glUniform3f(localCameraPosLocation, localPos.x, localPos.y, localPos.z))[![enter image description here][1]][1]
GLCall(glBindVertexArray(m_VAO))
for (auto &m_Meshe : m_Meshes) {
unsigned int MaterialIndex = m_Meshe.MaterialIndex;
if (m_Materials[MaterialIndex].pDiffuse) {
Texture *texture = m_Materials[MaterialIndex].pDiffuse;
GLCall(texture->bind())
GLCall(GLuint diffuseLocation = glGetUniformLocation(program, "gSampler"))
GLCall(glUniform1i(diffuseLocation, texture->getSlot()))
}
if (m_Materials[MaterialIndex].pSpecularExponent) {
Texture *texture = m_Materials[MaterialIndex].pSpecularExponent;
GLCall(GLuint specularLocation = glGetUniformLocation(program,
"gSamplerSpecularExponent"))
GLCall(texture->bind())
GLCall(glUniform1i(specularLocation, texture->getSlot()))
}
GLCall(glDrawElementsBaseVertex(GL_TRIANGLES, m_Meshe.NumIndices, GL_UNSIGNED_INT,
(GLvoid *) (sizeof(unsigned int) * m_Meshe.BaseIndex),
m_Meshe.BaseVertex))
}
GLCall(glBindVertexArray(0))
输出:
我设法通过正确存储法线、顶点和 Texchord 来修复它。