| |
 |
Tutorial on adding material to objects to affect Lighting
|
|
If you would like to see this site updated, please help out and
|
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;
}
|
Download C++ Source Code for this Tutorial
Download Visual Basic Source Code for this Tutorial
Comments:
| Name: Simon |
| Date: 2010-02-14 12:21:37 |
Comment:
Brief comment and how colours work: You are totally right for the light colours. The primary colours mixed as: R+G = Yellow R+B = Magenta (a pinky red) B+G = Cyan (a light blue)
And these three "new" colours (CYM) are the primary paint colours. They simply work the other way because material absorb and reflect specific light colours! eg: Cyan + yellow = green because normally Cyan reflects B and G and absorbs R, Yellow reflects R and G and absorbs B, so the combination absorbs R and B, and only G is reflected!
|
| Name: Donald Urquhart |
| Date: 2010-02-17 16:56:36 |
Comment:
Hi Simon,
That is a great description, hopefully it will help explain it for people.
Cheers, Donald Urquhart
|
| Name: Baby Stuey |
| Date: 2010-03-01 16:47:04 |
Comment:
Hey Donald,
Great job on these tutorials! I've been trying them on my Linux system, just using the ol' text editor and command-line compiler. I've found a couple of pitfalls that I hope I can save someone else doing it the old-fashioned way the frustration of figuring out!
Cheers,
Stu
---
1. There's nothing really "object-oriented" about this source code, so my instinct was to just label the files with a .c extension. This has a couple of side effects: you must manually include stdlib.h for any programs requiring the exit() function (among others); and there is no 'bool' type in ANSI C, requiring these to be changed to ints and the addition of #define true 1 and #define false 0 to the top of the code.
2. When the teapot first appears on the screen, it is white. The material values for the light components don't get set until you press each of the input keys once. This is fixed with the following modification to init():
void init (void) { glEnable (GL_DEPTH_TEST); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); // set initial material values here so we don't see a 'white' // teapot before the first key is pressed. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blankMaterial); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, blankMaterial); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, blankMaterial); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, blankMaterial); }
3. The following is just a tweak of keyboard() that removes some excess comparisons that don't need to be performed each time:
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); } } else 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); } } else 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); } } else if(key == 27) // 27 is the ASCII code for the ESC key { exit (0); // end the program } else { /* do nothing */ } }
4. :)
|
| Name: Baby Stuey |
| Date: 2010-03-01 16:48:45 |
Comment:
AHHH! My beautiful tabs got tossed in the bit bucket! :(
|
| Name: Baby Stuey |
| Date: 2010-03-01 18:20:41 |
Comment:
Trying again...
2. void init(void) { glEnable(GL_DEPTH_TEST); // enables depth testing glEnable(GL_LIGHTING); // enable OpenGL lighting support glEnable(GL_LIGHT0); // enable light #1 // glEnable(GL_COLOR_MATERIAL); // allow lights to colour materials // set initial material values here so we don't see a 'white' teapot // before the first key is pressed. glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blankMaterial); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, blankMaterial); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, blankMaterial); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, blankMaterial); }
3. 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); } } else 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); } } else 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); } } else if(key == 27) // 27 is the ASCII code for the ESC key { exit (0); // end the program } else { /* do nothing */ } }
|
Name Email
|
 |