Open GL Super Bible

Previous Table of Contents Next


Specular Exponent

As stated earlier, high specular light and reflectivity brighten the colors of the object. For this example, the present extremely high specular light (full intensity) and specular reflectivity (full reflectivity) will result in a jet that appears almost totally white or gray except where the surface points away from the light source (in which case it would be black and unlit). To temper this effect, we use the next line of code after the specular component is specified, as follows:

glMateriali(GL_FRONT,GL_SHININESS,128);

The GL_SHININES property sets the specular exponent of the material, which specifies how small and focused the specular highlight is. A value of 0 specifies an unfocused specular highlight, which is actually what is producing the brightening of the colors evenly across the entire polygon. If you set this value, you reduce the size and increase the focus of the specular highlight, causing a shiny spot to appear. The larger the value, the more shiny and pronounced the surface. The range of this parameter is 1–128 for all implementations of OpenGL.

Listing 9-6 shows the new SetupRC code in the sample program SHINYJET. This is the only code that changed from LITJET (other than the title of the window) to produce a very shiny and glistening jet. Figure 9-17 shows the output from this program, but to fully appreciate the effect, you should run the program and hold down one of the arrow keys to spin the jet about in the sunlight.


Figure 9-17  Output from the SHINYJET program

Listing 9-6 Setup from SHINYJET to produce specular highlights on the jet

// This function does any needed initialization on the rendering
// context.  Here it sets up and initializes the lighting for
// the scene.
void SetupRC()
        {
        // Light values and coordinates
        GLfloat  ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f };
        GLfloat  diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };
        GLfloat  specular[] = { 1.0f, 1.0f, 1.0f, 1.0f};
        Glfloat  lightPos[] = { 0.0f, 150.0f, 150.0f, 1.0f };
        GLfloat  specref[] =  { 1.0f, 1.0f, 1.0f, 1.0f };

        glEnable(GL_DEPTH_TEST);   // Hidden surface removal
        glFrontFace(GL_CCW);       // Counterclockwise polygons face out
        glEnable(GL_CULL_FACE);    // Do not calculate inside of jet

        // Enable lighting
        glEnable(GL_LIGHTING);

        // Set up and enable light 0
        glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
        glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
        glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
        glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
        glEnable(GL_LIGHT0);

        // Enable color tracking
        glEnable(GL_COLOR_MATERIAL);

        // Set Material properties to follow glColor values
        glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

        // All materials hereafter have full specular reflectivity
        // with a high shine
        glMaterialfv(GL_FRONT, GL_SPECULAR,specref);
        glMateriali(GL_FRONT,GL_SHININESS,128);

        // Light blue background
        glClearColor(0.0f, 0.0f, 1.0f, 1.0f );
        }

Normal Averaging

Earlier we mentioned that by “tweaking” your normals you can produce smooth surfaces with straight lines. This technique, known as normal averaging, produces some interesting optical illusions. Say you have a surface like that shown in Figure 9-18, with the usual surface normals.


Figure 9-18  Jagged surface with the usual surface normals

Although the normals are shown in between the corners, they are actually specified for each vertex. If you take into account that each vertex actually boarders another surface, you can specify the normal for that vertex as the average of the two normals at that point for each surface. Figure 9-19 shows that for two adjoining surfaces, their common corner would have a different normal specified as each surface is drawn. If we take the average of these two normals and use it when we specify each surface, the joining of the two surfaces will appear less sharp after OpenGL does its surface shading.


Figure 9-19  Averaging the normals will make sharp corners appear softer

Listing 9-7 shows the rendering function that creates the surface shown in Figure 9-18. (This code is from the example program WAVEY in the CD subdirectory for this chapter.) The surface is created by stepping from left to right for the x coordinates, and alternating up and down in the y coordinate direction. The z coordinates are constant, with –50 being the front of the image and 50 being at the back.


Previous Table of Contents Next