Ok, it used to be a simple bump mapping technique. At least in theory.
First, we go with the tangents. They seem to be right as you can see below:
Second, we pass them and set the textures uniforms:
shader->useProgram(BUMP);
GLuint tangentLoc= glGetAttribLocation (shader->handle_shader_programs[BUMP], "tangent");
glEnableVertexAttribArray (tangentLoc);
glVertexAttribPointer(tangentLoc, 3, GL_FLOAT, GL_FALSE, 0, tangent_array);
GLuint loc= glGetUniformLocationARB(shader->handle_shader_programs[BUMP],"diffuse_map");
glUniform1iARB( loc ,0);
loc= glGetUniformLocationARB(shader->handle_shader_programs[BUMP],"normal_map");
glUniform1iARB(loc,1);
I am not posting the render code here, but I am sure both of the textures are being send to the shader with:
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glActiveTexture(GL_TEXTURE0);
Texture::useTexture(current_mesh->diffuse_map);
glActiveTexture(GL_TEXTURE1);
Texture::useTexture(current_mesh->normal_map);
Third, we remember to unload the program and the attribute:
glDisableVertexAttribArray (tangentLoc);
shader->stopProgram(BUMP);
Forth, we use everything in the shader:
vertex:
varying vec3 eyeVec;
varying vec3 halfVec;
varying vec3 lightVec;
attribute vec3 tangent;
void main()
{
gl_Position = ftransform();
vec3 n = normalize (gl_NormalMatrix * gl_Normal);
vec3 t = normalize (gl_NormalMatrix * tangent);
vec3 b = cross (n, t);
// output texture coordinates for decal and normal maps
//gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_TexCoord[0] = gl_MultiTexCoord0;
// transform light and half angle vectors by tangent basis
vec3 v;
v.x = dot (vec3 (gl_LightSource[1].position), t);
v.y = dot (vec3 (gl_LightSource[1].position), b);
v.z = dot (vec3 (gl_LightSource[1].position), n);
lightVec = normalize (v);
v.x = dot (vec3 (gl_LightSource[1].halfVector), t);
v.y = dot (vec3 (gl_LightSource[1].halfVector), b);
v.z = dot (vec3 (gl_LightSource[1].halfVector), n);
halfVec = normalize (v);
eyeVec = vec3 (gl_ModelViewMatrix * gl_Vertex);
v.x = dot (eyeVec, t);
v.y = dot (eyeVec, b);
v.z = dot (eyeVec, n);
eyeVec = normalize (v);
}
fragment:
varying vec3 lightVec;
varying vec3 halfVec;
varying vec3 eyeVec;
void main (void)
{ vec3 normal = 2.0 * texture2D (normal_map, gl_TexCoord[0].st).rgb - 1.0;
normal = normalize (normal);
float lamberFactor= max(dot(lightVec,normal),0.0);
vec4 diffuseMaterial= vec4(0.0);
vec4 diffuseLight= vec4(0.0);
vec4 specularMaterial;
vec4 specularLight ;
float shininess ;
// compute ambient
vec4 ambientLight = gl_LightSource[1].ambient;
if (lamberFactor > 0.0)
{
diffuseMaterial = texture2D (diffuse_map, gl_TexCoord[0].st);
diffuseLight = gl_LightSource[1].diffuse;
// In doom3, specular value comes from a texture
specularMaterial = vec4(1.0) ;
specularLight = gl_LightSource[1].specular;
shininess = pow (max (dot (halfVec, normal), 0.0), 2.0) ;
gl_FragColor = diffuseMaterial * diffuseLight * lamberFactor ;
gl_FragColor += specularMaterial * specularLight * shininess ;
}
gl_FragColor += ambientLight;
}
And after all this I end up with a uglier version of bumpMapping:
I am a C/C++ guy and I am having difficulties with debugging things in GLSL. I know there are frameworks for that, but the problem is when I connect GLSL and C++. There is no printf() ways in GLSL that I know of. I was trying to use the gl_FragColor to print the information on the screen to double check if everything was passed ok, but I end up with another problem, if I did not use all my variables the programs starts to crash o_O.
I would really appreciate any tips on debugging a shader together with a C++ program or/and any idea of what could be going wrong with this bump mapping.