Jump to content

  • Log In with Google      Sign In   
  • Create Account


marx_86

Member Since 02 Apr 2012
Offline Last Active Apr 02 2012 12:49 PM
-----

Topics I've Started

Nightmare with tangent space and tbnMatrix

02 April 2012 - 03:18 AM

Hello everybody,
I have a huge problem that I can't fix alone.
I've tested a normal mapping shader with shader designer and here is everything working.
But I have problems when I try to supply the T and B vectors to my shader. I don't even know if the calculation of my T and B vector is correct.

Here's the code.

the render function for every model

void objModel::draw(float cp[3]){
if(NormalMapping()||BlinnPhong()){
glUseProgram(buf->program.progName);
}

else
glUseProgramObjectARB(0);

glBindBuffer(GL_ARRAY_BUFFER,getVertexBuffer());
glVertexPointer(3,GL_FLOAT,sizeof(Vertex),(void*)0);
glEnableClientState(GL_VERTEX_ARRAY);
if(applyNormalToObj()){//normal mapping shader
glBindBuffer(GL_ARRAY_BUFFER,getNormalBuffer());
glNormalPointer(GL_FLOAT,sizeof(Vertex),(void*)0);
glEnableClientState(GL_NORMAL_ARRAY);
}
if(NormalMapping()){
glEnableVertexAttribArrayARB(getTangentBuffer());  
glEnableVertexAttribArrayARB(getBinormalBuffer());
glVertexAttribPointerARB(getTangentBuffer(),3,GL_FLOAT,0,0,&par.Tangent[0]);
		glVertexAttribPointerARB(getBinormalBuffer(),3,GL_FLOAT,0,0,&par.Binormal[0]);
glUniform1i(buf->uniforms.textures[0],0);

glUniform1i(buf->uniforms.textures[1],1);//i don't use this in the shader

glUniform1i(buf->uniforms.textures[2],2);//I don't use this in the shader
glUniform1i(buf->uniforms.textures[3],3);
glUniform1f(buf->uniforms.mat.shininess,kShi);
glUniform4fv(buf->uniforms.mat.diffuse,1,kDiff);

}
//this works well
if(BlinnPhong()){

glUniform4fv(buf->uniforms.mat.ambient,1,kAmb);
glUniform4fv(buf->uniforms.mat.diffuse,1,kDiff);
glUniform4fv(buf->uniforms.mat.specular,1,kSpec);
glUniform1f(buf->uniforms.mat.shininess,kShi);
glUniform3fv(buf->uniforms.campos,1,cp);
}

if(applyTextureToObj()){//se devo applicare le texture al modello...
//diffuse texture
glActiveTexture(GL_TEXTURE0);

glBindTexture ( GL_TEXTURE_2D, getTextureNameDiffuse() );


glBindBuffer(GL_ARRAY_BUFFER,getTextureBuffer());

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
if(apply3CoordTexture())
glTexCoordPointer(3,GL_FLOAT,sizeof(Texel),(void*)0);
else
glTexCoordPointer(2,GL_FLOAT,sizeof(GLfloat)*2,(void*)0);//sizeof(Texeluv)

//_________________________________________________________________________________


//specular texture
glActiveTexture(GL_TEXTURE1);
glBindTexture ( GL_TEXTURE_2D, getTextureNameSpecular() );
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glBindBuffer(GL_ARRAY_BUFFER,getTextureBuffer());

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if(apply3CoordTexture())
glTexCoordPointer(3,GL_FLOAT,sizeof(Texel),(void*)0);
else
glTexCoordPointer(2,GL_FLOAT,sizeof(GLfloat)*2,(void*)0);//sizeof(Texeluv)
//__________________________________________________________________________
//gloss or normal texture
glEnable(GL_TEXTURE_2D);
glBindTexture ( GL_TEXTURE_2D, getTextureNameGloss( ));
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);

glBindBuffer(GL_ARRAY_BUFFER,getTextureBuffer());

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if(apply3CoordTexture())
glTexCoordPointer(3,GL_FLOAT,sizeof(Texel),(void*)0);
else
glTexCoordPointer(2,GL_FLOAT,sizeof(GLfloat)*2,(void*)0);//sizeof(Texeluv)

if(NormalMapping()){
//__________________________________________________________________________
//normal map texture
glEnable(GL_TEXTURE_2D);
glBindTexture ( GL_TEXTURE_2D, getTextureNameNormal( ));
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);

glBindBuffer(GL_ARRAY_BUFFER,getTextureBuffer());

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if(apply3CoordTexture())
glTexCoordPointer(3,GL_FLOAT,sizeof(Texel),(void*)0);
else
glTexCoordPointer(2,GL_FLOAT,sizeof(GLfloat)*2,(void*)0);//sizeof(Texeluv)
}


}

