Hi guys
I'm having some trouble getting my skeletal animation working. I've imported the model with Assimp, created the bone hierarchy, calculated all the bone transforms, so on and so forth. I've debugged through the code and the bone information *looks* like it's updating as I'd expect. The issue I'm having seems to come from the shader. As soon as I start using the bone information to update the position, the model ceases to display. I'm not sure whether this is because the bone information hasn't been successfully passed to the shader, the multiplications are wrong, or for some other reason (such as the model is now positioned out-of-view of the camera). If required I can post the entire contents of the class so you can see the entire process. Any input would be ace.
Here's the vertex shader code:
#version 330
layout (location = 0) in vec3 inPosition;
layout (location = 1) in vec2 inCoord;
layout (location = 2) in vec3 inNormal;
layout (location = 3) in ivec4 BoneIDs;
layout (location = 4) in vec4 Weights;
smooth out vec3 vNormal;
smooth out vec2 vTexCoord;
smooth out vec3 vWorldPos;
smooth out vec4 vEyeSpacePos;
uniform struct Matrices
{
mat4 projMatrix;
mat4 modelMatrix;
mat4 viewMatrix;
mat4 normalMatrix;
} matrices;
const int MAX_BONES = 100;
uniform mat4 gBones[MAX_BONES];
void main()
{
mat4 BoneTransform = gBones[BoneIDs[0]] * Weights[0];
BoneTransform += gBones[BoneIDs[1]] * Weights[1];
BoneTransform += gBones[BoneIDs[2]] * Weights[2];
BoneTransform += gBones[BoneIDs[3]] * Weights[3];
mat4 m_MV = matrices.viewMatrix*matrices.modelMatrix;
mat4 m_MVP = matrices.projMatrix*matrices.viewMatrix*matrices.modelMatrix;
vTexCoord = inCoord;
vec4 m_transPos = BoneTransform * vec4(inPosition, 1.0);
vEyeSpacePos = m_MV * m_transPos;
gl_Position = m_MVP * m_transPos;
vec4 m_normal = BoneTransform * vec4(inNormal, 1.0);
vNormal = (matrices.modelMatrix * m_normal).xyz;
vWorldPos = (matrices.modelMatrix * m_transPos).xyz;
}
Here's the Draw() function as it stands, in which the bone information and uniforms are passed to the shader:
void Sprite::Draw()
{
glBindVertexArray(g_VAO);
g_mainSP.UseProgram();
g_mainSP.SetUniform("matrices.projMatrix", g_projMat);
g_mainSP.SetUniform("matrices.viewMatrix", g_viewMat);
g_mainSP.SetModelAndNormalMatrix("matrices.modelMatrix", "matrices.normalMatrix", g_modelMat);
for (uint i = 0; i < g_transforms.size(); i++) {
g_mainSP.SetBoneTransform(i, g_transforms[i]);
}
g_mainSP.SetUniform("gSampler", 0);
g_mainSP.SetUniform("vColor", glm::vec4(1, 1, 1, 1));
g_ambient.SetUniformData(&g_mainSP, "sunLight");
if (!g_loaded)return;
for (uint i = 0; i < g_subMeshes.size(); i++)
{
const uint m_matIndex = g_subMeshes[i].materialIndex;
g_textures[m_matIndex].BindTexture();
aiMesh* m_mesh = g_scene->mMeshes[i];
glDrawElementsBaseVertex(GL_TRIANGLES,
g_subMeshes[i].numIndices,
GL_UNSIGNED_INT,
(void*)(sizeof(uint)* g_subMeshes[i].baseIndex),
g_subMeshes[i].baseVertex);
}
glBindVertexArray(0);
}
Finally:
void ShaderProgram::SetBoneTransform(glm::uint p_index, const glm::mat4& p_transform)
{
glUniformMatrix4fv(g_boneLoc[p_index], 1, GL_TRUE, glm::value_ptr<GLfloat>(p_transform));
}