Open GL Super Bible

Previous Table of Contents Next


Chapter 18
Polygon Tessellation

What you’ll learn in this chapter:

How to… Functions You’ll Use

Use the OpenGL Utility library to draw complex polygons gluBegin/gluEnd
Use the OpenGL Utility library to draw complex surfaces gluNextContour

The OpenGL Utility library (glu32.lib) includes a robust polygon tessellation interface that can handle rendering of complex polygons and surfaces. What is tessellation, you ask? According to the American Heritage Dictionary:

tes·sel·late verb, transitive
tes·sel·lat·ed, tes·sel·lat·ing, tes·sel·lates

To form into a mosaic pattern, as by using small squares of stone or glass.

te[sacute] sel·la tion noun1

A computer graphics tessellator takes one or more connected sets of points and forms a series of polygons that fill to form the described shape. In place of stone and glass, it uses triangles and pixels. A polygon tessellator is specially designed to manage the drawing of polygons that have unusual attributes such as holes.

Complex Polygons

What makes polygons complex? Well, in OpenGL a complex polygon is one that is either concave (the polygon contains a “dent”) or has holes in it. Figure 18-1 contains some simple and complex polygons that you may need to render at some time.


Figure 18-1  Simple and complex polygons

OpenGL’s GL_POLYGON primitive can only render simple, convex polygons. A polygon is convex if no point lies inside a line between any two vertices. That is, if you can draw a line between two vertices of a polygon and the line goes into empty space outside the polygon edge, the polygon is not convex; it is concave or complex.

Concave polygons are nonconvex polygons that have no unfilled holes in their interiors. The top-right polygon in Figure 18-1 is concave, but the one below it is not because it contains a hole in the middle of the filled area.

Complex polygons have holes or twists in them. The lower-right polygon in Figure 18-1 is complex.

Drawing Concave Polygons

Drawing concave polygons with the glu is not difficult. The first thing you must do is create a tessellator object, as shown here:

GLUtriangulatorObj *tess;

tess = gluNewTess();

The GLUtriangulatorObj structure contains state information that is used by the tessellator to render the polygon.

Next, you call a sequence of gluBeginPolygon, gluTessVertex, and gluEndPolygon to render the polygon:

GLdouble vertices[100][3];

gluBeginPolygon(tess);
  gluTessVertex(tess, vertices[0], NULL);
  gluTessVertex(tess, vertices[1], NULL);
  …
  gluTessVertex(tess, vertices[99], NULL);
gluEndPolygon(tess);

After the gluEndPolygon call, the tessellator does its work and generates a series of triangles, triangle strips, and triangle fans. Because this process can take a long time, it’s a good idea to put tessellated polygons into display lists to improve display performance (see Chapter 10).

Drawing Complex Polygons

Drawing complex polygons is a little more involved than for concave polygons but is not as hard as it would seem. Complex polygons can have holes and twists in them, so the gluNextContour function is provided to identify the type of path you are defining. Table 18-1 lists the path types for gluNextContour.

Table 18-1 gluNextContour Path Types

Path Type Description

GLU_EXTERIOR The path lies on the exterior of the polygon.
GLU_INTERIOR The path lies on the interior of the polygon (hole).
GLU_UNKNOWN You don’t know what the path is; the library will attempt to figure it out.
GLU_CCW This should only be used once and defines that counterclockwise paths are exterior paths and clockwise ones are interior.
GLU_CW This should only be used once and defines that counterclockwise paths are exterior paths and clockwise ones are interior.

For the example shown in Figure 18-2, we will define an exterior path for the outline, and an interior path for the triangular hole in the middle (see Figure 18-3).


Figure 18-2  The letter A as a complex polygon


Figure 18-3  Polygon paths for the letter A

To draw the letter A, we call gluNextContour only once before providing the interior points. The example in Listing 18-1, LETTER.C, uses this code to display a rotating A.

tess = gluNewTess();
gluBeginPolygon(tess);
  gluTessVertex(tess, outside[0], outside[0]);
  gluTessVertex(tess, outside[1], outside[1]);
  gluTessVertex(tess, outside[2], outside[2]);
  gluTessVertex(tess, outside[3], outside[3]);
  gluTessVertex(tess, outside[4], outside[4]);
  gluTessVertex(tess, outside[5], outside[5]);
  gluTessVertex(tess, outside[6], outside[6]);
gluNextContour(tess, GLU_INTERIOR);
  gluTessVertex(tess, inside[0], inside[0]);
  gluTessVertex(tess, inside[1], inside[1]);
  gluTessVertex(tess, inside[2], inside[2]);
gluEndPolygon(tess);
gluDeleteTess(tess);


Previous Table of Contents Next