if(getCullBack()){
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
if(getCullFront()){
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,getTIndeces());
glDrawElements(GL_TRIANGLES,getTIndecesSize(),GL_UNSIGNED_INT,(void*)0);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,getQIndeces());
//glDrawElements(GL_QUADS,getQIndecesSize(),GL_UNSIGNED_INT,(void*)0);

if(NormalMapping()){
glDisableVertexAttribArrayARB(getTangentBuffer());
		glDisableVertexAttribArrayARB(getBinormalBuffer());
}

if(getCullBack()|| getCullFront())
glDisable(GL_CULL_FACE);
if(applyNormalToObj())
glDisableClientState(GL_NORMAL_ARRAY);
if(applyTextureToObj()){
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//glDisable(GL_TEXTURE_2D);
}
glDisableClientState(GL_VERTEX_ARRAY);
}



here I have the setup of the normal map shader

if(par.NormalMapping()){
createNormalMappingVShader1(nmvs);//these are two funcions that create the text files with the shader source code
createNormalMappingFShader1(nmfs);
cout << " normal mapping shader creati " << endl;

buffer->vertex_shader = make_shader(GL_VERTEX_SHADER,nmvs.c_str());
if (buffer->vertex_shader == 0)
return 0;
buffer->fragment_shader = make_shader(GL_FRAGMENT_SHADER,nmfs.c_str());
if (buffer->fragment_shader == 0)
return 0;
buffer->program.progName = make_program(buffer->vertex_shader, buffer->fragment_shader);
if (buffer->program.progName == 0)
return 0;
buffer->uniforms.textures[0]=glGetUniformLocation(buffer->program.progName,"base");
buffer->uniforms.textures[1]=glGetUniformLocation(buffer->program.progName,"specularTexture");
buffer->uniforms.textures[2]=glGetUniformLocation(buffer->program.progName,"glossTexture");
buffer->uniforms.textures[3]=glGetUniformLocation(buffer->program.progName,"normalMap");

buffer->uniforms.mat.diffuse=glGetUniformLocation(buffer->program.progName,"kdiff");
buffer->uniforms.mat.shininess=glGetUniformLocation(buffer->program.progName,"kshi");
buffer->attributes.tangent=glGetAttribLocation(buffer->program.progName, "tangent");
glBindAttribLocation(buffer->program.progName,buffer->attributes.tangent,"tangent");
buffer->attributes.binormal=glGetAttribLocation(buffer->program.progName, "binormal");
glBindAttribLocation(buffer->program.progName,buffer->attributes.binormal,"binormal");


tangent space calculation



std::vector <int> nTimes;
if(NormalMapping()){





//init tantent
Vertex zero;
zero.x=zero.y=zero.z=0.0;

for(int a=0;a<NewVertex.size();a++) {
Tangent.push_back(zero);
Binormal.push_back(zero);
nTimes.push_back(0);
}


for(int a=0;a<triangle_elements.size();a++){

if((a%3)==0){


int i1,i2,i3;
i1=triangle_elements.at(a);
i2=triangle_elements.at(a+1);
i3=triangle_elements.at(a+2);

Vertex v1,v2,v3;
Texeluv t1,t2,t3;


v1.x=NewVertex[i1].x;
v1.y=NewVertex[i1].y;
v1.z=NewVertex[i1].z;
t1.u=NewTexeluv[i1].u;
t1.v=NewTexeluv[i1].v;

v2.x=NewVertex[i2].x;
v2.y=NewVertex[i2].y;
v2.z=NewVertex[i2].z;
t2.u=NewTexeluv[i2].u;
t2.v=NewTexeluv[i2].v;

v3.x=NewVertex[i3].x;
v3.y=NewVertex[i3].y;
v3.z=NewVertex[i3].z;
t3.u=NewTexeluv[i3].u;
t3.v=NewTexeluv[i3].v;


Tangent.at(i1)=somma(Tangent.at(i1),(generateTangent(v1,v2,v3,t1,t2,t3)));
Tangent.at(i2)=somma(Tangent.at(i2),(generateTangent(v1,v2,v3,t1,t2,t3)));
Tangent.at(i3)=somma(Tangent.at(i3),(generateTangent(v1,v2,v3,t1,t2,t3)));
Binormal.at(i1)=somma(Binormal.at(i1),(generateBinormal(v1,v2,v3,t1,t2,t3)));
Binormal.at(i2)=somma(Binormal.at(i2),(generateBinormal(v1,v2,v3,t1,t2,t3)));
Binormal.at(i3)=somma(Binormal.at(i3),(generateBinormal(v1,v2,v3,t1,t2,t3)));


nTimes.at(i1)++;
nTimes.at(i2)++;
nTimes.at(i3)++;







}



}



}

if(NormalMapping()){
for(int v=0;v<NewVertex.size();v++){
if(nTimes.at(v)!=0){
Tangent.at(v).x=Tangent.at(v).x/nTimes.at(v);
Tangent.at(v).y=Tangent.at(v).y/nTimes.at(v);
Tangent.at(v).z=Tangent.at(v).z/nTimes.at(v);
Binormal.at(v).x=Binormal.at(v).x/nTimes.at(v);
Binormal.at(v).y=Binormal.at(v).y/nTimes.at(v);
Binormal.at(v).z=Binormal.at(v).z/nTimes.at(v);

}

}

}


if(NormalMapping()){


for(int v=0;v<NewVertex.size();v++){
// Gram-Schmidt orthogonalize

Tangent.at(v).x=Tangent.at(v).x- NewNormal.at(v).x*(NewNormal.at(v).x*Tangent.at(v).x+NewNormal.at(v).y*Tangent.at(v).y+NewNormal.at(v).z*Tangent.at(v).z);
Tangent.at(v).y=Tangent.at(v).y- NewNormal.at(v).y*(NewNormal.at(v).x*Tangent.at(v).x+NewNormal.at(v).y*Tangent.at(v).y+NewNormal.at(v).z*Tangent.at(v).z);
Tangent.at(v).z=Tangent.at(v).z- NewNormal.at(v).z*(NewNormal.at(v).x*Tangent.at(v).x+NewNormal.at(v).y*Tangent.at(v).y+NewNormal.at(v).z*Tangent.at(v).z);

Tangent.at(v)=normalize(Tangent.at(v));

if((Tangent.at(v).x*Tangent.at(v).x)!=0)
Binormal.at(v).x=Binormal.at(v).x- NewNormal.at(v).x*(NewNormal.at(v).x*Binormal.at(v).x+NewNormal.at(v).y*Binormal.at(v).y+NewNormal.at(v).z*Binormal.at(v).z)-((Tangent.at(v).x*Binormal.at(v).x+Tangent.at(v).y*Binormal.at(v).y+Tangent.at(v).z*Binormal.at(v).z)*Tangent.at(v).x)/(Tangent.at(v).x*Tangent.at(v).x);
else
Binormal.at(v).x=Binormal.at(v).x- NewNormal.at(v).x*(NewNormal.at(v).x*Binormal.at(v).x+NewNormal.at(v).y*Binormal.at(v).y+NewNormal.at(v).z*Binormal.at(v).z)-((Tangent.at(v).x*Binormal.at(v).x+Tangent.at(v).y*Binormal.at(v).y+Tangent.at(v).z*Binormal.at(v).z)*Tangent.at(v).x);

if((Tangent.at(v).y*Tangent.at(v).y)!=0)
Binormal.at(v).y=Binormal.at(v).y- NewNormal.at(v).y*(NewNormal.at(v).x*Binormal.at(v).x+NewNormal.at(v).y*Binormal.at(v).y+NewNormal.at(v).z*Binormal.at(v).z)-((Tangent.at(v).x*Binormal.at(v).x+Tangent.at(v).y*Binormal.at(v).y+Tangent.at(v).z*Binormal.at(v).z)*Tangent.at(v).y)/(Tangent.at(v).y*Tangent.at(v).y);
else
Binormal.at(v).y=Binormal.at(v).y- NewNormal.at(v).y*(NewNormal.at(v).x*Binormal.at(v).x+NewNormal.at(v).y*Binormal.at(v).y+NewNormal.at(v).z*Binormal.at(v).z)-((Tangent.at(v).x*Binormal.at(v).x+Tangent.at(v).y*Binormal.at(v).y+Tangent.at(v).z*Binormal.at(v).z)*Tangent.at(v).y);
if((Binormal.at(v).z*Binormal.at(v).z)!=0)
Binormal.at(v).z=Binormal.at(v).z- NewNormal.at(v).z*(NewNormal.at(v).x*Binormal.at(v).x+NewNormal.at(v).y*Binormal.at(v).y+NewNormal.at(v).z*Binormal.at(v).z)-((Tangent.at(v).x*Binormal.at(v).x+Tangent.at(v).y*Binormal.at(v).y+Tangent.at(v).z*Binormal.at(v).z)*Tangent.at(v).z)/(Tangent.at(v).z*Tangent.at(v).z);
else
Binormal.at(v).z=Binormal.at(v).z- NewNormal.at(v).z*(NewNormal.at(v).x*Binormal.at(v).x+NewNormal.at(v).y*Binormal.at(v).y+NewNormal.at(v).z*Binormal.at(v).z)-((Tangent.at(v).x*Binormal.at(v).x+Tangent.at(v).y*Binormal.at(v).y+Tangent.at(v).z*Binormal.at(v).z)*Tangent.at(v).z);

Binormal.at(v)=normalize(Binormal.at(v));
}

}





Vertex  parser::generateTangent(Vertex v1, Vertex v2, Vertex v3, Texeluv tex1, Texeluv tex2,Texeluv tex3)
{
Vertex Q1,Q2;
Q1.x=v2.x-v1.x;
Q1.y=v2.y-v1.y;
Q1.z=v2.z-v1.z;
Q2.x=v3.x-v1.x;
Q2.y=v3.y-v1.y;
Q2.z=v3.z-v1.z;
float u1=tex2.u-tex1.u;
float vi1=tex2.v-tex1.v;
float u2=tex3.u-tex1.u;
float vi2=tex3.v-tex1.v;


float coef = 0.0f;
if(fabsf(u1* vi2 - u2 * vi1)<= 0.0001f)
coef=1.0;
else
coef = 1/ (u1* vi2 - u2 * vi1);

Vertex tangent;

tangent.x=coef*(vi2*Q1.x-vi1*Q2.x);
tangent.y=coef*(vi2*Q1.y-vi1*Q1.y);
tangent.z=coef*(vi2+Q1.x-vi1*Q1.z);



return normalize(tangent);


}


Vertex  parser::generateBinormal(Vertex v1, Vertex v2, Vertex v3, Texeluv tex1, Texeluv tex2,Texeluv tex3)
{
Vertex Q1,Q2;
Q1.x=v2.x-v1.x;
Q1.y=v2.y-v1.y;
Q1.z=v2.z-v1.z;
Q2.x=v3.x-v1.x;
Q2.y=v3.y-v1.y;
Q2.z=v3.z-v1.z;
float u1=tex2.u-tex1.u;
float vi1=tex2.v-tex1.v;
float u2=tex3.u-tex1.u;
float vi2=tex3.v-tex1.v;
float coef;

if(fabsf(u1* vi2 - u2 * vi1)<= 0.0001f)
coef=1.0;
else
coef = 1/ (u1* vi2 - u2 * vi1);

Vertex binormal;


binormal.x=coef*(-u2*Q1.x-u1*Q2.x);
binormal.y=coef*(-u2*Q1.y-u1*Q1.y);
binormal.z=coef*(-u2+Q1.x-u1*Q1.z);




return normalize(binormal);

}

that's should be everything... thanks

PARTNERS