Following a tutorial on importing animations using ASSIMP I've come across a problem in that the developers code was intended for a mesh where every vertex was affected by no more than 4 bones, which he thusly passed as two vec4's in the layout section.

Here is presumably his code:

Code :glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[BONE_VB]); glBufferData(GL_ARRAY_BUFFER, sizeof(Bones[0]) * Bones.size(), &Bones[0], GL_STATIC_DRAW); glEnableVertexAttribArray(BONE_ID_LOCATION); glVertexAttribIPointer(BONE_ID_LOCATION, 4, GL_INT, sizeof(VertexBoneData), (const GLvoid*)0); glEnableVertexAttribArray(BONE_WEIGHT_LOCATION); glVertexAttribPointer(BONE_WEIGHT_LOCATION, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBoneData), (const GLvoid*)16);

VertexBoneData is a struct:

Code :struct VertexBoneData { uint IDs[NUM_BONES_PER_VEREX]; float Weights[NUM_BONES_PER_VEREX]; }

and Bones is a vector of VertexBoneData, his shader looks like:

Code :#version 330 layout (location = 0) in vec3 Position; layout (location = 1) in vec2 TexCoord; layout (location = 2) in vec3 Normal; layout (location = 3) in ivec4 BoneIDs; layout (location = 4) in vec4 Weights; out vec2 TexCoord0; out vec3 Normal0; out vec3 WorldPos0; const int MAX_BONES = 100; uniform mat4 gWVP; uniform mat4 gWorld; 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]; vec4 PosL = BoneTransform * vec4(Position, 1.0); gl_Position = gWVP * PosL; TexCoord0 = TexCoord; vec4 NormalL = BoneTransform * vec4(Normal, 0.0); Normal0 = (gWorld * NormalL).xyz; WorldPos0 = (gWorld * PosL).xyz; }

I believe my mesh ends up with 6 bones but I had 12 as the max size to be safe.

My idea to get around this is to pass two matrices and have the shader look like this:

Code :#version 330 layout (location = 0) in vec3 Position; layout (location = 1) in vec2 TexCoord; layout (location = 2) in vec3 Normal; layout (location = 3) in mat4 BoneIDs; layout (location = 4) in mat4 Weights; out vec2 TexCoord0; out vec3 Normal0; out vec3 WorldPos0; const int MAX_BONES = 100; uniform mat4 gWVP; uniform mat4 gWorld; uniform mat4 gBones[MAX_BONES]; void main() { ivec4 BoneIDvec1 = ivec4(BoneIDs[0][0], BoneIDs[0][1], BoneIDs[0][2], BoneIDs[0][3]); ivec4 BoneIDvec2 = ivec4(BoneIDs[0][0], BoneIDs[0][1], BoneIDs[0][2], BoneIDs[0][3]); ivec4 BoneIDvec3 = ivec4(BoneIDs[0][0], BoneIDs[0][1], BoneIDs[0][2], BoneIDs[0][3]); ivec4 BoneIDvec4 = ivec4(BoneIDs[0][0], BoneIDs[0][1], BoneIDs[0][2], BoneIDs[0][3]); mat4 BoneTransform = gBones[BoneIDvec1[0]] * Weights[0][0]; BoneTransform += gBones[BoneIDvec1[1]] * Weights[0][1]; BoneTransform += gBones[BoneIDvec1[2]] * Weights[0][2]; BoneTransform += gBones[BoneIDvec1[3]] * Weights[0][3]; BoneTransform += gBones[BoneIDvec2[0]] * Weights[1][0]; BoneTransform += gBones[BoneIDvec2[1]] * Weights[1][1]; BoneTransform += gBones[BoneIDvec2[2]] * Weights[1][2]; BoneTransform += gBones[BoneIDvec2[3]] * Weights[1][3]; BoneTransform += gBones[BoneIDvec3[0]] * Weights[2][0]; BoneTransform += gBones[BoneIDvec3[1]] * Weights[2][1]; BoneTransform += gBones[BoneIDvec3[2]] * Weights[2][2]; BoneTransform += gBones[BoneIDvec3[3]] * Weights[2][3]; vec4 PosL = BoneTransform * vec4(Position, 1.0); gl_Position = gWVP * PosL; TexCoord0 = TexCoord; vec4 NormalL = BoneTransform * vec4(Normal, 0.0); Normal0 = (gWorld * NormalL).xyz; WorldPos0 = (gWorld * PosL).xyz; }

Would this work in theory? It seems like a lot of work, as I would need I think, to enter in all of his vertex data into two 4v4 matrices, and even then that's a maximum of 16 slots.

Thoughts?