Download The OpenGL Viewing Pipeline

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Linear least squares (mathematics) wikipedia , lookup

Covariance and contravariance of vectors wikipedia , lookup

Determinant wikipedia , lookup

Eigenvalues and eigenvectors wikipedia , lookup

Jordan normal form wikipedia , lookup

Principal component analysis wikipedia , lookup

Matrix (mathematics) wikipedia , lookup

Singular-value decomposition wikipedia , lookup

Rotation matrix wikipedia , lookup

Non-negative matrix factorization wikipedia , lookup

Perron–Frobenius theorem wikipedia , lookup

Orthogonal matrix wikipedia , lookup

Four-vector wikipedia , lookup

Cayley–Hamilton theorem wikipedia , lookup

Gaussian elimination wikipedia , lookup

Matrix calculus wikipedia , lookup

Matrix multiplication wikipedia , lookup

Transcript
The Viewing Pipeline
Adapted from notes by S. L. Abrams
http://deslab.mit.edu/DesignLab/courses/13.016/graphics/overview2.html
The viewing pipeline refers to the actions necessary to process the specified geometric primitives and show
them on the display device. For 2D geometry this is easy. First, we specify the world coordinate window, a
region of the 2D plane in which we have defined the geometry. Next, we define the viewport, the region of
the 2D display screen onto which the world window is mapped. This mapping is potentially comprised of a
translation and a scaling.
For 3D geometry, the viewing pipeline is more complicated and is best explained using the analogy of a
camera. We start with an object and a camera, each of which can move freely in 3D space. We want to fix
the relative positions of the camera and object so that the camera is looking at the object. The camera then
performs a projection, converting the 3D object into a 2D image.



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.
OpenGL provides functions that perform each of these operations.
Mathematically, the transformations are performed by considering each vertex of the geometric primitive as
a vector and multiplying it by a matrix that performs the specific 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. A
separate matrix is provided to perform the projection transformation.
Matrix Manipulation
The various types of transformations that we want to use can be performed mathematically by creating the
appropriate transformation matrix.
Some of the transformations only require a 3x3 matrix, but one transformation, translation, requires a 4x4
matrix. Because it is conceptually easier to understand these graphics operations with a single unified
mathematical model, OpenGL uses a 4x4 matrix for all operations. Also, many display devices can perform
these transformations efficiently using hardware optimized for 4x4 matrix operations.
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
The OpenGL state maintains two separate transformation matrices, the modelview matrix and the projection
matrix.


Modelview
o Translation
o Scaling
o Rotation
Projection
o Orthographic
o Perspective
To specify which matrix you want to modify, use:
glMatrixMode(mode);
where mode is either GL_MODELVIEW or GL_PROJECTION.
The current value of the selected matrix can be initialized by:
glLoadIdentity();
which sets the matrix to the 4x4 identity matrix.
M=I= 1000
0100
0010
0001
Recall that v = Iv.
To replace the current matrix C with a completely new matrix M:
float m[16];
glLoadMatrixf(m);
/* or double m[16]; */
/* or glLoadMatrixd(m); */
C' = M
You can multiply a new matrix M onto the current matrix C:
float m[16];
glMultMatrixf(m);
/* or double m[16]; */
/* or glMultMatrixd(m); */
C' = CM
Note that the order of matrix multiplication is important, and in general, does not commute, i.e. CM != MC. In
OpenGL, new matrices M are always multiplied onto the current matrix C from the right.
The current matrix can be saved and restored by pushing to or popping from the matrix stack:
glPushMatrix();
glPopMatrix();
/* save the current matrix on the stack */
/* restore the current matrix from the stack */
To receive a copy of the current matrix, use the following functions:
float matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);
glGetFloatv(GL_PROJECTION, matrix);
Translation
glTranslate{fd}(a, b, c);
C' = CT
where
T= 100a
010b
001c
0001
(x+a, y+b, z+c, 1) = T (x, y, z, 1)
Scaling
glScale{fd}(a, b, c);
C' = CS
where
S= a000
0b00
00c0
0001
(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
0
0
0001
M
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
0 0
0
1
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
0
0
0
1
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
0
0
0
1
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.
double eyeX, eyeY, eyeZ;
/*
double referX, referY, referZ;
/*
double upX, upY, upZ;
/*
gluLookAt(eyeX, eyeY, eyeZ, referX,
viewpoint */
reference point */
view up vector */
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.
The view up vector is necessary to correctly orient the viewing with regard to rotation about the viewing
direction. The coordinate system defined with the its origin at the viewpoint, its Z-axis pointing from the
viewpoint to the reference point, its Y-axis in the direction of the view up vector, and its X-axis as necessary
to complete a right handed system, is called the eye coordinate system.
Projection Transformations
OpenGL provides two types of projection transformations: orthographic and perspective. Each of these
transformation defines a volume of space called a frustum. Only geometry that is inside of the frusum is
displayed on the screen; any portion of geometry that is outside of the frustum is clipped.



Orthographic
double left, right, bottom, top, near, far;
glOrtho(left, right, bottom, top, near, far);
which defines a rectangular parallelpiped 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 Zaxis 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
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.
Building the Pipeline
Because all of the transformation matrices are mutliplied 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, and M is the modelview matrix. Since the modelview matrix can be though
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.
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);
glLoadIdentity();
gluPerspective(...);
/* specify the projection matrix */
/* initialize to identity */
/* or glOrtho(...) */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...);
/* specify the modelview matrix */
/* initialize to identity */
/* specify viewing transformation */
glTranslate(...);
glScale(...);
glRotate(...);
...
/* modeling transformations, */
/* as necessary */