When the character is standing still it renders fine but when I play an animation you can see some resemblance to the animation but its distorted and the character has monster hands (errors)
I am starting to think that the translated shader code is wrong
Setting buffers code:
void Model::FillHardwareBuffer(){ float *pVertexBuffer = (float*)malloc(30000*3*sizeof(float)); float *pWeightBuffer = (float*)malloc(30000*4*sizeof(float)); float *pMatrixIndexBuffer = (float*)malloc(30000*4*sizeof(float)); float *pNormalBuffer = (float*)malloc(30000*3*sizeof(float)); float *pTexCoordBuffer = (float*)malloc(30000*2*sizeof(float)); CalIndex *pIndexBuffer = (CalIndex*)malloc(50000*3*sizeof(CalIndex)); if(pVertexBuffer==NULL || pWeightBuffer == NULL || pMatrixIndexBuffer==NULL || pNormalBuffer == NULL || pTexCoordBuffer==NULL || pIndexBuffer == NULL) { Error(__FILE__, __LINE__); } m_calHardwareModel = std::shared_ptr<CalHardwareModel>(new CalHardwareModel(m_calCoreModel.get())); m_calHardwareModel->setVertexBuffer((char*)pVertexBuffer,3*sizeof(float)); m_calHardwareModel->setNormalBuffer((char*)pNormalBuffer,3*sizeof(float)); m_calHardwareModel->setWeightBuffer((char*)pWeightBuffer,4*sizeof(float)); m_calHardwareModel->setMatrixIndexBuffer((char*)pMatrixIndexBuffer,4*sizeof(float)); m_calHardwareModel->setTextureCoordNum(1); m_calHardwareModel->setTextureCoordBuffer(0,(char*)pTexCoordBuffer,2*sizeof(float)); m_calHardwareModel->setIndexBuffer(pIndexBuffer); m_calHardwareModel->load( 0, 0, 29); // the index index in pIndexBuffer are relative to the begining of the hardware mesh, // we make them relative to the begining of the buffer. int meshId; for(meshId = 0; meshId < m_calHardwareModel->getHardwareMeshCount(); meshId++) { m_calHardwareModel->selectHardwareMesh(meshId); int faceId; for(faceId = 0; faceId < m_calHardwareModel->getFaceCount(); faceId++) { pIndexBuffer[faceId*3+ m_calHardwareModel->getStartIndex()]+=m_calHardwareModel->getBaseVertexIndex(); pIndexBuffer[faceId*3+1+ m_calHardwareModel->getStartIndex()]+=m_calHardwareModel->getBaseVertexIndex(); pIndexBuffer[faceId*3+2+ m_calHardwareModel->getStartIndex()]+=m_calHardwareModel->getBaseVertexIndex(); } } // We use ARB_vertex_buffer_object extension, // it provide better performance glGenBuffers(6, m_bufferObject); glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[0]); glBufferData(GL_ARRAY_BUFFER, m_calHardwareModel->getTotalVertexCount()*3*sizeof(float),(const void*)pVertexBuffer, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[1]); glBufferData(GL_ARRAY_BUFFER, m_calHardwareModel->getTotalVertexCount()*4*sizeof(float),(const void*)pWeightBuffer, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[2]); glBufferData(GL_ARRAY_BUFFER, m_calHardwareModel->getTotalVertexCount()*3*sizeof(float),(const void*)pNormalBuffer, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[3]); glBufferData(GL_ARRAY_BUFFER, m_calHardwareModel->getTotalVertexCount()*4*sizeof(float),(const void*)pMatrixIndexBuffer, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[4]); glBufferData(GL_ARRAY_BUFFER, m_calHardwareModel->getTotalVertexCount()*2*sizeof(float),(const void*)pTexCoordBuffer, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufferObject[5]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_calHardwareModel->getTotalFaceCount()*3*sizeof(CalIndex),(const void*)pIndexBuffer, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0); free(pVertexBuffer); free(pWeightBuffer); free(pNormalBuffer); free(pMatrixIndexBuffer); free(pIndexBuffer);}
Rendering code
void Model::onRenderHardware(){ glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); int ww = glGetAttribLocation(GLR.GetMainShader().GetProgramObject(), "weight"); //Comes out to what I set it. int ii = glGetAttribLocation(GLR.GetMainShader().GetProgramObject(), "index"); //Comes out to what I set it. glEnableVertexAttribArray(ww); glEnableVertexAttribArray(ii); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bufferObject[5]); //Index buffer glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[0]); //Vertex buffer glVertexPointer(3, GL_FLOAT, 0, 0); //glVertexAttribPointer(0, 3 , GL_FLOAT, false, 0, NULL); glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[1]); glVertexAttribPointer(ww, 4 , GL_FLOAT, false, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[2]); glNormalPointer(GL_FLOAT, 0, 0); //glVertexAttribPointer(2, 3 , GL_FLOAT, false, 0, NULL); glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[3]); glVertexAttribPointer(ii, 4 , GL_FLOAT, false, 0, 0); glBindBuffer(GL_ARRAY_BUFFER, m_bufferObject[4]); glTexCoordPointer(2, GL_FLOAT, 0, 0); //glVertexAttribPointer(8, 2 , GL_FLOAT, false, 0, NULL); int hardwareMeshId; for(hardwareMeshId=0;hardwareMeshId<m_calHardwareModel->getHardwareMeshCount() ; hardwareMeshId++) { m_calHardwareModel->selectHardwareMesh(hardwareMeshId); unsigned char meshColor[4]; float materialColor[4]; // set the material ambient color m_calHardwareModel->getAmbientColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; glMaterialfv(GL_FRONT, GL_AMBIENT, materialColor); // set the material diffuse color m_calHardwareModel->getDiffuseColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; glMaterialfv(GL_FRONT, GL_DIFFUSE, materialColor); // set the material specular color m_calHardwareModel->getSpecularColor(&meshColor[0]); materialColor[0] = meshColor[0] / 255.0f; materialColor[1] = meshColor[1] / 255.0f; materialColor[2] = meshColor[2] / 255.0f; materialColor[3] = meshColor[3] / 255.0f; glMaterialfv(GL_FRONT, GL_SPECULAR, materialColor); // set the material shininess factor float shininess; shininess = 50.0f; //m_calHardwareModel->getShininess(); glMaterialfv(GL_FRONT, GL_SHININESS, &shininess); int boneId; for(boneId = 0; boneId < m_calHardwareModel->getBoneCount(); boneId++) { CalQuaternion rotationBoneSpace = m_calHardwareModel->getRotationBoneSpace(boneId, m_calModel->getSkeleton()); CalVector translationBoneSpace = m_calHardwareModel->getTranslationBoneSpace(boneId, m_calModel->getSkeleton()); CalMatrix rotationMatrix = rotationBoneSpace; float transformation[12]; transformation[0]=rotationMatrix.dxdx; transformation[1]=rotationMatrix.dxdy; transformation[2]=rotationMatrix.dxdz; transformation[3]=translationBoneSpace.x; transformation[4]=rotationMatrix.dydx; transformation[5]=rotationMatrix.dydy; transformation[6]=rotationMatrix.dydz; transformation[7]=translationBoneSpace.y; transformation[8]=rotationMatrix.dzdx; transformation[9]=rotationMatrix.dzdy; transformation[10]=rotationMatrix.dzdz; transformation[11]=translationBoneSpace.z; char buffer[18]; sprintf(buffer, "BoneMatrix[%i]", boneId*3); GLint MatrixLoc = glGetUniformLocation(GLR.GetMainShader().GetProgramObject(), buffer); glUniform4fv(MatrixLoc, 3, &transformation[0]); CTexture * ace = (CTexture *)m_calHardwareModel->getMapUserData(0); ace->Bind(0); } if(sizeof(CalIndex)==2) glDrawElements(GL_TRIANGLES, m_calHardwareModel->getFaceCount() * 3, GL_UNSIGNED_SHORT, (((CalIndex *)NULL)+ m_calHardwareModel->getStartIndex())); else glDrawElements(GL_TRIANGLES, m_calHardwareModel->getFaceCount() * 3, GL_UNSIGNED_INT, (((CalIndex *)NULL)+ m_calHardwareModel->getStartIndex())); } glDisableVertexAttribArray(ww); glDisableVertexAttribArray(ii); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glBindTexture(GL_TEXTURE_2D, 0);}
vert shader:
uniform mat4 World;uniform mat4 View;uniform mat4 Proj;attribute vec4 weight;attribute vec4 index;const int max_bones = 29;uniform vec4 BoneMatrix[max_bones*3];vec4 getVertex(){ vec4 R0, R1, R2, R3; int actIndex; vec3 pos = gl_Vertex.xyz; //v actIndex = int(index.w) * 3; R0.x = dot(pos.xyz, BoneMatrix[actIndex].xyz) + BoneMatrix[actIndex].w; //DPH R0.x, position.xyzz, matrix[A0.x]; R0.y = dot(pos.xyz, BoneMatrix[actIndex+1].xyz) + BoneMatrix[actIndex+1].w; //DPH R0.y, position.xyzz, matrix[A0.x + 1]; R0.z = dot(pos.xyz, BoneMatrix[actIndex+2].xyz) + BoneMatrix[actIndex+2].w; //DPH R0.z, position.xyzz, matrix[A0.x + 2]; actIndex = int(index.x) * 3; R1.x = dot(pos.xyz, BoneMatrix[actIndex].xyz) + BoneMatrix[actIndex].w; //DPH R1.y, position.xyzx, matrix[A0.x]; R1.y = dot(pos.xyz, BoneMatrix[actIndex+1].xyz) + BoneMatrix[actIndex+1].w; //DPH R1.z, position.xyzx, matrix[A0.x + 1]; R1.z = dot(pos.xyz, BoneMatrix[actIndex+2].xyz) + BoneMatrix[actIndex+2].w; //DPH R1.w, position.xyzx, matrix[A0.x + 2]; actIndex = int(index.y) * 3; R2.x = dot(pos.xyz, BoneMatrix[actIndex].xyz) + BoneMatrix[actIndex].w; //DPH R2.x, position.xyzx, matrix[A0.x]; R2.y = dot(pos.xyz, BoneMatrix[actIndex+1].xyz) + BoneMatrix[actIndex+1].w; //DPH R2.y, position.xyzx, matrix[A0.x + 1]; R2.z = dot(pos.xyz, BoneMatrix[actIndex+2].xyz) + BoneMatrix[actIndex+2].w; //DPH R2.z, position.xyzx, matrix[A0.x + 2]; actIndex = int(index.z) * 3; R3.x = dot(pos.xyz, BoneMatrix[actIndex].xyz) + BoneMatrix[actIndex].w; //DPH R3.x, position.xyzx, matrix[A0.x]; R3.y = dot(pos.xyz, BoneMatrix[actIndex+1].xyz) + BoneMatrix[actIndex+1].w; //DPH R3.y, position.xyzx, matrix[A0.x + 1]; R3.z = dot(pos.xyz, BoneMatrix[actIndex+2].xyz) + BoneMatrix[actIndex+2].w; //DPH R3.z, position.xyzx, matrix[A0.x + 2]; R0 *= weight.w; R1 *= weight.x; R2 *= weight.y; R3 *= weight.z; R0 = R0 + R1 + R2 + R3; R0.w = 1.0; return R0;}vec3 getNormal(void){ vec4 N0, N1, N2; vec3 normal; normal = gl_Normal; int actIndex; actIndex = int(index.x) * 3; N1.x = dot(normal.xyzx, BoneMatrix[actIndex].xyzx); //DPH R1.y, position.xyzx, matrix[A0.x]; N1.y = dot(normal.xyzx, BoneMatrix[actIndex+1].xyzx); //DPH R1.z, position.xyzx, matrix[A0.x + 1]; N1.z = dot(normal.xyzx, BoneMatrix[actIndex+2].xyzx); //DPH R1.w, position.xyzx, matrix[A0.x + 2]; actIndex = int(index.y) * 3; N2.x = dot(normal.xyzx, BoneMatrix[actIndex].xyzx); //DPH R2.x, position.xyzx, matrix[A0.x]; N2.y = dot(normal.xyzx, BoneMatrix[actIndex+1].xyzx); //DPH R2.y, position.xyzx, matrix[A0.x + 1]; N2.z = dot(normal.xyzx, BoneMatrix[actIndex+2].xyzx); //DPH R2.z, position.xyzx, matrix[A0.x + 2]; vec4 N3, N4; actIndex = int(index.z) * 3; N3.x = dot(normal.xyzx, BoneMatrix[actIndex].xyzx); //DPH R1.y, position.xyzx, matrix[A0.x]; N3.y = dot(normal.xyzx, BoneMatrix[actIndex+1].xyzx); //DPH R1.z, position.xyzx, matrix[A0.x + 1]; N3.z = dot(normal.xyzx, BoneMatrix[actIndex+2].xyzx); //DPH R1.w, position.xyzx, matrix[A0.x + 2]; actIndex = int(index.w) * 3; N4.x = dot(normal.xyzx, BoneMatrix[actIndex].xyzx); //DPH R2.x, position.xyzx, matrix[A0.x]; N4.y = dot(normal.xyzx, BoneMatrix[actIndex+1].xyzx); //DPH R2.y, position.xyzx, matrix[A0.x + 1]; N4.z = dot(normal.xyzx, BoneMatrix[actIndex+2].xyzx); N1 *= weight.x; N2 *= weight.y; N3 *= weight.z; N4 *= weight.w; //? N0 = N1 + N2 + N3 + N4; //N0 sollte die richtige normale sein return N0.xyz;}void main (void){ mat4 WVP = (Proj * View * World); mat4 WV = (View * World); mat4 W = World; vec4 avertex = getVertex(); gl_Position = WVP * avertex;}
Can someone please have a look?