I am trying to locate my light at position 0,0,0 but it always go bottom left of the box which has coords -20,-20,0 and I try to change light position to some arbitrary coordinates but it still stays at bottom left.
I provided a picture where camera positioned at 0,0,40:
void initLighting()
{
// Enable lighting
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
//glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHT0);
// Set lighting intensity and color
glLightfv(GL_LIGHT0, GL_AMBIENT, value_ptr(lights.at(0).ambient));
glLightfv(GL_LIGHT0, GL_DIFFUSE, value_ptr(lights.at(0).diffuse));
glLightfv(GL_LIGHT0, GL_SPECULAR, value_ptr(lights.at(0).specular));
glLightfv(GL_LIGHT0, GL_POSITION, value_ptr(vec4(lights.at(0).position, 1.0f)));
////////////////////////////////////////////////
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 15.0);// set cutoff angle
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, value_ptr(box.center));
glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 1); // set focusing strength
}
void display(void)
{
glMatrixMode(GL_MODELVIEW);
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT);
// clear the identity matrix.
glLoadIdentity();
glPushMatrix();
gluLookAt(camera.position.x, camera.position.y, camera.position.z, box.center.x, box.center.y, box.center.z,
camera.upVector.x, camera.upVector.y, camera.upVector.z);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, value_ptr(materials.at(box.material).ambient));
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, value_ptr(materials.at(box.material).diffuse));
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, value_ptr(materials.at(box.material).specular));
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, materials.at(box.material).exponent);
glBegin(GL_TRIANGLES);
for (int i = 0; i < box.indices.size(); i = i + 3)
{
glNormal3fv(value_ptr(box.vertices.at(box.indices.at(i)).Normal));
glVertex3f(box.vertices.at(box.indices.at(i)).Position.x, box.vertices.at(box.indices.at(i)).Position.y, box.vertices.at(box.indices.at(i)).Position.z);
glNormal3fv(value_ptr(box.vertices.at(box.indices.at(i + 1)).Normal));
glVertex3f(box.vertices.at(box.indices.at(i + 1)).Position.x, box.vertices.at(box.indices.at(i + 1)).Position.y, box.vertices.at(box.indices.at(i + 1)).Position.z);
glNormal3fv(value_ptr(box.vertices.at(box.indices.at(i + 2)).Normal));
glVertex3f(box.vertices.at(box.indices.at(i + 2)).Position.x, box.vertices.at(box.indices.at(i + 2)).Position.y, box.vertices.at(box.indices.at(i + 2)).Position.z);
}
glEnd();
glPopMatrix();
glPushMatrix();
gluLookAt(camera.position.x, camera.position.y, camera.position.z, box.center.x, box.center.y, box.center.z,
camera.upVector.x, camera.upVector.y, camera.upVector.z);
glLightfv(GL_LIGHT0, GL_POSITION, value_ptr(vec4(lights.at(0).position, 1.0f)));
glPopMatrix();
glFlush();
glutSwapBuffers();
}
When the light position is set by glLightfv(GL_LIGHT0, GL_POSITION, pos)
, then
pos
is multiplied by the current model view matrix.
This means if the position is set before the view matrix is set (gluLookAt
), then the light position is relative to the camera (view space position).
If it is set after the view matrix was set, then the light position has to be in world coordinates, becaus it is transformed by the view matrix.
When the spot light direction is set by glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir)
, then
the direction is multiplied by the upper 3x3 of the modelview matrix.
Note, that the parameter GL_SPOT_DIRECTION
has to be a direction vector and not a position.
This means you have to set it somehow like this, after the view matrix was set:
vec3 dir = box.center - lights.at(0).position;
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, value_ptr(dir));
Further note, that the OpenGL fixed function pipeline calculates the light per vertex: Gouraud shading.
This may cause, that you can't "see" the light, if the light cone of the spotlight does not hit any vertex position.
You are in danger of that behavior, because your geometry consists of "large" primitives and the cone opening angle of the spot light is very small (15°).
See OpenGL Lighting on texture plane is not working
Edit:
Your light cone angle (GL_SPOT_DIRECTION
) is 15° and the direction of the light is slightly directed to the bottom left, because according to the comment below box.center
is (-6.6,-6.6,-53). This causes that the one and only vertex coordinate which receives light is the bottom left corner (Gouraud shading).
So it seem as if the light is directly directed to the bottom left corner.
Increase or skip the light cone angle to solve the issue:
e.g.:
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);