12. OpenGL Materials and Lighting

So now we have our lights set up exactly how we want them.

The only problem now is adding colours to our objects that work
with the light.

First you should know a little about how light works. For example:
Light addition and Light subtraction. This comes into play when you
have coloured lights and coloured objects. In case you didnt know,
light doesnt work the same way colour wise, as say paint. If you get
red and green paint and mix them together, you will get brown, light
on the other hand you mix red and green and you get yellow. Go figure,
thats just the way light works.

Here are some basic colouring to show you what I mean.
Paint
Red + Green = Brown
Blue + Yellow = Green
White + Blue = Light Blue
Red + White = Light Red

Lights
Red + Green = Yellow
Blue + Yellow = White
White + Blue = Light Blue
Red + White = Yellow

I pointed out earlier that you can keep your current colours
by using:
glEnable(GL_COLOR_MATERIAL);

But this only sets the colour, because we are using lights
we can also change to properties of how the objects colour
is effected by each type of light along with a shininess factor
which allows the object to reflect a certain amount of light.

When it comes to shininess, the shininess factor is a number between
0 and 128, where 0 is the shiniest the object can be.

Now first we as usual have to set up our variables:
set the material to red
GLfloat redDiffuseMaterial[] = {1.0, 0.0, 0.0};
set the material to white
GLfloat whiteSpecularMaterial[] = {1.0, 1.0, 1.0};
set the material to green
GLfloat greenEmissiveMaterial[] = {0.0, 1.0, 0.0};

set the light specular to white
GLfloat whiteSpecularLight[] = {1.0, 1.0, 1.0};
set the light ambient to black
GLfloat blackAmbientLight[] = {0.0, 0.0, 0.0};
set the diffuse light to white
GLfloat whiteDiffuseLight[] = {1.0, 1.0, 1.0};

I am starting off with all the materials disabled, this will
cause our object to appear black as the ambient light is set to black
bool diffuse = false;
bool emissive = false;
bool specular = false;

Now I am just assigning the colours to the current light
glLightfv(GL_LIGHT0, GL_SPECULAR, whiteSpecularLight);
glLightfv(GL_LIGHT0, GL_AMBIENT, blackAmbientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteDiffuseLight);

Now for the actual adding of materials to objects:
Because I am not setting the material unless it is enabled I am using this code
if (key==’s’)
{
if (specular==false)
{

If specular is enabled then set the specular material to the white material,
and the shininess to our shininess value
specular = true;
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, whiteSpecularMaterial);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mShininess);
}
else if (specular==true)
{

If specular is not enabled then set the specular material to the blank material,
and the shininess value to our blank material
specular = false;
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blankMaterial);
glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, blankMaterial);
}
}

if (key==’d’)
{
if (diffuse==false)
{

If diffuse is enabled then set the diffuse material to the red material
diffuse = true;
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, redDiffuseMaterial);
}
else if (diffuse==true)
{

If diffuse is not enabled then set the diffuse material to the blank material
diffuse = false;
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, blankMaterial);
}
}

if (key==’e’)
{
if (emissive==false)
{

If emissive is enabled then set the emissive material to the green material
emissive = true;
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, greenEmissiveMaterial);
}
else if (emissive==true)
{

If emissive is not enabled then set the emissive material to the blank material
emissive = false;
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, blankMaterial);
}

I am setting whether or not the materials are enabled through simple
key presses of, e,s and d.

If you have any issues with this tutorial, please 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.
    #include <GL/gl.h>
#include <GL/glut.h>

GLfloat angle = 0.0;

GLfloat redDiffuseMaterial[] = {1.0, 0.0, 0.0}; //set the 
material to red

GLfloat whiteSpecularMaterial[] = {1.0, 1.0, 1.0}; //set 
the material to white

GLfloat greenEmissiveMaterial[] = {0.0, 1.0, 0.0}; //set 
the material to green

GLfloat whiteSpecularLight[] = {1.0, 1.0, 1.0}; //set the 
light specular to white

GLfloat blackAmbientLight[] = {0.0, 0.0, 0.0}; //set the 
light ambient to black

GLfloat whiteDiffuseLight[] = {1.0, 1.0, 1.0}; //set the 
diffuse light to white

GLfloat blankMaterial[] = {0.0, 0.0, 0.0}; //set the diffuse
 light to white

GLfloat mShininess[] = {128}; //set the shininess of the 
material

bool diffuse = false;
bool emissive = false;
bool specular = false;

void init (void) {
    glEnable (GL_DEPTH_TEST);
    glEnable (GL_LIGHTING);
    glEnable (GL_LIGHT0);
}

void light (void) {
    glLightfv(GL_LIGHT0, GL_SPECULAR, whiteSpecularLight);
    glLightfv(GL_LIGHT0, GL_AMBIENT, blackAmbientLight);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, whiteDiffuseLight);
}

void display (void) {
    glClearColor (0.0,0.0,0.0,1.0);
    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    light();
    glTranslatef(0,0,5);
    
    glRotatef(angle,1,1,1);
    
    glutSolidTeapot(2);
    glutSwapBuffers();
    angle ++;
}

void reshape (int w, int h) {
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
    glMatrixMode (GL_MODELVIEW);
}

void keyboard (unsigned char key, int x, int y) {
    if (key==‘s’)
    {
        if (specular==false)
        {
            specular = true;
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, 
whiteSpecularMaterial);
            glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mShininess);
        }
        else if (specular==true)
        {
            specular = false;
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blankMaterial);
            glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 
blankMaterial);
        }
    }
    
    if (key==‘d’)
    {
        if (diffuse==false)
        {
            diffuse = true;
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, 
redDiffuseMaterial);
        }
        else if (diffuse==true)
        {
            diffuse = false;
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, blankMaterial);
        }
    }
    
    if (key==‘e’)
    {
        if (emissive==false)
        {
            emissive = true;
            glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, 
greenEmissiveMaterial);
        }
        else if (emissive==true)
        {
            emissive = false;
            glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, blankMaterial);
        }
    }
}

int main (int argc, char **argv) {
    glutInit (&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize (500, 500);
    glutInitWindowPosition (100, 100);
    glutCreateWindow (“A basic OpenGL Window);
    init ();
    glutDisplayFunc (display);
    glutIdleFunc (display);
    glutKeyboardFunc (keyboard);
    glutReshapeFunc (reshape);
    glutMainLoop ();
    return 0;
}

  • March 25, 2010
  • 5