The Viewing Pipeline adaptation of Paul Bunn & Kerryn Hugo s notes What is it? The viewing pipeline is the procession of operations that are applied to the OpenGL matrices, in order to create a 2D representation from 3D geometry. These processes can be broken up into three major areas: The movement of the object is called a modeling transformation. The movement of the camera is called a viewing transformation. The conversion from 3D to 2D is called a projection transformation. The Modeling Transformation The modeling transformations are those such as gltranslate (), glrotatef () and glscalef (), which dictate the movement of the object in local coordinates. These operations are applied to the modelview matrix, as opposed to the projection matrix. To begin transformation of this matrix, we need to specify it in the matrix mode function, then initialize the matrix to the Identity matrix, and perform your transformations thereafter: glmatrixmode(gl_modelview); glloadidentity(); glpushmatrix(); //store current matrix glrotate{f,d}(f/d,x,y,z); gltranslate{fd}(a, b, c); glscale{f/d}(a, b, c); glpopmatrix(); //restore current matrix
Because all coordinates are stored as 4D values, we can manipulate the coordinates with the 4x4 transformation matrix. For a homogeneous coordinate v and a matrix M: v' = Mv, where M is the modified ModelView matrix. Translation gltranslate{fd}(a, b, c); C' = CT, where T= 1 0 0 a 0 1 0 b 0 0 1 c (x+a, y+b, z+c, 1) = T (x, y, z, 1) Scaling glscale{fd}(a, b, c); C' = CS, where S = a 0 0 0 0 b 0 0 0 0 c 0 (xa, yb, zc, 1) = S (x, y, z, 1) Note that scaling is performed relative to the origin of the current coordinate system. Rotation glrotate{fd}(a, x, y, z); where a is the (right-handed) rotation angle, given in degrees, and (x, y, z) define the axis of rotation. C' = CR, where R = 0 M 0 0 where M is a general 3x3 rotation matrix. Note the following three special cases of rotation about the coordinate axes. Rotation about the x-axis glrotatef(a, 1.0, 0.0, 0.0); R = 1 0 0 0 0 cos(a) -sin(a) 0 0 sin(a) cos(a) 0
Rotation about the y-axis glrotatef(a, 0.0, 1.0, 0.0); R = cos(a) 0 sin(a) 0 0 1 0 0 -sin(a) 0 cos(a) 0 Rotation about the z-axis glrotatef(a, 0.0, 0.0, 1.0); R = cos(a) -sin(a) 0 0 sin(a) cos(a) 0 0 0 0 1 0 Like scaling, rotation is performed relative to the origin of the current coordinate system. Viewing Transformations The default OpenGL viewpoint is located at the origin, looking down the negative Z- axis. The geometry that we wish to view must either by moved to a position from which it can be seen from the default viewpoint, or the viewpoint must be moved so that it can see the geometry. Note that the modeling and viewing transformations have an inverse relationship: rotating the model geometry in a positive direction about the X-axis is equivalent to rotating the viewpoint in a negative direction about the X-axis. It is possible to build a viewing transformation by concatenating a series of translations and rotations, however, this can be quite complex. Instead, OpenGL provides a simplified function to define the transformation. Note that although the modeling and viewing transformations can be considered logically separate operations, OpenGL concatenates all of the modeling and viewing transformations into a single matrix (i.e. the ModelView Matrix). A separate matrix is provided to perform the projection transformation. double eyex, eyey, eyez; /* viewpoint */ double referx, refery, referz; /* reference point */ double upx, upy, upz; /* view up vector */
glulookat(eyex, eyey, eyez, referx, refery, referz, upx, upy, upz); where (eyex,eyey,eyez) is the viewpoint, (referx,refery,referz) is a point along the desired line of sight (if the point is at the center of the scene being looked at, it is usually referred to as the reference point), and (upx,upy,upz) is the view up vector. How To Move The Camera Supposing the eye point is fixed: To pan the camera (like shaking your head left and right): Move the reference point horizontally. To tilt the camera (like nodding your head up and down): Move the reference point vertically. To rock the camera (like tilting your head left and right): Let the eye point to the reference point be the normal vector of a plane A; change the direction of the up vector so that it s projection onto A rotates left and right. Projection Transformations OpenGL provides two types of projection transformations: orthographic and perspective. Each of these transformations defines a volume of space called a frustum. Only geometry that is inside of the frustum is displayed on the screen; any portion of geometry that is outside of the frustum is clipped. Orthographic Projection Given by: double left, right, bottom, top, near, far; glortho(left, right, bottom, top, near, far); which defines a rectangular parallelepiped frustum. An orthographic projection projects a 3D point v onto the 2D near clipping plane (sometimes called the picture plane) by constructing a ray through v that is parallel to the viewing direction, i.e. the Z-axis in the eye coordinate system. The (x,y) position on the picture plane where the ray intersects the plane is the 2D projection of v. In other words, if v is expressed in the eye coordinate system as (x,y,z), then the orthographic projection is (x,y).
Perspective Projection Given by: double fov, aspect, near, far; gluperspective(fov, aspect, near, far); which defines a truncated pyramid frustum. A perspective projection projects a 3D point v onto the 2D picture plane by constructing a ray through v that passes through the viewpoint direction, i.e. the origin of the eye coordinate system. The (x,y) position on the picture plane where the ray intersects the plane is the 2D projection of v. In other words, if v is expressed in the eye coordinate system as (x,y,z), then the perspective projection is (near*x/z, near*y/z). Perspective projection produces images that appear more realistic; it more closely mimics the operation of the human eye. This perspective projection can also be achieved by the OpenGL command glufrustum (), which can be used to mimic the behavior of gluperspective (). The frustum command has the added functionality of being able to accommodate off-axis projections, whereas gluperspective only produces symmetrical / on-axis projections (Please look at Kerryn s notes for more info on this function). Building the Pipeline Because all of the transformation matrices are multiplied on the right: C' = CM And the multiplication of a vertex coordinate with the transformation matrices also occurs on the right: v' = Cv The matrix that is farthest to the right is applied to the vertex first.
We can represent the viewing pipeline as follows: v' = PMv Where P is the projection matrix (orthographic / perspective transformations) and M is the modelview matrix (modeling and viewing transformations). Since the modelview matrix can be thought of logically as separate viewing and modeling transformations: v' = PVMv where V is the viewing matrix and M is the modeling matrix. Note that first we apply the modeling transformation to orient the geometric model, then we apply the viewing transformation to define the eye coordinate system, and finally we perform the projection from 3D to 2D. The 2D picture plane forms the world coordinate window, which can be mapped to the screen viewport. The viewport can hence be used to stretch the 2D scene if necessary (i.e. W/H ratio of window can be 2x W/H ratio of world window): Since the order of the transformations is significant, we want to invoke the OpenGL functions is the proper order, i.e. in the reverse order in which they will be applied. glviewport(...); /* screen viewport */ glmatrixmode(gl_projection); /* specify the projection matrix */ glloadidentity(); /* initialize to identity */ gluperspective(...); /* or glortho(...) */ glmatrixmode(gl_modelview); /* specify the modelview matrix */ glloadidentity(); /* initialize to identity */ glulookat(...); /* specify viewing transformation */ gltranslate(...); /* modeling transformations, */ glscale(...); /* as necessary */ glrotate(...);...