OpenGL ES /OpenGL ES /OpenGL ES /OpenGL ES /OpenGL ES Image rendering implementation and rendering problems OpenGL/OpenGL ES introduction: basic transformation – beginning vector/matrix OpenGL/OpenGL ES introduction: texture exploration – common API parsing OpenGL/OpenGL ES introduction: OpenGL/OpenGL ES: Vertex shaders and slice shaders (OpenGL transition OpenGL ES) Introduction to OpenGL/OpenGL ES: GLKit usage and case studies

The ability to determine the position and orientation of an object is very important for any 3D graphics programmer, and as we will see, it is actually quite convenient to describe the dimensions of an object around its origin and then transform it to the desired position.

vector

Is a point in space (arbitrarily selected), and an arrowhead line segment in space from the origin of the coordinate system to the point’s coordinates, and this arrowhead line segment can be regarded as a vector

The first thing a vector can represent is direction, and the second thing is quantity. Direction: for example, the X-axis is the vector (1,0,0). It is +1 in the X direction and 0 in the Y and Z directions; Quantity: The number of a vector is the length of the vector. For the top X-axis vector (1, 0, 0), the length of the vector is 1. We call vectors of length 1 unit vectors

There are two data types in the Math3D library that can represent a three-dimensional or four-dimensional vector: M3DVertor3f can represent a three-dimensional vector (X, Y, Z), and M3DVertor4f can represent a four-dimensional vector (X, Y, Z, W), where W is the scaling factor, usually 1.

// Simple declaration M3DVector3f vVector; M3DVector4f vVertex = {0.0f, 0.0f, 1.0f, 1.0f}; M3DVector4f vVertex = {0.0f, 0.0f, 1.0f}; // declare a three-component vertex array M3DVector3f vVerts[] = {-0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.5f, 0.0f};Copy the code

Dot product

A dot product between two unit vectors yields a scalar (with a single value) that represents the Angle between the two vectors. To do this, these two vectors have to be unit vectors, and it’s going to return something between minus 1 and 1, which is essentially the cosine of the Angle between these two vectors

The Math3D library also contains some useful functions that use the dot product operation.

M3dDotProduct3 function to actually get the dot product between two vectors

// Float m3dDotProduct3(const M3DVector3f u, const M3DVector3f v); // Float m3dDotProduct3(const M3DVector3f u, const M3DVector3f v);

M3dGetAngleBetweenVectors3 () function returns the radian of Angle value / / returns the radian of the Angle of float m3dGetAngleBetweenVectors3 (const M3DVector3f u, const M3DVector3f v);

cross-product

The cross product between the two vectors is another vector that is perpendicular to the plane defined by the original vectors. To take the cross product, neither of these guys have to be a unit vector. The other thing that’s different from the dot product is that the cross product doesn’t comply with the commutation law V1, X, V2 factorial. = V2 X V1.

There is also a function m3dCrossProduct3 in the Math3D library that takes the cross product of two vectors and returns the resulting vector

void m3dCrossProduct3(M3DVector3f result, const M3DVector3f u, const M3DVector3f v);

matrix

It is a very powerful mathematical tool, which greatly simplifies the process of solving equations or systems of equations with complex relationships between variables. One common example that is relevant to graphic programmers is coordinate transformations. For example, if we have a point in space, defined by x, y, and z coordinates, and we choose an Angle around any point in any direction, we need to know the current position of that point, we need to use a matrix. Why is that? Because the new x coordinate is related not only to the original x coordinate and other rotation parameters, but also to the original y and Z coordinate values. This correlation between variables and solutions is what matrices are best at solving.

In our 3D programming work, we will use almost entirely two dimensional matrices, namely 3 x 3 and 4 x 4 matrices. There are also matrix data types for these two dimensions in the Math3D library.

typedef float M3DMatrix33f[9]; typedef float M3DMatrix44f[16];

Understanding the transformation

In the time between when we specify vertices and when these vertices appear on the screen, three types of geometric transformations may occur: view transformations, model transformations, and projection transformations

Visual coordinates

Visual coordinates are relative to the point of view of the observer, and we can treat them as “absolute” screen coordinates, no matter what transformations are possible.

From the observer’s point of view, the x – and Y-axis squares point to the right and up, respectively. The z-axis square points to the user from the origin, while the negative z-axis points to the inside of the screen from the observer.

View transformation

View transformation is the first transformation applied to the scene. He used it to determine the location of the drift in the scene. By default, the point of view in perspective projection is at the origin (0,0,0) and is viewed in the negative direction of the z-axis (looking into the display). The point of view is moved relative to the visual coordinate system to provide a specific vantage point. When the point of view is at the origin (0,0,0), as in perspective projection, the object drawn at the positive z coordinate is behind the observer. In orthographic projection, the observer is thought to be at infinity in the positive direction of the Z-axis, able to see anything in the viewframe. A view transform allows us to place the point of view wherever we want and allows us to view the scene in any direction. To determine a view transform, we want to place the camera in the scene and point it in a certain direction.

Model transformation

The following figure shows the three most common model transformations: translation: an object is moved along a given axis. Rotation: an object is rotated and scaled around an axis. An object is enlarged or shrunk by a specified amount. The scaling can be uneven, that is, different dimensions can be scaled to different degrees.

The final appearance of a scene or object may depend largely on the order in which model transformations are applied. As shown in the figure below, the results of model transformation are different from that of model transformation transformation.

