Light does not work

Hello, I want to light a green plane with a positioned light source, but it does not work.


#include <GL/glut.h>

void draw(){
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    GLfloat ambientColor[] = {0.0f, 0.0f, 0.0f, 1.0f};
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

    //Light
    GLfloat lightColor0[] = {0.9f, 0.9f, 0.9f, 1.0f};
    GLfloat lightPos0[] = {0.0f, 1.0f, 0.0f, 1};
    glLightfv(GL_LIGHT1, GL_SPECULAR, lightColor0);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor0);
    glLightfv(GL_LIGHT1, GL_POSITION, lightPos0);
    
    glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 45.0);
    GLfloat spot_direction[] = { 0.0, -1.0, 0.0 };
    glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);
    glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 2.0);
    glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.0);
    
    //Material
    GLfloat mcolor[] = {0.1, 0.9, 0.4, 1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mcolor);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mcolor);
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0);
    
    //Green plane
    glColor3fv(mcolor); 
    glBegin(GL_QUADS);
        glNormal3f(0,1,0);
        glVertex3f(-50.0, 0.0,-50.0);
        glVertex3f(-50.0, 0.0, 50.0);
        glVertex3f( 50.0, 0.0, 50.0);
        glVertex3f( 50.0, 0.0,-50.0);
    glEnd();
     
    glutSwapBuffers();
}


int main(){
    
    int argc = 1; char* argv[] = {(char*)"test"};
    glutInit(&argc, argv);
    
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    glutInitWindowPosition(100, 50);
    glutInitWindowSize(600, 600);
    glutCreateWindow("Light");
    glutDisplayFunc(draw);
    
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_LIGHTING);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_COLOR_MATERIAL);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, 1, 0.1, 100.0);
    gluLookAt(0.0, 1.0, 5.0,    0.0f, 1.0f, 0.0f,    0,1,0);
    
    
    glEnable(GL_LIGHT1);
    
    glutMainLoop();
    return 0;
}

Here you go:


#include <GL/glut.h>

void draw(){
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 200.0, 0.0,    0.0f, 0.0f, 0.0f,    0,0,1);
    
    GLfloat ambientColor[] = {0.0f, 0.0f, 0.0f, 1.0f};
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

    //Light
    GLfloat lightColor0[] = {0.9f, 0.9f, 0.9f, 1.0f};
    GLfloat lightPos0[] = {0.0f, 30.0f, 0.0f, 1};
    glLightfv(GL_LIGHT1, GL_SPECULAR, lightColor0);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightColor0);
    glLightfv(GL_LIGHT1, GL_POSITION, lightPos0);
    
    glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 45.0);
    GLfloat spot_direction[] = { 0.0, -1.0, 0.0 };
    glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction);
    glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 2.0);
    glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.0);
    
    //Material
    GLfloat mcolor[] = {0.1, 0.9, 0.4, 1.0};
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mcolor);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mcolor);
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0);
    
    //Green plane
    glColor3fv(mcolor); 
    glNormal3f(0,1,0);

    glBegin(GL_QUADS);
    for ( int x = -50; x < 50; x++ )
      for ( int z = -50; z < 50; z++ )
      {
        glVertex3f( x  , 0, z   );
        glVertex3f( x  , 0, z+1 );
        glVertex3f( x+1, 0, z+1 );
        glVertex3f( x+1, 0, z   );
      }
    glEnd();
     
    glutSwapBuffers();
}


int main(){
    
    int argc = 1; char* argv[] = {(char*)"test"};
    glutInit(&argc, argv);
    
    glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
    glutInitWindowPosition(100, 50);
    glutInitWindowSize(600, 600);
    glutCreateWindow("Light");
    glutDisplayFunc(draw);
    
    glClearColor(0.0f, 0.0f, 0.25f, 1.0f);
    
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glEnable(GL_LIGHTING);
    glShadeModel(GL_SMOOTH);
    glDisable(GL_COLOR_MATERIAL);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, 1, 1, 1000.0);
    
    
    glEnable(GL_LIGHT1);
    
    glutMainLoop();
    return 0;
}

Now let’s briefly discuss the changes:


> diff tst2.orig.cxx tst2.cxx                                       7a8
>     gluLookAt(0.0, 200.0, 0.0,    0.0f, 0.0f, 0.0f,    0,0,1);
14c15
<     GLfloat lightPos0[] = {0.0f, 1.0f, 0.0f, 1};
---
>     GLfloat lightPos0[] = {0.0f, 30.0f, 0.0f, 1};
32a34,35
>     glNormal3f(0,1,0);
> 
34,38c37,44
<         glNormal3f(0,1,0);
<         glVertex3f(-50.0, 0.0,-50.0);
<         glVertex3f(-50.0, 0.0, 50.0);
<         glVertex3f( 50.0, 0.0, 50.0);
<         glVertex3f( 50.0, 0.0,-50.0);
---
>     for ( int x = -50; x < 50; x++ )
>       for ( int z = -50; z < 50; z++ )
>       {
>         glVertex3f( x  , 0, z   );
>         glVertex3f( x  , 0, z+1 );
>         glVertex3f( x+1, 0, z+1 );
>         glVertex3f( x+1, 0, z   );
>       }
56c62
<     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
---
>     glClearColor(0.0f, 0.0f, 0.25f, 1.0f);
62c68
<     glEnable(GL_COLOR_MATERIAL);
---
>     glDisable(GL_COLOR_MATERIAL);
66,67c72
<     gluPerspective(45, 1, 0.1, 100.0);
<     gluLookAt(0.0, 1.0, 5.0,    0.0f, 1.0f, 0.0f,    0,1,0);
---
>     gluPerspective(45, 1, 1, 1000.0);

