Quantcast
Channel: Handouts – Staging Area
Viewing all articles
Browse latest Browse all 20

OpenGL Transformations

$
0
0

There are three basic transformations in OpenGL:

  • Scale (changing the size of an object)
  • Translate (moving an object to another location relative to where it started)
  • Rotate (rotating an object around a particular axis through the origin of the model)

The actual method calls for each of these transformations is fairly straightforward:

gl.glScaled(double xScale, double yScale, double zScale);
gl.glTranslated(double xTranslation, double yTranslation, double zTranslation);
gl.glRotated(double degrees, double x, double y, double z);

It is worth mentioning that in each of these method calls, the method ends in a D not because it is in the past tense, but because there are several variations of each of these methods, and the one we will use expects doubles as parameters (as opposed to glRotatef, which expects floats). Presumably glScaled() and glTranslated() are fairly self-evident: the object is either stretched by a particular factor or shifted by a particular factor along each of the axes — and it could be a different factor for each axis.

glRotated() requires further explanation. glRotated() operates on what is colloquially referred to as the “Right Hand Rule”.

http://www.flickr.com/photos/globetrotter1937/1557776175/

Imagine that your hand is placed with the base of the palm at the origin. The (x, y, z) coordinates specified by glRotated() are at the tip of your thumb. The line from the origin (your palm) to that point (your thumb) defines the axis of rotation — the pole about which the rotation will be performed — nota bene that the axis of rotation will always pass through the origin. Your fingers then define the direction of rotation around that axis. And the number of degrees is, well, the number of degrees that you will rotate the object.

The order of transformations is critical. Applying transformations in different orders will have noticeably different effects. The best way to think of the situation that the objects being modeled are passing through a filter, the transformation matrix. Each time a new transformation is applied, the filter is adjusted slightly. A rotation followed by a translation will first rotate the object and then translate it into a new position. A translation followed by a rotation will first move the object into its new position and then rotate the object — from its new position — around the axis of rotation at the origin — causing a planet-like orbit about the origin.

Because this filter is adjusted by each transformation applied, all transformations apply to any objects drawn after the transformations apply — the objects always pass through the transformation matrix on their way to being drawn on-screen, and each transformation we apply adjusts the transformation matrix. There is only one transformation matrix. All objects pass through it. The only question is: when do they pass through it? Before or after a particular adjustment?

gl.glRotated(90, 0, 1, 0); // rotate 90 degrees around the positive y-axis
glut.glutWireTeapot(1.0); // the teapot is rotated
gl.glTranslated(10, 0, 0); // translate 10 units along the positive x-axis
glut.glutWireTetrahedron; // the tetrahedron is translated and then rotated
gl.glScaled(1, 1, 3); // scale, leaving x- and y-axes unchanged, but triple z
glut.glutWireIcosahedron(); // the icosahedron is scaled, translated and then rotated

Note that something strange happens to the order of the transformations — the objects are passed through the most recent transformations first, moving backward in through all of the transformations applied. A quick way to figure out what order the transformations will be applied to a particular object is start at that object and run a finger up the lines of code. The order in which the transformations are encountered is the order in which they will be applied to the object.

Suppose we don’t want every transformation to apply to every object? It would be nice to apply a transformation and then unapply it. We can do this: we save the transformation matrix in its pre-alteration state, apply a new transformation (or two or three…), draw our object, and then revert back to the version that we saved earlier.

gl.glPushMatrix(); // save current state of transformation matrix
{
    gl.glRotated(90, 0, 1, 0); // rotate 90 degrees around the positive y-axis
    glut.glutWireTeapot(1.0); // the teapot is rotated
}
gl.glPopMatrix(); // revert to saved version of transformation matrix

gl.glPushMatrix(); // save transformation matrix (again)
{
    gl.glTranslated(10, 0, 0); // translate 10 units along the positive x-axis
    glut.glutWireTetrahedron; // the tetrahedron is ONLY translated
}
gl.glPopMatrix(); // revert to saved (again)

gl.glPushMatrix(); // save the transformation matrix a last time
{
    gl.glScaled(1, 1, 3); // scale, leaving x- and y-axes unchanged, but triple z
    glut.glutWireIcosahedron(); // the icosahedron is ONLY scaled
}
gl.glPopMatrix(); // reverto saved a last time

// anything that follows will be unaffected by our transformations!

Viewing all articles
Browse latest Browse all 20

Trending Articles