Depth Testing and Lighting

You'll learn now:

How can I turn on depth testing?

Depth testing is used to remove hidden surfaces. We did not yet need it, because we always rendered wired objects. Lighting makes much more sense, when objects are filled and wired model are everything else but certainly not realistic.

Depth testing is difficult easy to use: Pass one more constant to glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

Now a depth buffer is created on which the depth information is stored for each pixel.

The next thing is to enble it: glEnable(GL_DEPTH_TEST); Now you can draw your objects as normal.

Depth buffering is sometimes also called z-buffering.

How can I enable lighting?

Just call glEnable(GL_LIGHTING);

Then you have to enable each of the lights you use, for example glEnable(GL_LIGHT0);

How can I specify light sources?

Lighting is a very complex topic and you can simulate every possible light with OpenGL. I only want to explain the basics here. In the DisplayList-tutorial, two sided lighting is explained.

Perhaps I'll write another tutorial that goes deeper into lighting.

To specify light properties, you have to use a glLight*() command, where * stands for f or i plus, if you want to specify the value as a vector, "v".

To pass the position to OpenGL you first define a four-dimensional vector (x,y,z and w). The x, y and z values are divided by w, that means that if you set "w" to 0.0, the position rises infinitely far away. An example for this is the sun. If you want to use a so called "positional" light (i.e. w is nonzero) you should set w to 1.0.

static GLfloat LightPos[] = {0.5, 0.5, 1.0, 1.0};

Then you call

glLightfv(GL_LIGHT0, GL_POSITION, LightPos);

Of course you can use other values for GL_LIGHT0.  Note that for keeping the light where you want it, you should call this command after each Camera.Render()

Another important value is the color. You can define different colors for different properties. Those different properties can be described when you imagine a metal sphere, once lit by a flashlight, once by a candle. Even if there is no other light source in the room, the objects are visible from each side. This is caused by reflections from the walls. I could imagine that a candle makes the sides of an object, that look away from the light, brighter than a flashlight. Perhaps that's wrong, I don't know, ask a physics expert or check it out! This value is called "ambient". Another value (diffuse), is the property, how much the polygons are lit when they don't face the light directly. A third parameter is called "specular". It defines, how much of the light is reflected. Here the value of the flashlite is probably higher than for the candle. You should also use different colors: The candle has a light that goes to yellow, a flashlight more white.

Have a look at the source of the tutorial to see the use of this command.

How can I specify material properties?

Material properties work similar to light properties. Of course they don't have a position, but also ambient, diffuse and specular properties. Especially the specular value differs from material to material: A metal object is much more shiny than a wooden one.

The command to specify the properties is glMaterial*().   The first argument is either, GL_FRONT, GL_BACK or GL_FRONT_AND_BACK. It is sometimes senseless to make the lighting calculations for the back side. But how does OpenGL know, which side is fron and which is back? This is done by the orientation of the vertices. By a call to glFrontFace() you can define, whether the front facing polygons should be the ones which are clockwise oriented (GL_CW) or counterclockwise (GL_CCW). If you pass GL_FRONT or GL_BACK to glMaterial*()  you should note, that your models must be in the correct format, otherwise you'll get wrong results. Here an example how you could set a material's property:

static GLfloat MatAmb[] = { 0.4, 0.4, 0.4, 1.0};

static GLfloat MatDiff[] = { 0.8, 0.6, 0.6, 1.0};

glMaterialfv(GL_FRONT, GL_AMBIENT, MatAmb);
glMaterialfv(GL_FRONT, GL_DIFFUSE, MatDiff);

Here you can see the results of using this tutorial.



Any comments? Conact me!