First, when debugging such issues I highly recommend turning off GL_LIGHTING first and ensuring that your PROJECTION and VIEWING transforms are right. In your code you were calling gluLookAt (sets the viewing transform), but pushing it on the PROJECTION matrix stack instead of the MODELVIEW matrix stack. So I moved it up into your draw() method after you load identity onto MODELVIEW, and tweaked the value so that you’re looking directly down onto the quad.

Also so we could see the quad better, changed your clear color to 0, 0, 0.25 so that we could see the quad even if it’s black.

Second, because the fixed-function pipeline only does vertex lighting, it’s pretty darn hard to see spotlights unless you have a bunch of vertices. You only had 1 quad stretching from X=-50…50,Z=-50…50, so for the heck of it I created 10,000 quads, each 1x1, filling this same region. Of course, the modern solution to this problem is to just write your own shaders and do lighting at fragment (pixel) frequency rather than vertex frequency. Then you only need one quad, not tons of them, to see decent lighting quality on a flat region.

I disabled color material because you’re already setting the uniform material attributes and didn’t have a glColorMaterial directive to say which ones to override with the vertex color. They’re all mcolor, so it didn’t matter anyway.

I pushed your far clip plane (gluPerspective) out from 100 to 1000, so we could get the entire quad in view with a 45 deg FOV.

And I backed your light position up from the object a bit so we could see the light’s effect a bit better.

Note that you could have used GL_LIGHT0 instead of GL_LIGHT1. Doesn’t really make any difference though.

Also, one thing to keep in mind is that the MODELVIEW transform that is active when you position your light source is used to transform that position into eye space. Right now you’ve only got a VIEWING transform (gluLookAt) on the MODELVIEW, so your object and your light are both specified in WORLD space.

You’ll notice that the edges of the spotlight cone are really jaggy. That’s because the lighting is only computed per vertex and there are only so many vertices in a 100x100 grid. If you write your own shaders and do fragment lighting, you get a cut-off that’s accurate per pixel. But the work-around is to either increase your SPOT_CUTOFF angle or increase your SPOT_EXPONENT so that the beam intensity falls off before the existing SPOT_CUTOFF angle.

hi,

I have a similar problem to the one Ryuzaki posted.

the difference is, that I have a complex scene, with multiple objects, each of them having it’s own texture and so on.

I’ve also defined a spotlight, but it has absolutely no effect on my scene, and I can’t figure out why.

I define it like this:

GLfloat mat_specular3[] = { 3.0, 3.0, 3.0, 1.0 };
GLfloat mat_shininess3[] = { 50.0 };
GLfloat light_position3[] = { -9.0,6.0,0.0, 1.0 };
GLfloat spotDir[] = { -9.0,6.0,0.0 };
glClearColor (0.5, 0.5, 0.5, 0.0);
glLightfv(GL_LIGHT2,GL_SPECULAR,mat_specular2);
glLightfv(GL_LIGHT2,GL_POSITION,light_position2);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular2);
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess2);
// Definig spotlight attributes
glLightf(GL_LIGHT2,GL_SPOT_CUTOFF,60.0);
glLightf(GL_LIGHT2,GL_SPOT_EXPONENT,60.0);
glLightfv(GL_LIGHT2,GL_SPOT_DIRECTION,spotDir);
glLightf(GL_LIGHT2, GL_CONSTANT_ATTENUATION, 2.0);

notes: I enable it in the renderScene function; this is my third light in the scene, that’s why it’s numbered this way

any ideas?
thx:)

Util you ensure you’re doing things right, you want the light to be as blatent as possible so you can see its effect.

First, make the light omnidirectional (GL_SPOT_CUTOFF = 180.0).

Second don’t let the light attenuate (CONSTANT_ATTENUATION = 1.0, LINEAR_ATTENUATION = 0.0, QUADRATIC_ATTENUATION = 0.0

Third, it looks like you want to make this light all specular. That’s hard to see sometimes. I’d instead make it all diffuse (GL_DIFFUSE = 1,1,1), and get rid of the specular initially.

Now you’re more likely to see “something” and get some visual indication of where the light is in your scene.

If not, then try cranking up the GL_AMBIENT of the light to 1,0,0,1. Then go from there based on whether everything turns red or not.

Keep in mind that the light’s GL_POSITION and GL_DIRECTION are transformed by the then-active MODELVIEW, so pay attention to what your MODELVIEW matrix is set to when you call the above.