Original Post
Hi, Sorry in advance as I feel like this is kind of a 'Here's the code, tell me what's wrong' post. I did read the guidelines [smile] but I am really lost here. I am learning GLSL and going through the orange book, I'm currently recreating the standard pipeline from their examples. But I have a very strange problem with a uniform int, I'm using one to pass in how many lights there are in the scene (there are two). If I write: then I get my two lights and everything is great. However if I write: then only the first light has any effect. I have put in checks to change the colour if u_num_lights isn't equal to 2 and even put a counter to make sure the loop is going round twice! As far as I can make out it is. I am really at a loss, I feel like either I have done something really stupid or there is something very weird going on. If anyone could simply confirm or deny whether they see the same problem when running the code I would really appreciate it. If anyone has any solutions then even better! Cheers The relevant code follows: main.cpp: standard.frag: standard.vert: I have put the whole lot in a zip file, if you want to try and run it.
for (int i ; i < 2 ; i++) {...}
for (int i ; i < u_num_lights ; i++) {...}
...
int current_light = 0;
int num_lights = 2;
float light_pos[2][4] = {{0,-1,1,1},{1,0.5,-3,1}};
float light_dir[2][3] = {{0,0,-1,},{0,0,1}};
...
void light() {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
//light no 1
glLightfv(GL_LIGHT0, GL_SPECULAR, blue);
glLightfv(GL_LIGHT0, GL_DIFFUSE, red);
glLightfv(GL_LIGHT0, GL_AMBIENT, black);
glLightfv(GL_LIGHT0, GL_POSITION, light_pos[0]);
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.f);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light_dir[0]);
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 15.0f);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.1f);
//light no 2
glLightfv(GL_LIGHT1, GL_SPECULAR, cyan);
glLightfv(GL_LIGHT1, GL_DIFFUSE, turquoise);
glLightfv(GL_LIGHT1, GL_AMBIENT, black);
glLightfv(GL_LIGHT1, GL_POSITION, light_pos[1]);
glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 180.f);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, light_dir[1]);
glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 15.0f);
glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f);
glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f);
glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.1f);
glPopMatrix();
}
...
void register_uniforms(int shader_index) {
int prog = shader_program_ids[shader_index];
cout << "prog was " << prog << endl;
int loc;
switch (shader_index) {
case 0:
loc = glGetUniformLocation(prog, "u_num_lights");
glUniform1i(loc, num_lights);
break;
}
cout << "loc was " << loc << endl;
GLenum error = glGetError();
if (error != GL_NO_ERROR)
cout << "ERROR!! : " << gluErrorString(error) << endl;
}
...
void main(void) {
gl_FragColor = gl_Color;
}
uniform int u_num_lights;
...
void main (void) {
...
int c = 0;
for (int i = 0; i < u_num_lights; i++) { /*!!!! try changing 'u_num_lights' to '2' to see the difference !!!!!!*/
if (gl_LightSource.position.w == 0.0)
directional_light (i, normal, ambient, diffuse, specular);
else if (gl_LightSource.spotCutoff == 180.0)
point_light (i, to_eye, ec_position_3, normal, ambient, diffuse, specular);
else
spot_light (i, to_eye, ec_position_3, normal, ambient, diffuse, specular);
c++;
}
vec4 colour = gl_FrontLightModelProduct.sceneColor +
ambient * gl_FrontMaterial.ambient +
diffuse * gl_FrontMaterial.diffuse +
specular * gl_FrontMaterial.specular;
if (u_num_lights != 2) colour = vec4(0.0,0.0,1.0,1.0);
if (c != 2) colour = vec4(1.0,0.0,0.0,0.0);
gl_FrontColor = colour;
}