Setting Up Your Coordinate System
In Chapter 1, we introduced the two kinds of projections that we most often use in 3D graphics (orthographic and perspective). These projections, or types of coordinate systems, are really just a specially formed 4 x 4 transformation matrix. These and other types of matrices are the topic of the next chapter, so we don't want to get lost in the details too soon here. Suffice it to say, you need a projection matrix of one of these types to render geometry in the appropriate coordinate system. If you do not use one of these matrices, you get a default orthographic projection where the axes range only from -1.0 to 1.0. Our example programs in Chapter 2, "Getting Started," made use of this coordinate system, and this was useful given that all three of the sample programs were essentially 2D. For this chapter, however, we want to begin to move on a bit.
The Math3d library that is part of GLTools contains functions that construct different kinds of matrices for you, and you learn to use and apply them in Chapter 4. For this chapter, we use the GLFrustum class as a container for our projection matrix.
Typically, we use orthographic projections for 2D drawings, and we keep the z coordinate at 0.0 for our geometry. The z-axis, however, can extend to any length we want. Figure 3.2 shows an example orthographic projection that stretches -100 to +100 in all three directions. This viewing volume as it is sometimes called will contain all of your geometry. If you specify geometry outside the viewing volume, it is clipped, meaning it is literally cut along the boundary of the viewing volume. In an orthographic projection everything that falls within this space is displayed on-screen, and there is really no concept of a camera or eye coordinate system. To set this up, we call the GLFrustum method, SetOrthographic.
GLFrustum::SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax);
Figure 3.2 A Cartesian viewing volume measuring 200 x 200 x 200.
A perspective projection performs perspective division to shorten and shrink objects that are farther away from the viewer. The width of the back of the viewing volume does not have the same measurements as the front of the viewing volume after being projected to the screen. Thus, an object of the same logical dimensions appears larger at the front of the viewing volume than if it were drawn at the back of the viewing volume. Figure 3.3 shows an example of a geometric shape called a frustum. A frustum is a truncated section of a pyramid viewed from the narrow end to the broad end, with the viewer back some distance from the narrow end.
Figure 3.3 A perspective projection defined by a frustum.
The GLFrustum class constructs a frustum for you with the function SetPerspective.
GLFrustum::SetPerspective(float fFov, float fAspect, float fNear, float fFar);
The parameters are the field-of-view angle in the vertical direction, the aspect ratio of the width to the height of your window, and the distances to the near and far clipping planes (see Figure 3.4). You find the aspect ratio by dividing the width (w) by the height (h) of the window or viewport.
Figure 3.4 The frustum as defined by the GLFrustum class's SetPerspective method.