* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download The OpenGL Viewing Pipeline
Survey
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
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 */