Positional light rotates with camera

So I’ve been trying to get a positional light to work in my code for some time now, and I can’t seem to get it to work the way I expect. I set the light next to my ‘shed’, and it will seemingly rotate with the camera. Any ideas?

Here is my code for moving the camera:


void mousemove_func(int x, int y)
{
    if (x != glutGet(GLUT_WINDOW_WIDTH) / 2 || y != glutGet(GLUT_WINDOW_HEIGHT) / 2)
    {
        GLfloat diffx = x - (glutGet(GLUT_WINDOW_WIDTH) / 2);
        GLfloat diffy = y - (glutGet(GLUT_WINDOW_HEIGHT) / 2);

        if ((camXAngle + diffy) < 70 && (camXAngle + diffy) > -70)
        {
            camXAngle += (diffy / 5);
            camYAngle += (diffx / 5);

            if (camYAngle > 360)
            {
                camYAngle -= 360;
            }

            else if (camYAngle < 0)
            {
                camYAngle += 360;
            }

            glutPostRedisplay();
        }

        glutWarpPointer(glutGet(GLUT_WINDOW_WIDTH) / 2,
            glutGet(GLUT_WINDOW_HEIGHT) / 2);
    }
}

Code for the light itself:


void display()
{

...
        // positional light
    glPushMatrix();

    glRotatef(camXAngle, 1, 0, 0);
    glRotatef(camYAngle, 0, 1, 0);
    glTranslatef(camXPos + 789, camYPos + 150, camZPos + 449); // sets the light at coordinate (789, 150, 449)

    shedLight.setSource(GL_LIGHT1);
    shedLight.setDiffuse(2, 2, 2);
    shedLight.setPosition(0, 0, 0, 1);
    shedLight.setDirection(0, -1, 0);
    shedLight.enableLight();

    glPopMatrix();
        ...
}


and here is the code for the light…


class light
{
public:

    light();
    ~light();

    void setPosition(GLint x, GLint y, GLint z, GLint w = 1);
    void setDirection(GLint x, GLint y, GLint z, GLint = 1);
    void setDiffuse(GLint r, GLint g, GLint b, GLint w = 1);
    void setSource(GLint lightSource);
    void setCutoff(GLint angle);

    void adjustLight();
    void enableLight();
    void disableLight();

private:

    GLfloat diffuseLight[4];
    GLfloat position[4];
    GLfloat direction[4];
    GLint source;
};

light::light() :
    source(GL_LIGHT0)
{
    for (int i = 0; i < 4; ++i)
    {
        diffuseLight[i] = 0;
        position[i] = 0;
        direction[i] = 0;
    }
    glLightfv(source, GL_SPOT_DIRECTION, direction);
    glLightfv(source, GL_DIFFUSE, diffuseLight);
    glLightfv(source, GL_POSITION, position);
}

light::~light()
{
}

void light::setCutoff(GLint angle)
{
    glLightf(source, GL_SPOT_CUTOFF, angle);
}

void light::setDiffuse(GLint r, GLint g, GLint b, GLint w)
{
    diffuseLight[0] = r;
    diffuseLight[1] = g;
    diffuseLight[2] = b;
    diffuseLight[3] = w;
    glLightfv(source, GL_DIFFUSE, diffuseLight);
}

void light::setPosition(GLint x, GLint y, GLint z, GLint w)
{
    position[0] = x;
    position[1] = y;
    position[2] = z;
    position[3] = w;
    glLightfv(source, GL_POSITION, position);
}

void light::setDirection(GLint x, GLint y, GLint z, GLint w)
{
    direction[0] = x;
    direction[1] = y;
    direction[2] = z;
    direction[3] = w;
    glLightfv(source, GL_SPOT_DIRECTION, direction);
}

void light::adjustLight()
{
    glLightfv(GL_LIGHT0, GL_POSITION, position);
}

void light::setSource(GLint lightSource)
{
    source = lightSource;
}

void light::enableLight()
{
    glEnable(source);
}

void light::disableLight()
{
    glDisable(source);
}

See the references to “modelview” on the glLight*() API man page. In particular, for GL_POSITION and GL_SPOT_DIRECTION.

Here are a few helpful links related to your problem:

(Ignore the title of the second link. Just read the contents.)

Fixed-Function GL stores the light position in eye space. To do this, the light position is multiplied by the current ModelView matrix at the time of the glLightfv(…, GL__POSITION, …) call. If you move your camera without re-specifying the light position, it has the effect of a light which remains stationary relative to the camera.

If you want a light which is stationary in the world, you have to load the view matrix (and just the view matrix) and specify the world space light position whenever the view matrix changes.