13. OpenGL Lighting Types

Previously we spoke about setting up some basic lights.

Here we are going to take that to the next level and set the type
of shading, the colour of the light, the colour of our object
and the type of light in which we are using.

Now lets take into account that OpenGL has different types of lights.
They are:
Specular
Diffuse
Ambient
Emissive

A specular light is a light that sets highlights and often the shininess of
an object. So if you light a sphere with a diffuse light and a specular light
the specular light will add the highlights.

A diffuse light, is just a coloured light, and handles the diffuse term for lighting. It basically sets the colour.

An ambient light is a light that lights up the scene from every direction.
So even though the sun is a diffuse light, it acts like an ambient light
to us who are on the surface of the earth and during the day, see light
everywhere.

Now an emissive light is a light which radiates from an object. Like a glow, only without the nice, blurred halo type effect.

Now first off we need variables to hold our light colours and positions.
I am setting these up in our Display function as they are requiring variables
which I am setting up at runtime.
set DiffuseLight[] to the specified values
GLfloat DiffuseLight[] = {dlr, dlg, dlb};
set AmbientLight[] to the specified values
GLfloat AmbientLight[] = {alr, alg, alb};
set the LightPosition to the specified values
GLfloat LightPosition[] = {lx, ly, lz, lw};

Now I am going to use 2 lights here, so I enable them with:
glEnable (GL_LIGHT0);
glEnable (GL_LIGHT1);

Next I am setting the light variables:

diffuse light color variables
GLfloat dlr = 1.0;
GLfloat dlg = 1.0;
GLfloat dlb = 1.0;

ambient light color variables
GLfloat alr = 1.0;
GLfloat alg = 1.0;
GLfloat alb = 1.0;

light position variables
GLfloat lx = 0.0;
GLfloat ly = 0.0;
GLfloat lz = 1.0;
GLfloat lw = 0.0;

As you can see, I have made the diffuse light white by setting it to:
R = 1, G = 1, B = 1
I have then done the same with the ambient light.

Next I have set the position so that it is placed at:
X = 0, Y = 0, Z = 1, W = 0
Now as for the fourth variable, that sets whether or not we want a point light. If we want a point light, we will set it to 1.0, if we want a directional light, we will use 0.0. In this case, I am using a light that points in the direction of the z axis.

Now to get this to take effect in our application I set up the lights with:
Set our diffuse light to our diffuse light color
glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLight);
Set our ambient light to our ambient light color
glLightfv (GL_LIGHT1, GL_AMBIENT, AmbientLight);
Move the light to the position we have set
glLightfv (GL_LIGHT0, GL_POSITION, LightPosition);

So light0 is our diffuse light and light1 is our ambient light.
You could technically set all these values to one light, but I have
done it in 2.

Now as for the shade model, you can set this to either:
GL_SMOOTH
or
GL_FLAT

Smooth allows for a nice transition from the dark colour to the light
colour, while flat makes the side, 1 colour, instead of a nice gradient.

If you have any queries over this tutorial, email me at swiftless@gmail.com

1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
    #include <GL/gl.h>
#include <GL/glut.h>

//angle of rotation
GLfloat angle = 0.0;

//diffuse light color variables
GLfloat dlr = 1.0;
GLfloat dlg = 1.0;
GLfloat dlb = 1.0;

//ambient light color variables
GLfloat alr = 1.0;
GLfloat alg = 1.0;
GLfloat alb = 1.0;

//light position variables
GLfloat lx = 0.0;
GLfloat ly = 0.0;
GLfloat lz = 1.0;
GLfloat lw = 0.0;

//draw the cube
void cube (void) {
    glRotatef(angle, 1.0, 0.0, 0.0); //rotate on the x axis
    glRotatef(angle, 0.0, 1.0, 0.0); //rotate on the y axis
    glRotatef(angle, 0.0, 0.0, 1.0); //rotate on the z axis
    glutSolidCube(2); //draw the cube
}

void init (void) {
    glEnable (GL_DEPTH_TEST); //enable the depth testing
    glEnable (GL_LIGHTING); //enable the lighting
    glEnable (GL_LIGHT0); //enable LIGHT0, our Diffuse Light
    glEnable (GL_LIGHT1); //enable LIGHT1, our Ambient Light
    glShadeModel (GL_SMOOTH); //set the shader to smooth shader

}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0); //clear the screen to 
black

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /
/clear the color buffer and the depth buffer

    glLoadIdentity();  
    GLfloat DiffuseLight[] = {dlr, dlg, dlb}; //set DiffuseLight
[] to the specified values

    GLfloat AmbientLight[] = {alr, alg, alb}; //set AmbientLight
[] to the specified values

    glLightfv (GL_LIGHT0, GL_DIFFUSE, DiffuseLight); //change
 the light accordingly

    glLightfv (GL_LIGHT1, GL_AMBIENT, AmbientLight); //change
 the light accordingly

    GLfloat LightPosition[] = {lx, ly, lz, lw}; //set the 
LightPosition to the specified values

    glLightfv (GL_LIGHT0, GL_POSITION, LightPosition); /
/change the light accordingly

    gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); /
/camera position, x,y,z, looking at x,y,z, Up Positions of the 
camera

    cube(); //call the cube drawing function
    glutSwapBuffers(); //swap the buffers
    angle++; //increase the angle
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h); //set the viewport
 to the current window specifications

    glMatrixMode (GL_PROJECTION); //set the matrix to projection

    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0)
; //set the perspective (angle of sight, width, height, , depth
)

    glMatrixMode (GL_MODELVIEW); //set the matrix back to model

}

void keyboard (unsigned char key, int x, int y) {
    if (key==‘r’) {
        dlr = 1.0; //change light to red
        dlg = 0.0;
        dlb = 0.0;
    }
    if (key==‘g’) {
        dlr = 0.0; //change light to green
        dlg = 1.0;
        dlb = 0.0;
    }
    if (key==‘b’) {
        dlr = 0.0; //change light to blue
        dlg = 0.0;
        dlb = 1.0;
    }
    if (key==‘w’) {
        ly += 10.0; //move the light up
    }
    if (key==‘s’) {
        ly = 10.0; //move the light down
    }
    if (key==‘a’) {
        lx = 10.0; //move the light left
    }
    if (key==‘d’) {
        lx += 10.0; //move the light right
    }
}

int main (int argc, char **argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH); //set 
the display to Double buffer, with depth

    glutInitWindowSize (500, 500); //set the window size
    glutInitWindowPosition (100, 100); //set the position of 
the window

    glutCreateWindow (“A basic OpenGL Window); //the caption
 of the window

    init (); //call the init function
    glutDisplayFunc (display); //use the display function to 
draw everything

    glutIdleFunc (display); //update any variables in display,
 display can be changed to anyhing, as long as you move the 
variables to be updated, in this case, angle++;

    glutReshapeFunc (reshape); //reshape the window accordingly

    glutKeyboardFunc (keyboard); //check the keyboard
    glutMainLoop (); //call the main loop
    return 0;
}

  • March 25, 2010
  • 8