The three OpenGL routines for modeling transformations are glTranslate*(), glRotate*(), and glScale*(). As you might suspect, these routines transform an object (or coordinate system, if you're thinking of it that way) by moving, rotating, stretching, or shrinking it. All three commands are equivalent to producing an appropriate translation, rotation, or scaling matrix, and then calling glMultMatrix*() with that matrix as the argument. However, these three routines might be faster than using glMultMatrix*(). OpenGL automatically computes the matrices for you; if you're interested in the details, see Appendix G .
In the command summaries that follow, each matrix multiplication is described in terms of what it does to the vertices of a geometric object using the fixed coordinate system approach, and in terms of what it does to the local coordinate system that's attached to an object.
Multiplies the current matrix by a matrix that moves (translates) an object by the given x, y, and z values (or moves the local coordinate system by the same amounts).
Figure 3-5 shows the effect of glTranslatef().
![[IMAGE]](figures/fig3-5.gif)
Figure 3-5 : Translating an Object
Note that using (0.0, 0.0, 0.0) as the argument for glTranslate*() is the identity operation - that is, it has no effect on an object or its local coordinate system.
Multiplies the current matrix by a matrix that rotates an object (or the local coordinate system) in a counterclockwise direction about the ray from the origin through the point (x, y, z). The angle parameter specifies the angle of rotation in degrees.
The effect of glRotatef(45.0, 0.0, 0.0, 1.0), which is a rotation of 45 degrees about the z-axis, is shown in Figure 3-6 .
![[IMAGE]](figures/fig3-6.gif)
Figure 3-6 : Rotating an Object
Note that an object that lies farther from the axis of rotation is more dramatically rotated (has a larger orbit) than an object drawn near the axis. Also, if the angle argument is zero, the glRotate*() command has no effect.
Multiplies the current matrix by a matrix that stretches, shrinks, or reflects an object along the axes. Each x, y, and z coordinate of every point in the object is multiplied by the corresponding argument x, y, or z. With the local coordinate system approach, the local coordinate axes are stretched by the x, y, and z factors, and the associated object is stretched with them.
Figure 3-7 shows the effect of glScalef(2.0, -0.5, 1.0).
![[IMAGE]](figures/fig3-7.gif)
Figure 3-7 : Scaling and Reflecting an Object
glScale*() is the only one of the three modeling transformations that changes the apparent size of an object: Scaling with values greater than 1.0 stretches an object, and using values less than 1.0 shrinks it. Scaling with a -1.0 value reflects an object across an axis. The identity values for scaling are (1.0, 1.0, 1.0). In general, you should limit your use of glScale*() to those cases where it is necessary. Using glScale*() decreases the performance of lighting calculations, because the normal vectors have to be renormalized after transformation.
A scale value of zero collapses all object coordinates along that axis to zero. It's usually not a good idea to do this, because such an operation cannot be undone. Mathematically speaking, the matrix cannot be inverted, and inverse matrices are required for certain lighting operations (see Chapter 6 ). Sometimes collapsing coordinates does make sense, however; the calculation of shadows on a planar surface is a typical application (see "Shadows," ). In general, if a coordinate system is to be collapsed, the projection matrix should be used rather than the modelview matrix.
Example 3-2 is a portion of a program that renders a triangle four times, as shown in Figure 3-8 :
A solid wireframe triangle is drawn with no modeling transformation.
The same triangle is drawn again, but with a dashed line stipple and translated.
A triangle is drawn with a long dashed line stipple, with its height (y-axis) halved and its width (x-axis) doubled.
A rotated, scaled triangle, made of dotted lines, is drawn.
![[IMAGE]](figures/model.gif)
Figure 3-8 : Modeling Transformation Example
Example 3-2 : Using Modeling Transformations: model.c
glLoadIdentity(); glColor3f(1.0, 1.0, 1.0); draw_triangle(); /* solid lines */ glEnable(GL_LINE_STIPPLE); /* dashed lines */ glLineStipple(1, 0xF0F0); glLoadIdentity(); glTranslatef(-20.0, 0.0, 0.0); draw_triangle(); glLineStipple(1, 0xF00F); /*long dashed lines */ glLoadIdentity(); glScalef(1.5, 0.5, 1.0); draw_triangle(); glLineStipple(1, 0x8888); /* dotted lines */ glLoadIdentity(); glRotatef (90.0, 0.0, 0.0, 1.0); draw_triangle (); glDisable (GL_LINE_STIPPLE);
Note the use of glLoadIdentity() to isolate the effects of modeling transformations; initializing the matrix values prevents successive transformations from having a cumulative effect. Even though using glLoadIdentity() repeatedly has the desired effect, it might be inefficient, depending on your particular OpenGL implementation. See "Manipulating the Matrix Stacks" for a better way to isolate transformations.
Sometimes, programmers who want a continuously rotating object attempt to achieve this by repeatedly applying a rotation matrix that has small values. The problem with this technique is that because of round-off errors, the product of thousands of tiny rotations gradually drifts away from the value you really want (it might even become something that isn't a rotation). Instead of using this technique, increment the angle and issue a new rotation command with the new angle at each update step.
OpenGL Programming Guide