Open GL Super Bible

Previous Table of Contents Next


Listing 6-9 shows the code used to store this pattern. Each row of the array represents a row from Figure 6-26. The first row in the array is the last row of the figure, and so on, up to the last row of the array and the first row of the figure.

Listing 6-9 The mask definition for the campfire in Figure 6-26

// Bitmap of camp fire
GLubyte fire[] = { 0x00, 0x00, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0x00,
                                       0x00, 0x00, 0x00, 0xc0,
                                       0x00, 0x00, 0x01, 0xf0,
                                       0x00, 0x00, 0x07, 0xf0,
                                       0x0f, 0x00, 0x1f, 0xe0,
                                       0x1f, 0x80, 0x1f, 0xc0,
                                       0x0f, 0xc0, 0x3f, 0x80,
                                       0x07, 0xe0, 0x7e, 0x00,
                                       0x03, 0xf0, 0xff, 0x80,
                                       0x03, 0xf5, 0xff, 0xe0,
                                       0x07, 0xfd, 0xff, 0xf8,
                                       0x1f, 0xfc, 0xff, 0xe8,
                                       0xff, 0xe3, 0xbf, 0x70,
                                       0xde, 0x80, 0xb7, 0x00,
                                       0x71, 0x10, 0x4a, 0x80,
                                       0x03, 0x10, 0x4e, 0x40,
                                       0x02, 0x88, 0x8c, 0x20,
                                       0x05, 0x05, 0x04, 0x40,
                                       0x02, 0x82, 0x14, 0x40,
                                       0x02, 0x40, 0x10, 0x80,
                                       0x02, 0x64, 0x1a, 0x80,
                                       0x00, 0x92, 0x29, 0x00,
                                       0x00, 0xb0, 0x48, 0x00,
                                       0x00, 0xc8, 0x90, 0x00,
                                       0x00, 0x85, 0x10, 0x00,
                                       0x00, 0x03, 0x00, 0x00,
                                       0x00, 0x00, 0x10, 0x00};


Suggestion: Come Back Later
If you are still uncertain about how this campfire bitmap is stored and interpreted, we suggest you come back and reread this material after you’ve finished Chapter 11, “Raster Graphics in OpenGL.”

To make use of this stipple pattern, we must first enable polygon stippling and then specify this pattern as the stipple pattern. The PSTIPPLE example program does this, and then draws a hexagon (stop sign) using the stipple pattern. Listing 6-10 is the pertinent code, and Figure 6-27 shows the output from PSTIPPLE.

Listing 6-10 Code from PSTIPPLE that draws a stippled hexagon

// 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 red
        glColor3f(1.0f, 0.0f, 0.0f);

        // Enable polygon stippling
        glEnable(GL_POLYGON_STIPPLE);

        // Specify a specific stipple pattern
        glPolygonStipple(fire);
        }

// Called to draw scene
void RenderScene(void)
        {
        // Clear the window
        glClear(GL_COLOR_BUFFER_BIT);

        …
        …

        // Begin the stop sign shape,
        // use a standard polygon for simplicity
        glBegin(GL_POLYGON);
                glVertex2f(-20.0f, 50.0f);
                glVertex2f(20.0f, 50.0f);
                glVertex2f(50.0f, 20.0f);
                glVertex2f(50.0f, -20.0f);
                glVertex2f(20.0f, -50.0f);
                glVertex2f(-20.0f, -50.0f);
                glVertex2f(-50.0f, -20.0f);
                glVertex2f(-50.0f, 20.0f);
        glEnd();

        …
        …

        // Flush drawing commands
        glFlush();
       }


Figure 6-27  Output from the PSTIPPLE program

Figure 6-28 shows the hexagon rotated somewhat. You’ll notice that the stipple pattern is still used, but the pattern is not rotated with the polygon. That’s because the stipple pattern is only used for simple polygon filling on screen. If you need to map a bitmap to a polygon so that it mimics the polygon’s surface, you will have to use texture mapping (Chapter 12).


Figure 6-28  PSTIPPLE output with the polygon rotated, showing that the stipple pattern is not rotated

Polygon Construction Rules

When you are using many polygons to construct a complex surface, you’ll need to remember two important rules.

The first rule is that all polygons must be planar. That is, all the vertices of the polygon must lie in a single plane, as illustrated in Figure 6-29. The polygon cannot twist or bend in space.


Figure 6-29  Planar vs. nonplanar polygons

Here is yet another good reason to use triangles. No triangle can ever be twisted so that all three points do not line up in a plane, because mathematically it only takes three points to define a plane. (So if you can plot an invalid triangle, aside from winding it in the wrong direction, the Nobel Prize committee may just be looking for you!)

The second rule of polygon construction is that the polygon’s edges must not intersect, and the polygon must be convex. A polygon intersects itself if any two of its lines cross. “Convex” means that the polygon cannot have any indentions. A more rigorous test of a convex polygon is to draw some lines through it. If any given line enters and leaves the polygon more than once, then the polygon is not convex. Figure 6-30 gives examples of good and bad polygons.


Figure 6-30  Some valid and invalid primitive polygons


Why the Limitations on Polygons?
You may be wondering why OpenGL places the restrictions on polygon construction. Handling polygons can become quite complex, and OpenGL’s restrictions allow it to use very fast algorithms for the rendering of these polygons. We predict that you’ll not find these restrictions burdensome, and that you’ll be able to build any shapes or objects you need using the existing primitives. (And you can use GL_LINES to draw an otherwise illegal shape, too.)


Previous Table of Contents Next