## Describing Points, Lines, and PolygonsThis section explains how to describe OpenGL geometric primitives.
All geometric primitives are eventually described in terms of their ## What Are Points, Lines, and Polygons?You probably have a fairly good idea of what a mathematician
means by the terms One difference comes from the limitations of computer-based calculations. In any OpenGL implementation, floating-point calculations are of finite precision, and they have round-off errors. Consequently, the coordinates of OpenGL points, lines, and polygons suffer from the same problems. Another more important difference arises from the limitations of a raster graphics display. On such a display, the smallest displayable unit is a pixel, and although pixels might be less than 1/100 of an inch wide, they are still much larger than the mathematician's concepts of infinitely small (for points) or infinitely thin (for lines). When OpenGL performs calculations, it assumes points are represented as vectors of floating-point numbers. However, a point is typically (but not always) drawn as a single pixel, and many different points with slightly different coordinates could be drawn by OpenGL on the same pixel. ## PointsA point is represented by a set of floating-point numbers
called a vertex. All internal calculations are done as if vertices are three-dimensional.
Vertices specified by the user as two-dimensional (that is, with only
OpenGL works in the homogeneous coordinates of three-dimensional
projective geometry, so for internal calculations, all vertices are represented
with four floating-point coordinates ( w coordinate in OpenGL commands,
but that's rarely done. If the w coordinate isn't specified, it's
understood to be 1.0. (See Appendix F for more information about homogeneous coordinate systems.) ## LinesIn OpenGL, the term
## PolygonsPolygons are the areas enclosed by single closed loops of line segments, where the line segments are specified by the vertices at their endpoints. Polygons are typically drawn with the pixels in the interior filled in, but you can also draw them as outlines or a set of points. (See "Polygon Details.") In general, polygons can be complicated, so OpenGL makes some
strong restrictions on what constitutes a primitive polygon. First, the edges
of OpenGL polygons can't intersect (a mathematician would call a polygon satisfying
this condition a
The reason for the OpenGL restrictions on valid polygon types is that it's simpler to provide fast polygon-rendering hardware for that restricted class of polygons. Simple polygons can be rendered quickly. The difficult cases are hard to detect quickly. So for maximum performance, OpenGL crosses its fingers and assumes the polygons are simple. Many real-world surfaces consist of nonsimple polygons, nonconvex polygons, or polygons with holes. Since all such polygons can be formed from unions of simple convex polygons, some routines to build more complex objects are provided in the GLU library. These routines take complex descriptions and tessellate them, or break them down into groups of the simpler OpenGL polygons that can then be rendered. (See "Polygon Tessellation" in Chapter 11 for more information about the tessellation routines.) Since OpenGL vertices are always three-dimensional, the points
forming the boundary of a particular polygon don't necessarily lie on the same
plane in space. (Of course, they do in many cases - if all the
## RectanglesSince rectangles are so common in graphics applications, OpenGL
provides a filled-rectangle drawing primitive,
void glRect{sifd}v(TYPE*v1, TYPE*v2);
Note that although the rectangle begins with a particular
orientation in three-dimensional space (in the ## Curves and Curved SurfacesAny smoothly curved line or surface can be approximated - to any arbitrary degree of accuracy - by short line segments or small polygonal regions. Thus, subdividing curved lines and surfaces sufficiently and then approximating them with straight line segments or flat polygons makes them appear curved (see Figure 2-5). If you're skeptical that this really works, imagine subdividing until each line segment or polygon is so tiny that it's smaller than a pixel on the screen.
Even though curves aren't geometric primitives, OpenGL does provide some direct support for subdividing and drawing them. (See Chapter 12 for information about how to draw curves and curved surfaces.) ## Specifying VerticesWith OpenGL, all geometric objects are ultimately described
as an ordered set of vertices. You use the
Example 2-2 provides some examples of using
`glVertex2s(2, 3); `
`glVertex3d(0.0, 0.0, 3.1415926535898); `
`glVertex4f(2.3, 1.0, -2.2, 2.0); `
` `
`GLdouble dvect[3] = {5.0, 9.0, 1992.0};`
`glVertex3dv(dvect);`
The first example represents a vertex with three-dimensional
coordinates (2, 3, 0). (Remember that if it isn't specified, the On some machines, the vector form of ## OpenGL Geometric Drawing PrimitivesNow that you've seen how to specify vertices, you still need
to know how to tell OpenGL to create a set of points, a line, or a polygon from
those vertices. To do this, you bracket each set of vertices between a call
to
`glBegin(GL_POLYGON);`
` glVertex2f(0.0, 0.0);`
` glVertex2f(0.0, 3.0);`
` glVertex2f(4.0, 3.0);`
` glVertex2f(6.0, 1.5);`
` glVertex2f(4.0, 0.0);`
`glEnd();`
If you had used GL_POINTS instead of GL_POLYGON, the primitive
would have been simply the five points shown in Figure 2-6. Table 2-2 in the following function summary for
.
Figure 2-7 shows examples of all the geometric primitives listed in Table 2-2. The paragraphs that follow the figure describe the pixels that are drawn for each of the objects. Note that in addition to points, several types of lines and polygons are defined. Obviously, you can find many ways to draw the same primitive. The method you choose depends on your vertex data.
As you read the following descriptions, assume that
## Restrictions on Using glBegin() and glEnd()The most important information about vertices is their coordinates,
which are specified by the
No other OpenGL commands are valid between a Note, however, that only OpenGL commands are restricted; you
can certainly include other programming-language constructs (except for calls,
such as the aforementioned
`#define PI 3.1415926535898 `
`GLint circle_points = 100; `
`glBegin(GL_LINE_LOOP); `
for (i = 0; i < circle_points; i++) { ` angle = 2*PI*i/circle_points;`
` glVertex2f(cos(angle), sin(angle));`
`} `
`glEnd();`
Unless they are being compiled into a display list, all Although many commands are allowed between `glBegin(GL_POINTS); `
` glColor3f(0.0, 1.0, 0.0); /* green */`
` glColor3f(1.0, 0.0, 0.0); /* red */`
` glVertex(…);`
` glColor3f(1.0, 1.0, 0.0); /* yellow */`
` glColor3f(0.0, 0.0, 1.0); /* blue */`
` glVertex(…);`
` glVertex(…);`
`glEnd();`
You can use any combination of the 24 versions of the |