Open GL Super Bible

Previous Table of Contents Next


Listing 9-7 The rendering function from the WAVEY example program

// Called to draw scene
void RenderScene(void)
        {
        float normal[3];   // Storage for calculate normal
        float v[4][3];     // Storage for rectangle coordinates
        float lastY;       // Left-hand side of rectangle
        float nextY;       // Right-hand side of rectangle
        float temp;        // Temporary storage for swapping
        float x;           // X coordinate storage

        // Menu state specifies if wireframe or not
        if(iState == WIRE)
                glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
        else
                glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

        // Menu state specifies if smooth or flat shading
        if(iState == SMOOTH || iState == AVERAGE)
                glShadeModel(GL_SMOOTH);
        else
                glShadeModel(GL_FLAT);

        // Clear the window with current clearing color
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Reset viewing volume and viewport
        ChangeSize(lastWidth,lastHeight);

        // Rotate the image according to accumulated angle set
        // by the arrow key handlers
        glRotatef(xRot, 1.0f, 0.0f, 0.0f);
        glRotatef(yRot, 0.0f, 1.0f, 0.0f);

        // Set surface color to blue
        glRGB(0,0,255);

        // Initialize the y steppings
        lastY = 0.0f;
        nextY = 10.0f;

        // Loop through x coordinate from left to right, build
        // a rectangle with alternating slopes upward and downward
        for(x = -60.0f; x < 60.0f; x+= 20.0f)
                {
                // 1st Vertices
                v[0][0] = x;        // X coord for left
                v[0][1] = lastY;
                v[0][2] = 50.0f;    // Z coord for back

                // 2nd vertices
                v[1][0] = x;        // X coord for left
                v[1][1] = lastY;
                v[1][2] = -50.0f;   // Z coord for front

                // 3rd Vertices
                v[2][0] = x + 20.0f;  // X coord for right
                v[2][1] = nextY;
                v[2][2] = -50.0f;   // Z coord for front

                // 4th Vertices
                v[3][0] = x + 20.0f;  // X coord for right
                v[3][1] = nextY;
                v[3][2] = 50.0f;    // Z coord for back

                // Begin the polygon
                glBegin(GL_POLYGON);
                        if(iState != AVERAGE)
                               {
                               // Calculate and set the normal vector,
                               unless
                               // averaging selected from the menu.
                               calcNormal(v,normal);
                               glNormal3fv(normal);
                               }
                        else   // Average normals. Here we cheat because we
                               know
                               // the normal points either up or down
                               {
                               // Normal points straight up
                               if(nextY == 10)
                                       glNormal3f(0.0f,1.0f, 0.0f);
                               else
                                       // Normal points straight down
                                       glNormal3f(0.0f,-1.0f, 0.0f);
                               }

                        // Specify the left two verticies
                        glVertex3fv(v[0]);
                        glVertex3fv(v[1]);

                        // Do the same, but the normal on the other side
                        points 
                        // the other direction
                        if(iState == AVERAGE)
                               {
                               if(nextY == 10)
                                       glNormal3f(0.0f,-1.0f, 0.0f);
                                       // points down
                               else
                                       glNormal3f(0.0f,1.0f, 0.0f);
                                       // points up
                               }

                        // Specify the right two vertices
                        glVertex3fv(v[2]);
                        glVertex3fv(v[3]);
                glEnd();

                // Swap the y coordinate positions
                temp = lastY;
                lastY = nextY;
                nextY = temp;
                }

         // Flush drawing commands
         glFlush();
         }

The WAVEY program has menu options to render just a wireframe image, do flat or smooth shading, and finally do the normal averaging. Figure 9-20 shows this folding image using flat shading, and Figure 9-21 is the same object with the normals averaged. You can see that the second image appears to have a smooth rippling effect across its surface.


Figure 9-20  Bent surface with regular surface normals


Figure 9-21  Bent surface with surface normals averaged together

Spotlights

So far, we have been specifying a light’s position with glLight as follows:

// Array to specify position
GLfloat  lightPos[] = { 0.0f, 150.0f, 150.0f, 1.0f };

…
…

// Set the light position
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);

The array lightPos[] contains the x, y, and z values that specify either the light’s actual position in the scene, or the direction from which the light is coming. The last value, a 1.0 in this case, indicates that the light is actually present at this location. By default, the light will radiate equally in all directions from this location—but this can be changed to make a spotlight effect.

To make a light source an infinite distance away and coming from the direction specified by this vector, you would place a 0.0 in this last lightPos[] array element. A directional light source, as this is called, strikes the surface of your objects evenly. That is, all the light rays are parallel. In a positional light source on the other hand, the light rays diverge from the light source. The specular highlights achieved in the SHINYJET example would not be possible with a directional light source. Rather than the glistening spot, the entire face of the triangles that make up the jet would be white when they faced the light source dead on (the light rays strike the surface at a 90? angle).


Previous Table of Contents Next