C++ Opengl - lighting using spotlight

Itzik984 picture Itzik984 · Dec 15, 2012 · Viewed 16.3k times · Source

I have a model that needs to be under a spotlight/directional light,

Meaning, I need to switch between the modes (Spotlight and directional).

Here is the code with some explanation:

I can rotate the model / light source with mouse movements so I am using

glRotate and glTranslate for that.

Once the user pressed the 'L' key I'm supposed to switch between the modes.

here is the code for the lightning:

void LightBall::projectLight(void)
{
if(LIGHT == _lightMode){
    printf("Entering LIGHT mode\n"); <--- Supposed to be a directional light
    glDisable(GL_LIGHT1);
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_POSITION, _light_position);
}

if(SPOT_LIGHT == _lightMode){
    printf("Entering SPOTLIGHT mode\n"); <--- Supposed to be a spotlight
    glDisable(GL_LIGHT0);
    glEnable(GL_LIGHT1);
    glLightfv(GL_LIGHT1, GL_POSITION, _light_position);
    glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 10.0);
    glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.0);
    glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,_spotlight_position);
}
}

The problem is I always get the same light mode when switching between them,

Which is the following:

directional

And another example after switching between 2 light modes and still getting same light

source with light source rotation (the small ball):

rotation

How can I get the wanted result?

Here are the LIGHT0 & LIGHT1 definitions:

    GLfloat light_ambient[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse[] = { 1.0, 0.0, 0.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
_light_position[0] =  0.0;
_light_position[1] = 1.0;
_light_position[2] = 0.0;
_light_position[3] = 0.0;

_spotlight_position[0] = 0.0;
_spotlight_position[1] = -1.0;
_spotlight_position[2] = 0.0;

glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular);

Thanks!

Answer

Whether a GL light is a directional light or a spotlight depends on the w (4th) component of its position. If the coordinate is 0, it's directional. If nonzero (usually 1), it's a spotlight. You'll have to modify _lightPosition accordingly before calling glLightfv(..., GL_POSITION, ...).