ArticleDirectory
 Preface
 I. 3D mathematical history
 2. Matrix Transformation
 3. Implementation in OpenGL
 Iv. Projection Transformation
 5. View Transformation
 Vi. Postscript
 7. Reference
[OpenGL ES 03] 3D Transformation: model, view, projection, and viewport
Luo chaohui (http://www.cnblogs.com/kesalin)
This article follows the "signaturenoncommercial useconsistency" creation public agreement
Preface
I was planning to write tutorial 04 directly, but thinking of 3D transformation involves a lot of mathematical knowledge, which is often a obstacle for many beginners (such as myself ). In addition, OpenGL ES 2.0 no longer provides some heavyweight functions related to 3D transformations in OpenGL ES 1.0, such as glmatrixmode (gl_projection), glmatrixmode (gl_modelview), glloadmatrixf, and glmultmatrix, these functions must be implemented by ourselves in OpenGL ES 2.0. Without a brief introduction to linear algebra and ry, it may be difficult for many people to understand why some steps in this article are required. Therefore, this article will give up its original plan to introduce some knowledge about 3D mathematics and 3D transformation. BTW, originally plannedCodeThe example has been written. If you are interested, you can browse it first and put the code here. The running effect is as follows:
I. 3D mathematical history
We have all learned ry. We should all know that Euclidean (Greek mathematician in the third century BC), the originator of this ry, was the one who created the Euclidean ry. He proposed based on X, Y, the concept of threedimensional space in Zaxis. In the 17th century, there was another great ox Descartes. The Cartesian coordinate we usually call is his creation. The Cartesian coordinate perfectly associates the Euclidean geometric theory with the Representative mathematics. Only with Cartesian coordinates can we simply useMatrix)To represent 3D transformations. However, a matrix is used to represent an unsolved problem in 3D transformation operationsUniversal Joint lock. What is a universal joint lock? Simply put, the two axes are rotated to the same direction, and the two axes are parallel, so one dimension is less than the original one (For details, refer to here ). After more than one hundred years, Hamilton (Sir William Rowan Hamilton) created(Quaternion)It solves the problem of universal joint lock caused by rotation, and there is another use of the Quaternary element, but it is mainly used to deal with the Rotation Problem in 3D mathematics.
Okay, maybe you have a bit of fog. It doesn't matter. You just need to know:A matrix is used to represent 3D transformations. However, when a matrix is used to represent rotation, the universal joint lock may occur. The use of the Quaternary element can avoid the universal joint lock.You can.
2. Matrix Transformation
As mentioned above, matrix can be used to represent 3D transformation operations. How can a transformation be implemented through matrix? Next, let's talk about this. Here I recommend a 3D mathematics getting started book: 3D mathematical basics: graphics and Game Development
We usually use a 4dimensional vector (X, Y, Z, W) to represent a point in 3D space, and the last onedimensional W to represent homogeneous coordinates. Homogeneous coordinates mean that two parallel lines intersect at a point in the infinite distance of the projection plane, but they do not represent infinity in the matrix, so the homogeneous coordinates are added. As you can imagine, the two sides of a train track appear to be at one point in an infinite distance. For details about the homogeneous coordinates, refer to this article.
Matrix calculation rules:
1) if matrix A and B are not reciprocal matrices, the multiplication exchange law is not satisfied, that is, a × B is not equal to B ×;
2) a matrix of order m x n can only be multiplied by a matrix of order n x O, that is, the Order N is equal, and the result is a matrix of order m x O;
3) The calculation process of matrix A × B is that each row of A is multiplied by each column of B as a row in the result matrix;
4) the inverse matrix B of matrix A satisfies the requirements of a × B = B × A = unit matrix.
5) The Matrix of units is 1 on the diagonal line, and the rest are 0 matrices. The unit matrix does not affect Coordinate Transformation (you can replace the following 3D transformation matrix with the unit matrix ).
When an object in a 3D space is projected onto a 2D plane, the homogeneous coordinates are used. Therefore, a matrix of 4 × 4 is used to represent the transformation. InProgramming LanguageSuch a matrix can be represented by a 16dimensional array or a 4 × 4 twodimensional array. Because matrix multiplication does not meet the multiplication exchange law, array representation of matrix can be divided into two forms: the primary order of the row and the Primary Order of the column. They are essentially equivalent, it is only a right multiplication (Primary Order of the row, right of the matrix) and a left multiplication (Primary Order of the column, left of the matrix ).OpenGL uses the column primary sequence matrix, that is, the column matrix.,Therefore, we always calculate (the left multiplication matrix, the transformation effect is in the order from right to left): Projection Matrix × view matrix × model matrix × 3d position.
Array representation of the 4*4 column matrix: number indicates the row and column positions corresponding to the array Subscript:
So
Translation matrixIt can be expressed:
Translation matrix X column matrix (a, B, c, 1) = column matrix (a + X, B + Y, C + Z, 1 ).
Zoom MatrixIt can be expressed:
Zoom matrix X column matrix (a, B, c, 1) = column matrix (A × Sx, B × Sy, c × SZ, 1 ).
Rotating matrix around X axisIt can be expressed:
X axis rotation matrix X column matrix (a, B, c, 1) = column matrix (a, B x cos (θ)C x sin (θ ), B xsin (θ) + C x cos (θ), 1 ).
Rotating matrix around Y axisIt can be expressed:
Rotate matrix X column matrix (a, B, c, 1) = column matrix (A × cos (θ)C × sin (θ), B, A ×sin (θ) + c × cos (θ), 1 ).
Rotating matrix around the Z axisIt can be expressed:
Rotating matrix X column matrix (a, B, c, 1) = column matrix (a x cos (θ)B x sin (θ), a Xsin (θ) + B × cos (θ), C, 1 ).
3. Implementation in OpenGL
OpenGL uses righthand rules for rotationTherefore, the clockwise direction is the positive angle, while the clockwise direction is the negative angle. Do you still remember the Right Hand rules for middle school physics? If you forget it, see:
Note:
As mentioned above, matrix multiplication does not satisfy the multiplication law. Therefore, you rotate a 3D coordinate first and then perform translation (translation matrix X rotation matrix X 3D coordinates, then, the results obtained by rotating the matrix X translation matrix X 3D coordinates are quite different. As shown in:
In the first case, we usually call the rotation in the local space because it is carried around the center of the object, in the latter case, the rotation is usually called in World Space. We know that points can be converted between coordinate spaces, which is a very important concept.In OpenGL, objects are first in the local coordinate space, then converted to the world coordinate space, then to the camera view space, and then to the projection space. These conversions are implemented by matrix computing.
In OpenGL and OpenGL ES 1.0, the corresponding code is similar:
Glviewport (0, 0, (glsizei) W, (glsizei) H); A) glmatrixmode (gl_projection); B) glloadidentity (); glfrustum (1.0, 1.0,1.0, 1.0, 1.5, 20.0); c) glmatrixmode (gl_modelview); d) glclear (gl_color_buffer_bit); glcolor3f (1.0, 1.0, 1.0); glloadidentity (); /* clear the matrix * // * viewing transformation */glulookat (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0); e) glscalef (0.0, 2.0, 1.0);/* modeling transformation */F) fig (1.0); g) glflush ();
Note:
A) is used for viewport transformation. The viewport transformation occurs after the projection to the 2D projection plane.NormalizationPoint ing to the coordinates in the area on the screen. The purpose of the CTR is to specify the area where the projected image is displayed on the screen. As follows:
The glviewport (X, Y, width, height) is changed in the view. X and Y are the starting position of the projection plane in the screen or window. (Note that the screen coordinates are at the origin in the top left corner ), width and height are measured in pixels, indicating the size of the area depicted by the projection plane on the screen. If the aspect ratio of the projection plane is different from the width/height ratio (the right image above), the scenario is distorted.
As shown in the whole process from cropping to the screen, W is the onedimensional coordinate mentioned above. From clip space to normalized device space is the process of projection standardization, from normalized device space to window space is the process of viewport transformation.
The internal formula for the conversion is:
(XW, YW) is the screen coordinate, (x, y, width, height) is the input parameter, (xnd, ynd) the point after the projection is normalized (the point in the normalized device space ). Therefore, the viewport transformation is to convert the normalized points after projection to the screen coordinates that can be used for rendering on the screen;
B) It indicates that the matrix below is used for projection transformation. In this example, the perspective projection transformation is set through Statement C) glfrustum. There are two types of projection transformations: orthogonal projection and perspective projection, which will be detailed later;
D) It means that the matrix below is used for Model View transformation. Note that both OpenGL and OpenGL ES combine model transformation and view transformation, instead of being separated into two, this is because model transformation is equivalent to reverse transformation of view transformation. View transformation refers to converting an object into the sight space of the observer (usually called Camera. You can imagine, when taking a picture, you can: a) the camera doesn't understand, you can rotate your head to find a side image, or B) You can not move yourself, the camera rotates at a certain angle to achieve the same effect. The following two figures describe case A and case B respectively ):
Case A): rotating an object without moving the camera
Case B): rotate the camera and the object does not move
In OpenGL, we usually adopt case B when setting the scene (scene). Therefore, in statement E, we set the camera position and orientation, (f) glscale is set in the model transformation, and finally the statement g) depicts the object in the local space.
Note:
When writing OpenGL code, the order from top to bottom is: Set the viewport, set the projection transformation, set the view transformation, set the model transformation, and depict the object in the local coordinate space.In the previous sections, the sequence of introduction is as follows:In OpenGL, objects are first in the local coordinate space, then converted to the world coordinate space, then to the camera view space, and then to the projection space.Since the Model transformation includes the transformation of the local space to the world coordinate space, weUnderstanding 3D transformation is an order, while actually writing code is in the opposite order.MatrixIn this case, it is easy to understand why it is in reverse order.
With the overall concept of 3D transformation above, the following describes Projection Transformation and view transformation in detail.
Iv. Projection Transformation
The purpose of projection transformation is to determine how objects in a 3D space are projected onto a 2D plane to form a 2D image. These 2D images are then rendered to the screen after the visual mouth transformation. As mentioned above, there are two types of projection transformations: orthogonal projection and Perspective Projection. Perspective Projection is widely used. It is closer to the real world: near objects look larger than distant objects, but orthogonal projection does not, orthogonal projection is usually used in CAD or architectural design. The orthogonal projection and perspective projection effects are as follows:
Orthogonal projection 
Perspective Projection 


