Jump to content
  • Advertisement
Sign in to follow this  
rgibson11

OpenGL cal3d glsl code

This topic is 2514 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am have been implementing GPU skinning using some sample code from the official cal3d opengl vp example which uses assembly glsl and translated code from here http://nopaste.info/1ed83dfd4f.html

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?

Share this post


Link to post
Share on other sites
Advertisement
hi!

were you able to solve it? i get monster hands when i set the max_bones to too low.

i'm getting a different problem. in my case the textures are just not showing up, though the animation is working fine.
any ideas?

Share this post


Link to post
Share on other sites
hi!

are you using the assembly shader or the GLSL shader? is your model appearing textured? if so, could you please share your code with me?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!