I was trying to add some basic lighting effects to an animating cube but for some reason it just displays a blank colored window. I'm totally lost in finding the problem. The code was working fine before adding the lighting. The first thing that I did to find the problem is to add the
gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
to the end of fragment shader in order to avoid all the lighting calculations that might go wrong. But it just changed the color shown in the window. I'm not sure if this problem is because of camera settings or calculating normals or maybe other factors. Here is the obj file data that I'm using to load the cube:
v -1.0 -1.0 1.0
v 1.0 -1.0 1.0
v 1.0 1.0 1.0
v -1.0 1.0 1.0
v -1.0 -1.0 -1.0
v 1.0 -1.0 -1.0
v 1.0 1.0 -1.0
v -1.0 1.0 -1.0
vn 0.577350 0.577350 -0.577350
vn 0.577350 -0.577350 -0.577350
vn -0.577350 -0.577350 -0.577350
vn -0.577350 0.577350 -0.577350
vn 0.577350 0.577350 0.577350
vn 0.577350 -0.577350 0.577350
vn -0.577350 -0.577350 0.577350
vn -0.577350 0.577350 0.577350
f 0 1 2
f 2 3 0
f 1 5 6
f 6 2 1
f 7 6 5
f 5 4 7
f 4 0 3
f 3 7 4
f 4 5 1
f 1 0 4
f 3 2 6
f 6 7 3
This is the camera setting and matrix calculations:
float move = -4.0f;// sinf(SDL_GetTicks() / 1000.0 * (2 * 3.14) / 5); // -1<->+1 every 5 seconds
float angle = 0.0;// SDL_GetTicks() / 1000.0 * 45; // 45° per second
glm::vec3 axis_y(0, 1, 0);
glm::mat4 translation = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, move));
glm::mat4 rotation = glm::rotate(glm::mat4(1.0f), glm::radians(angle), axis_y);
glm::mat4 scaling = glm::scale(glm::mat4(1.0f), glm::vec3(1.0f, 1.0f, 1.0f));
glm::mat4 model = translation * rotation * scaling;
glm::mat4 view = glm::lookAt(glm::vec3(0.0, 2.0, 0.0), glm::vec3(0.0, 0.0, -4.0), glm::vec3(0.0, 1.0, 0.0));
glm::mat4 projection = glm::perspective(45.0f, 1.0f*screen_width / screen_height, 0.1f, 10.0f);
glm::mat4 mvp = projection * view * model;
glm::mat4 mv = view * model;
glm::mat4 normalMatrix = glm::transpose(glm::inverse(mv));
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(mv));
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(normalMatrix));
and the vertex shader includes:
gl_Position = mvp * vec4(positions, fade);
I have defined the lighting properties as follows:
float shininess = 5.0f;
glm::vec3 lightDirection = glm::vec3(0.0f, 1.0f, 2.0f);
glm::vec4 lightAmbient = glm::vec4(1, 0.83, 0.75, 1.0f);
glm::vec4 lightDiffuse = glm::vec4(1.0f, 1.0f, 0.4f, 1.0f);
glm::vec4 lightSpecular = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
glm::vec4 materialAmbient = glm::vec4(1, 0.83, 0.75, 1.0f);
glm::vec4 materialDiffuse = glm::vec4(1.0f, 1.0f, 0.4f, 1.0f);
glm::vec4 materialSpecular = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
glUniform1f(uniform_shininess, shininess);
glUniform3fv(uniform_lightDirection, 1, glm::value_ptr(lightDirection));
glUniform4fv(uniform_lightAmbient, 1, glm::value_ptr(lightAmbient));
glUniform4fv(uniform_lightDiffuse, 1, glm::value_ptr(lightDiffuse));
glUniform4fv(uniform_lightSpecular, 1, glm::value_ptr(lightSpecular));
glUniform4fv(uniform_materialAmbient, 1, glm::value_ptr(materialAmbient));
glUniform4fv(uniform_materialDiffuse, 1, glm::value_ptr(materialDiffuse));
glUniform4fv(uniform_materialSpecular, 1, glm::value_ptr(materialSpecular));
and fragment shader is:
uniform float shininess;
uniform vec3 lightDirection;
uniform vec4 lightAmbient;
uniform vec4 lightDiffuse;
uniform vec4 lightSpecular;
uniform vec4 materialAmbient;
uniform vec4 materialDiffuse;
uniform vec4 materialSpecular;
varying vec3 vNormal;
varying vec3 vEyeVec;
void main(void){
vec4 Ia = lightAmbient * materialAmbient;
vec4 Id = vec4(0.0,0.0,0.0,1.0);
vec4 Is = vec4(0.0,0.0,0.0,1.0);
vec3 L = normalize(lightDirection);
vec3 N = normalize(vNormal);
float lambertTerm = dot(N,-L);
if(lambertTerm > 0.0){
Id = lightDiffuse * materialDiffuse * lambertTerm;
vec3 E = normalize(vEyeVec);
vec3 R = reflect(L, N);
float specular = pow( max(dot(R, E), 0.0), shininess);
Is = lightSpecular * materialSpecular * specular;
}
vec4 finalColor = Ia + Id + Is;
finalColor.a = 1.0;
gl_FragColor = finalColor;
//gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
}
The two varyings are coming from vertex shader:
vNormal = vec3(normalMatrix * vec4(normals, 1.0));
vec4 vertex = mv * vec4(positions, 1.0);
vEyeVec = -vec3(vertex.xyz);
What I was guessing is that if the normals and lighting calculations go wrong then the last line in the fragment shader gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); should cancel them. However, that didn't make any help. I tried different camera positions but that didn't make any difference.