Duality of model view

In fact, view and model transformations are the same in terms of their internal effects and the final appearance of the scene. Keep the two separate for our convenience. For example, there is no visual difference between moving the object backward and moving the reference frame forward, as shown below:

The model view means that these two transformations are combined in the transformation pipeline to form a single matrix. The model view matrix.

Projection transformation

The projection transformation is applied to the vertices after the model view transformation. This projection actually defines the view body and creates the clipping plane. More specifically, a projection transform specifies how a completed scene (with all model transformations completed) is projected onto the final image on the screen.

  • In orthographic projection, all polygons are accurately drawn on the screen in accordance with the specified relative size
  • Perspective projection shows a scene that is closer to real life. Perspective projection is characterized by shortening perspective, which makes distant objects look smaller than close objects of the same size.

Viewport transformation

When all this is done, you have a two-dimensional projection of the scene, which is mapped to a window somewhere on the screen. This mapping to the physical window is our final transformation, the viewport transformation.

The graphics hardware will do this for us, so don’t worry too much about the process.

Model view matrix

Unit matrix

Multiplying a vector by an identity matrix is the same thing as multiplying this vector by 1, and it doesn’t change anything. The identity matrix is 0 except for one set of elements along the diagonal.

You can generate an identity matrix in OpenGL like this:

GLFloat m [] = {1.0 f, f, 0.0 0.0 f, f 0.0, 0.0 f, f 1.0, 0.0 f, f 0.0, 0.0 f to 0.0 f, f 1.0, 0.0 f, f 0.0, 0.0 f, f 0.0, 1.0} f; Or use 'math3D' of 'M3DMatrix44f' type: F M3DMatrix44f m = {1.0, 0.0 f, f 0.0, 0.0 f, f 0.0, 1.0 f, f 0.0, 0.0 f, 0.0 f. f 0.0, 1.0 f, f 0.0, 0.0 f, f 0.0, 0.0 f, 1.0 f};Copy the code

In the Math3D library, there is also a shortcut function m3dLoadIdentity44 that initializes an identity matrix.

void m3dLoadIdentity44(M3DMatrix44f m);

translation

A translation matrix simply shifts our vertices along one or more of the three axis weights.

The transformation matrix can be used by calling the m3dTranslationMatrix44 function in the Math3D library

void m3dTranslationMatrix44(M3DMatrix44f m, float x, float y, float z);

rotating

To rotate an object along one of three axes or any vector, a rotation matrix is required.

void m3dRotationMatrix44(M3DMatrix44f m, float x, float y, float z);

The zoom

The scale matrix can change the size of an object by zooming in or out of all vertices along three axes by a specified factor. Scaling is not necessarily uniform, we can use it in different directions to stretch and compress at the same time.

M3DMatrix44f m;

void m3dScaleMatrix44(M3DMatrix44f m, float xScale, float yScale, float zScale);

Comprehensive transformation

To move an object to the desired position, we may need to first translate it to the desired position and then rotate it to get the desired result. And since the 4 x 4 transformation matrix contains one position and one direction, a single matrix can do both transformations. You just multiply the two matrices, and the resulting matrix contains the transformation of the associative trace together, all in one matrix. In the Math3D library, m3dMatrixMultiply44 is used to multiply two matrices and return the result.

void m3dMatrixMultiply44(M3DMatrix44f product, const M3DMatrix44f a, const M3DMatrix44f b);

Use of matrix stack

Initialize the

The GLMatrixStack constructor allows you to specify the maximum stack depth. The default stack depth is 64. The matrix stack is initialized to contain the identity matrix. GLMatrixStack::GLMatrixStack(int iStackDepth = 64); / / on the top of the stack in a unit matrix void GLMatrixStack: : LoadIdentity (void); / / / / on the top of the stack load any matrix parameters: 4 x4 matrix void GLMatrixStack: : LoadMatrix (const M3DMatrix44f m); / / matrix multiplied by the matrix stack at the top of the matrix, multiply the storage to the top of the stack void GLMatrixStack: : MultMatrix (const M3DMatrix44f); // To accommodate GLShaderManager, or to get a copy of the top matrix const M3DMatrix44f & GLMatrixStack::GetMatrix(void); void GLMatrixStack::GetMatrix(M3Datrix44f mMatrix);Copy the code

Push the stack, out of the stack

The real value of a matrix lies in storing a state by pushing the stack and then restoring that state by pushing the stack. With the GLMatrixStack class, we can use the PushMatrix function to push the matrix onto the stack to store the value of the current matrix. PopMatrix will remove the top matrix and restore the values below it.

/ / the current matrix onto the stack (stack) matrix copy a to stack void GLMatrixStack: : PushMatrix (void); Void PushMatrix(const M3DMatrix44f mMatrix); // Push GLFrame into matrix void PushMatrix(GLFrame &frame); Void GLMatrixStack::PopMatrix(void); void GLMatrixStack::PopMatrix(void);Copy the code

Refer to the following flow chart for details

Affine transformation

The GLMatrixStack class also has built-in support for creating rotation, translation, and scaling matrices. The following function:

// translation void MatrixStack::Translate(GLfloat x, GLfloat y, GLfloatz); // The rotation argument Angle is the passed degree, not radians void MatrixStack::Rotate(GL)float angle, GLfloat x, GLfloat y, GLfloatz); // Scale void MatrixStack::Scale(GL)float x, GLfloat y, GLfloat z);
Copy the code