Projections and OpenGL
Friday, August 11th, 2006In order to represent 3d objects or scenes in a computer display it is necessary to transform a 3 dimensional space into a bi dimensional space. This is done via projection.
One can see projection as rays being cast from points in the scene into the plane that represents the display, called the projection plane. The direction these rays take determines the projection. If the rays are parallel the projection is called Parallel projection, if they all converge into the viewer’s position it is called a Perspective projection.
The main difference between perspective and parallel projection is the fact that the former is more natural to the human eye. Objects that are farther appear smaller than those who are nearer. In parallel projection all objects retain their sizes no matter how far they are. This view is more practical for technical drawing while perspective projection is more suitable for displaying physical (real or imaginary) worlds.
Parallel projections are subdivided into two categories: Orthographic and Oblique. The former occurs when the direction of the projection rays is perpendicular to the projection plane and the latter otherwise.
OpenGL has a simple way to handle projections. In the graphic pipeline projection occurs at the final stage, after the world and camera transformations. The projection is stored in the projection matrix. In order to manipulate this matrix it is necessary to set it as the current matrix.
glMatrixMode(GL_PROJECTION);
The simplest projection to setup in OpenGL is the orthogonal projection. It is only necessary to define a cube against which the scene will be clipped. This can be accomplished with the glOrtho function.
glOrtho (xmin, xmax, ymin, ymax, zmin, zmax);
These parameters are also known as left, right, bottom, top, near,far.
Perspective projection requires more information to be set. The parameters necessary for perspective are centre of projection,projection direction, up direction and field of view. Remember that in perspective rays are traced in the viewer’s direction so the first three parameters are related to it. If you are familiar with OpenGL you will recognize these parameters as does for the gluLookAt. The field of view is a pair representing the horizontal viewing angle and the vertical viewing angle. These parameters define a frustrum, which is nothing more than a section of a rectangular pyramid with its tip in the centre of projection, and height along the projection direction. Like in ortographic projection there is a function to set up this frustrum called glFrustrum. This function takes the same arguments as glOrtho.
glFrustrum (xmin, xmax, ymin, ymax, zmin, zmax);
To avoid the burden of the calculation of the coordinates of the frustum points, it is possible to use gluPerspective. This function takes the vertical field of view, the aspect ration between the width and height sizes of the view port and the near and far clip planes (zmin and zmax). This function however does not permit asymmetric frustrums.
glPerspective (fov, aspect, near, far);
There is no function to set up an oblique projection in OpenGL. However oblique projection can be accomplished multiplying the projection matrix, after calling glOrtho,with a shear matrix.
float shear_matrix = { 1, 0, -cot(theta), 0,
0, 1, -cot(phi), 0,
0, 0, 1, 0,
0, 0, 0, 0 };
glMultMatrix (shear_matrix);
Where theta is the angle between the x plane and the z plane and phi is the angle between the y plane and the z plane.
For technical drawings orthographic projections should use projection planes parallel to the coordinate system’s axes, in order to prevent foreshortening. Foreshortening is an effect caused by the projections of points that lie on planes that are not parallel to the projection plane. However ther eare cases in which is required to see all axes at the same time. This kind of view is called a pictorial. Although this can produce some results similar to perspective projection, the rays are still cast parallel. These pictorials are produced with axonometric projection.This type of projection always displays an axis in vertical. There are three types of axonometric projections: isometric,dimetric and trimetric.
Axonometric projections are defined by the angles between the projected axes. In an isometric projection all projected axes form the same angle between them, which gives the same amount of foreshortening in all axes. This occurs when the normal of the projection plane, n = (nx,ny, nz), has the same angle between all axes therefore |nx| = |ny| =|nz|. This can be accomplished, for instance, rotating 45º along x and y axes.
A dimetric projection is one that two of the axes have the same angle between them. The normal must have two equal components |nx| = |ny| or |nx| = |nz| or |ny| = |nz|. One possible set up is the rotation of 27.94º in x and 48.5º in y.
In a trimetric projection none of the angles is the same. Any rotation angles can produce this effect.
Pictorals can be achieved in OpenGL manipulating the camera’s position. If dist represents the distance of the camera to the scene, centred at the origin, and camerax, cameray, cameraz its position
camerax = dist * cos (phi) * cos (theta);
cameray = dist * cos (phi) * sin (theta);
cameraz = dist * sin (phi);
Where phi is the rotation along the y axis and theta is the rotation around x axis, places the camera at an axonometric position.
References:
