Open GL Super Bible

Previous Table of Contents Next


Triangle Fans

In addition to triangle strips, you can use GL_TRIANGLE_FAN to produce a group of connected triangles that fan around a central point. Figure 6-15 shows a fan of three triangles produced by specifying four vertices. The first vertex, V0, forms the origin of the fan. After the first three vertices are used to draw the initial triangle, all subsequent vertices are used with the origin (V0) and the vertex immediately preceding it (Vn-1) to form the next triangle. Notice that the vertices are traversed in a clockwise direction, rather than counterclockwise.


Figure 6-15  The progression of GL_TRIANGLE_FAN

Building Solid Objects

Composing a solid object out of triangles (or any other polygon) involves more than just assembling a series of vertices in a 3D coordinate space. Letís examine the example program TRIANGLE, which uses two triangle fans to create a cone in our viewing volume. The first fan produces the cone shape, using the first vertex as the point of the cone and the remaining vertices as points along a circle further down the z-axis. The second fan forms a circle and lies entirely in the xy plane, making up the bottom surface of the cone.

The output from TRIANGLE is shown in Figure 6-16. Here you are looking directly down the z-axis and can only see a circle composed of a fan of triangles. The individual triangles are emphasized by coloring them alternately green and red.


Figure 6-16  Initial output from the TRIANGLE sample program

The code for the SetupRC and RenderScene functions is shown in Listing 6-8. (You will see some unfamiliar variables and specifiers that will be explained shortly.) This program demonstrates several aspects of composing 3D objects. Notice the Effects menu item; this will be used to enable and disable some 3D drawing features so we can explore some of the characteristics of 3D object creation.

Listing 6-8 Pertinent code for the TRIANGLE sample program

// This function does any needed initialization on the rendering
// context.
void SetupRC()
        {
        // Black background
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

        // Set drawing color to green
        glColor3f(0.0f, 1.0f, 0.0f);

        // Set color shading model to flat
        glShadeModel(GL_FLAT);

        // Clockwise-wound polygons are front facing; this is reversed
        // because we are using triangle fans
        glFrontFace(GL_CW);
        }

// Called to draw scene
void RenderScene(void)
       {
       GLfloat x,y,angle;       // Storage for coordinates and angles
       int iPivot = 1;          // Used to flag alternating colors

       // Clear the window and the depth buffer
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

       // Turn culling on if flag is set
       if(bCull)
               glEnable(GL_CULL_FACE);
       else
               glDisable(GL_CULL_FACE);
       // Enable depth testing if flag is set
       if(bDepth)
               glEnable(GL_DEPTH_TEST);
       else
               glDisable(GL_DEPTH_TEST);
       // Draw the back side as a polygon only, if flag is set
       if(bOutline)
               glPolygonMode(GL_BACK,GL_LINE);
       else
               glPolygonMode(GL_BACK,GL_FILL);

       // Save matrix state and do the rotation
       glPushMatrix();
       glRotatef(xRot, 1.0f, 0.0f, 0.0f);
       glRotatef(yRot, 0.0f, 1.0f, 0.0f);

       // Begin a triangle fan
       glBegin(GL_TRIANGLE_FAN);

       // Pinnacle of cone is shared vertex for fan, moved up z-axis
       // to produce a cone instead of a circle
       glVertex3f(0.0f, 0.0f, 75.0f);

       // Loop around in a circle and specify even points
       along the circle
       // as the vertices of the triangle fan
       for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/8.0f))
              {
              // Calculate x and y position of the next vertex
              x = 50.0f*sin(angle);
              y = 50.0f*cos(angle);

              // Alternate color between red and green
              if((iPivot %2) == 0)
                      glColor3f(0.0f, 1.0f, 0.0f);
              else
                      glColor3f(1.0f, 0.0f, 0.0f);
              // Increment pivot to change color next time
             iPivot++;

              // Specify the next vertex for the triangle fan
             glVertex2f(x, y);
             }

       // Done drawing fan for cone
       glEnd();

       // Begin a new triangle fan to cover the bottom
        glBegin(GL_TRIANGLE_FAN);

       // Center of fan is at the origin
        glVertex2f(0.0f, 0.0f);
        for(angle = 0.0f; angle < (2.0f*GL_PI); angle += (GL_PI/8.0f))
                {
                // Calculate x and y position of the next vertex
                x = 50.0f*sin(angle);
                y = 50.0f*cos(angle);

               // Alternate color between red and green
               if((iPivot %2) == 0)
                       glColor3f(0.0f, 1.0f, 0.0f);
               else
                       glColor3f(1.0f, 0.0f, 0.0f);

               // Increment pivot to change color next time
               iPivot++;

               // Specify the next vertex for the triangle fan
               glVertex2f(x, y);
               }

        // Done drawing the fan that covers the bottom
        glEnd();
        // Restore transformations
        glPopMatrix();
        // Flush drawing commands
        glFlush();
       }


Previous Table of Contents Next