Perspective Projection can be expressed in two ways. OpenGL and OpenGL ES 1.0 provide glfrustum, while the glut auxiliary Library provides gluperspective. They are essentially the same, but they are different expressions:
Video cone/Visual Object:
Glfrustum (left, right, bottom, top, znear, zfar );
Left, right, bootom, top defines the near cropping surface size, while znear and zfar define the distance from camera/Viewer to the distance between the two cropping surfaces (note that the distance between the two is positive ). The six parameters can define a cone composed of six cropping surfaces, which are usually called a cone or a visual object. Only the objects in this cone can be seen. objects not in this cone are no longer within the line of sight and will be dropped. OpenGL will not render these objects.
Since OpenGL ES 2.0 does not provide this function, we need to implement it ourselves. The formula is as follows:
Suppose: L = left, r = right, B = bottom, t = Top, n = znear, F = zfar, there are
Perspective:
Gluperspective (fovy, aspect, znear, zfar );
Fovy defines the line of sight angle of camera in the Y direction (between 0 and ~ 180), aspect defines the width to height ratio of the nearcropping surface aspect = W/H, znear and zfar define the distance from camera/Viewer to the distance between the two cropping surfaces (note that both distances are positive ). The four parameters also define a cone.
In OpenGL ES 2.0, we also need to implement this function by ourselves. We can use the Triangle Formula Tan (fovy/2) = (H/2)/znear to calculate h, and then calculate W according to W = H * aspect, in this way, we can obtain the left, right, top, bottom, znear, and zfar parameters, and use the formula mentioned in the introduction of the cone.
Orthogonal projection is provided by glortho in OpenGL and OpenGL ES 1.0. we can regard orthogonal projection as a special form of Perspective Projection: that is, the near and far cropping surfaces are identical except for the Z position, so the objects are always the same size and will not become smaller even in the distance.
Glortho (Left,Right,Bottom,Top,Znear,Zfar);
Left, right, bootom, top defines the near cropping surface size, while znear and zfar define the distance from camera/Viewer to the distance between the two cropping surfaces (note that the distance between the two is positive ).
Assume that xmax = right, xmin = left, Ymax = Top, ymin = bottom, zmax = far, zmin = near, and orthogonal projection can be calculated in two steps: first, translate to the center of the video cone, and then zoom.
Translation matrix: (2 min in the figure should be zmin)
Zoom matrix:
Orthogonal projection matrix R = S x T:
5. View Transformation
The purpose of view transformation is to enable us to observe a specific scene (from the observer's perspective) or to convert an object from the world to the view space of the camera's line of sight (from the 3D object perspective ). This can be achieved by setting the position and orientation of the observer or performing 3D transformation on the object, usually in the previous way (that is, setting the position and orientation of the observer ). As shown in, the XYZ coordinate axis represents the world coordinates, and the bluewhite area is the view space. The view transformation is to switch the Cube from the world space to the coordinate system of the view space, then, the projection is normalized, and then the viewport is converted and mapped to the screen for rendering.
In OpenGL, we can use the glulookat function provided by the tool library to implement this function. The function is prototype:
Glulookat (eyex, eyey, Eyez, centerx, centery, centerz, UPX, upy, upz );
Eye indicates the position of the camera/Viewer, center indicates the focus of the camera or eye (it is used together with the eye to determine the orientation of the eye), and Up indicates the positive direction of the eye, note that up only indicates the direction, regardless of the size. By calling this function, you can set the observed scenario. In this scenario, the objects will be processed by OpenGL.In OpenGL, the default position of the eye is at the origin, pointing to the negative direction of the Z axis (screen to the inside), and the UP direction is the positive direction of the Y axis.In the following tutorial 04, the default settings are used.
OpenGL ES 2.0 does not provide this function. The internal implementation of glulookat is to first rotate to the same direction as the observer's line of sight, and then move to the observer's position. The implementation pseudo code is as follows:
Matrix4 getlookatmatrix (vector3 eye, vector3 at, vector3 up) {vector3 forward, side; Forward = ateye; normalize (forward); side = cross (forward, up ); normalize (side); up = cross (side, forward); matrix4 res = matrix4 (side. x, up. x,forward. x, 0, side. y, up. y,forward. y, 0, side. z, up. z,forward. z, 0, 0, 0, 0, 1); translate (Res, vector3 (0eye); Return res ;}
In the code above, Cross is the cross product, normalize is the normalization, matrix4 is the primary column order, and translate is the translation.
Vi. Postscript
3D transformation is difficult for beginners. I try to understand it, but I don't know how it works. It took me a lot of time to write this article, but I only mentioned the fourelement and universal joint locks. I will introduce them separately later. Nate Robin wrote a visual tutorial tool for 3D transformation. It is very helpful for understanding projection, view, and model transformation. It is strongly recommended to download and run this tool.ProgramAnd adjust relevant parameters to see the effect. Click here to go to the download page (for Windows and Mac)
7. Reference
1. OpenGL programming guide
2. 3D mathematical basics: graphics and Game Development
3, http://cse.csusb.edu/tong/courses/cs420/notes/viewing2.php
Http://www.mesa3d.org/
Http://dbin.com/blog/2011/04/camerasonopengles2x/ 5