Even though OpenGL can only draw convex polygons, there’s still a way to create a nonconvex polygon—by arranging two or more convex polygons together. For example, let’s take a four-point star as shown in Figure 6-31. This shape is obviously not convex and thus violates OpenGL’s rules for simple polygon construction. However, the star on the right is composed of six separate triangles, which are legal polygons.
When the polygons are filled, you won’t be able to see any edges and the figure will seem to be a single shape on screen. However, if you use glPolygonMode to switch to an outline drawing, it would be distracting to see all those little triangles making up some larger surface area.
OpenGL provides a special flag called an edge flag for this purpose. By setting and clearing the edge flag as you specify a list of vertices, you inform OpenGL which line segments are considered border lines (lines that go around the border of your shape), and which ones are not (internal lines that shouldn’t be visible). The glEdgeFlag() function takes a single parameter that sets the edge flag to True or False. When set to True, any vertices that follow mark the beginning of a boundary line segment. Listing 6-11 shows an example of this from the STAR example program on the CD.
Listing 6-11 Example usage of glEdgeFlag from the STAR program
// Begin the triangles GlBegin(GL_TRIANGLES); glEdgeFlag(bEdgeFlag); glVertex2f(-20.0f, 0.0f); glEdgeFlag(TRUE); glVertex2f(20.0f, 0.0f); glVertex2f(0.0f, 40.0f); glVertex2f(-20.0f,0.0f); glVertex2f(-60.0f,-20.0f); glEdgeFlag(bEdgeFlag); glVertex2f(-20.0f,-40.0f); glEdgeFlag(TRUE); glVertex2f(-20.0f,-40.0f); glVertex2f(0.0f, -80.0f); glEdgeFlag(bEdgeFlag); glVertex2f(20.0f, -40.0f); glEdgeFlag(TRUE); glVertex2f(20.0f, -40.0f); glVertex2f(60.0f, -20.0f); glEdgeFlag(bEdgeFlag); glVertex2f(20.0f, 0.0f); glEdgeFlag(TRUE); // Center square as two triangles glEdgeFlag(bEdgeFlag); glVertex2f(-20.0f, 0.0f); glVertex2f(-20.0f,-40.0f); glVertex2f(20.0f, 0.0f); glVertex2f(-20.0f,-40.0f); glVertex2f(20.0f, -40.0f); glVertex2f(20.0f, 0.0f); glEdgeFlag(TRUE); // Done drawing Triangles glEnd();
The Boolean variable bEdgeFlag is toggled on and off by a menu option to make the edges appear and disappear. If this flag is True, then all edges are considered boundary edges and will appear when the polygon mode is set to GL_LINES. In Figures 6-32a and 6-32b you can see the output from STAR, showing the wireframe star with and without edges.
We’ve covered a lot of ground in this chapter. At this point you can create your 3D space for rendering, and you know how to draw everything from points and lines to complex polygons. We’ve also shown you how to assemble these two dimensional primitives as the surface of three-dimensional objects.
We encourage you to experiment with what you have learned in this chapter. Use your imagination and create some of your own 3D objects before moving on to the rest of the book. You’ll then have some personal samples to work with and enhance as you learn and explore new techniques throughout the book.