Writing in the front

This paper mainly introduces how to display the vertex data in fixed position in 6 different pixels, and use the keyboard to control the view transformation.

See: github.com/cjf56455885…

1. Rendering flow chart

The entire rendering process of this case is roughly shown in figure 1.

  • Main function: program entry, mainly initialize OpenGL required libraries, set custom callback functions, and start the run loop

  • ChangeSize function: called when the window changes size or is just created, using the dimensions of the window to set the viewport and projection matrix

  • SteupRC function: This function does any necessary initialization in the rendering context, where OpenGL drawing takes place.

  • SpecialKeys: Special key handling (move up, down, left, right)

  • KeyPressFunc function: Switches different primiples according to the number of Spaces

  • RenderScene function: Call scene, the final rendering function

  • DrawWireFrameBatch function: used for filling and border drawing of stereo graphics

A few key functions are further explained below.

2. ChangeSize function

Void ChangeSize(int w, int h){// Set the position and size of the viewport glViewport(0, 0, w, h); / / create the projection matrix and loading it in the projection matrix stack viewFrustum. SetPerspective (35.0 f, float (w)/float (h), 1.0 f, 500.0 f); / / by setting the projection method to obtain the projection matrix, and place it in the projection matrix projectionMatrix. LoadMatrix (viewFrustum. GetProjectionMatrix ()); / / call the top load cell matrix modelViewMatrix. LoadIdentity (); }Copy the code
  • 1. Set the position and size of the viewport
glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
Copy the code

The first two parameters represent the x and y coordinate points, and the last two parameters represent the width and height, which are consistent with the width and height of the window size.

Viewport: The size of the viewport area, usually the same as the size of the window, or optionally, the vertices outside the viewport are clipped

  • 2. Set the projection matrix
    • Parameter 1: Vertical field of view, which can be understood as the Angle of eye opening
    • Parameter 2: Viewport aspect ratio = W /h
    • Parameter 3: Distance near the clipping surface
    • Four parameters: Distance from the cutting surface
viewFrustum.SetPerspective(float fFov, float fAspect, float fNear, float fFar);
Copy the code

FNear and fFar can be adjusted to fit the situation, and the effect is similar to the difference between an egg in a box and a suitcase, as long as the container is big enough to hold the object.

Here because it is to display three-dimensional graphics, so the perspective projection.

  • 3. Obtain the projection matrix using the preset projection mode and save it to the projection matrix
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());
Copy the code

As the window changes, so does the viewport in this example. So we’re going to get the projection matrix every time we make a change.

  • 4. Stack a cell matrix against the model view matrix
modelViewMatrix.LoadIdentity();
Copy the code

After rendering each scene, you need to return to the original state and prepare to render the next scene. So a cell matrix is pressed in advance, and after drawing, the matrix stack pops out for restoration.

Model view matrix: a combination of model matrix and view matrix. The model matrix corresponds to the transformation of the object itself, and the view matrix corresponds to the transformation of the observer.

Model matrix: transfers defined local coordinates to world coordinates.

View matrix: Transfer world coordinates to camera coordinates.

The two are usually used in combination. When you want to photograph something, you can do it in two ways.

1. If the camera does not move, move the object to the viewing range

2. If the object does not move, move the camera to ensure that the object is visible

The purpose of both changes is the same, so they are generally used in combination to determine what you can see.

In graphics, in order to facilitate processing, it is generally stipulated that the camera is located at the origin, and more importantly, the position of the object is adjusted.

3. SetupRC function

A function that prepares the initialization of the background color, fixes the initialization of the shader management class, sets the orientation of the observer, gives initialized vertex data and specifies the batch class.

Void SetupRC(){// Grey background glClearColor(0.7f, 0.7f, 0.7f, 1.0f); / / fixed shader management class initialization shaderManager InitializeStockShaders (); / / set the transformation pipeline to use the two matrices stack transformPipeline. SetMatrixStacks (modelViewMatrix projectionMatrix); CameraFrame. MoveForward (15.0 f); . Pointbatch.begin (GL_POINTS, 3); pointBatch.begin (GL_POINTS, 3); pointBatch.begin (GL_POINTS, 3); pointBatch.CopyVertexData3f(vCoast); pointBatch.End(); Linebatch. Begin(GL_LINES, 3); lineBatch.CopyVertexData3f(vCoast); lineBatch.End(); Linestripbatch.begin (GL_LINE_STRIP, 3); linestripbatch.begin (GL_LINE_STRIP, 3); lineStripBatch.CopyVertexData3f(vCoast); lineStripBatch.End(); Lineloopbatch.begin (GL_LINE_LOOP, 3); lineLoopBatch.CopyVertexData3f(vCoast); lineLoopBatch.End(); }Copy the code
  • 1. Set the background color
GlClearColor (0.7 f, f, 0.7 0.7 f, 1.0 f);Copy the code
  • 2. Fixed shader management class initialization
shaderManager.InitializeStockShaders();
Copy the code

Fixed shaders are provided by OpenGL and must be initialized before using fixed shaders.

  • 3. Transform pipeline using matrix stack
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);
Copy the code

The modelViewMatrix and projectionMatrix matrix stack are handed over to the transformation pipeline, and then the model view projectionMatrix can be obtained directly through the get method of the transformation pipeline.

Transformation pipeline: the pipeline that manages matrices and matrix transformations. It contains the result of multiplying matrices and matrices.

  • 4. Set the observer position
CameraFrame. MoveForward (15.0 f);Copy the code

The observer position can be set in three ways:

methods The effect
void MoveForward(float fDelta) Move back and forth to change the z value
void MoveUp(float fDelta) Move up and down, change the y value
void MoveRight(float fDelta) Move left and right, change the x value

4. Functions that respond to special keys

SpecialKeys: Special key function that controls view rotation

KeyPressFunc: space key function to switch view elements

Void SpecialKeys(int key, int x, int y){if(key == GLUT_KEY_UP) objectFrame.rotateWorld (m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0 f); If (GLUT_KEY_DOWN) objectFrame.rotateWorld (m3dDegToRad(5.0f), 1.0f, 0.0f, 0.0f); If (GLUT_KEY_LEFT) objectFrame.rotateWorld (m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f); If (key == GLUT_KEY_RIGHT) objectFrame.rotateWorld (m3dDegToRad(5.0f, 0.0f, 1.0f, 0.0f); glutPostRedisplay(); }Copy the code

GLUT_KEY_UP,GLUT_KEY_DOWN,GLUT_KEY_LEFT, and GLUT_KEY_RIGHT are the fields provided by the system in response to the left, right, and upper keys

  • 1. Set the rotation
RotateWorld(**float** fAngle, **float** x, **float** y, **float** z);Copy the code
  • 2. Submit a re-render
glutPostRedisplay();
Copy the code

5. RenderScene function

Functions that actually do the work.

void RenderScene(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); / / pressure stack modelViewMatrix. PushMatrix (); // The observer matrix is pressed into the matrix stack M3DMatrix44f mCamera; cameraFrame.GetCameraMatrix(mCamera); modelViewMatrix.MultMatrix(mCamera); // Model view matrix is pressed into matrix stack M3DMatrix44f mObjectFrame; objectFrame.GetMatrix(mObjectFrame); modelViewMatrix.MultMatrix(mObjectFrame); // Use a flat shader, Matrix parameters from the transformation pipeline shaderManager. UseStockShader (GLT_SHADER_FLAT, transformPipeline GetModelViewProjectionMatrix (), vBlack); / *switch**(nStep) {case 0: glPointSize(4.0f); pointBatch.Draw(); GlPointSize (1.0 f); break; Case 1: // Set line width glLineWidth(2.0f); lineBatch.Draw(); GlLineWidth (1.0 f); break; Case 2: glLineWidth (2.0 f); lineStripBatch.Draw(); GlLineWidth (1.0 f); break; Case 3: glLineWidth (2.0 f); lineLoopBatch.Draw(); GlLineWidth (1.0 f); break; case 4: DrawWireFramedBatch(&triangleBatch); break; case 5: DrawWireFramedBatch(&triangleStripBatch); break; case 6: DrawWireFramedBatch(&triangleFanBatch); break; } / / restore to the previous model view matrix (matrix) modelViewMatrix. PopMatrix (); GlutSwapBuffers (); }Copy the code
  • 1. Clear the buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
Copy the code

At each rendering, the buffer used is cleared to prevent the contents of the previous frame from remaining in the buffer.

  • 2. Model view matrix pushes element matrix
modelViewMatrix.PushMatrix();
Copy the code

The element matrix is pressed to ensure that the original state is left after the last frame is rendered. Element matrix multiplication is still element matrix, so to be on the safe side, the matrix stack can be pushed into the element matrix multiple times without impact.

  • 3. Stack the matrix into the corresponding matrix

There is the concept of two matrix stacks. The observer matrix stack and the model view matrix stack are both handed over to the transform pipeline in SetupRC.

M3DMatrix44f mCamera;  
cameraFrame.GetCameraMatrix(mCamera); 
modelViewMatrix.MultMatrix(mCamera); 

M3DMatrix44f mObjectFrame;     
objectFrame.GetMatrix(mObjectFrame);     
modelViewMatrix.MultMatrix(mObjectFrame);
Copy the code

The observer matrix is pushed onto the observer matrix stack, and the model view matrix onto the model view matrix stack.

  • 4. Draw with a flat shader
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
Copy the code

Surface shader for the second parameter is the projection matrix, used here transformPipeline. GetModelViewProjectionMatrix () from the transformation pipeline after processing the model view projection matrix.

  • 5. Switch ICONS according to the number of Spaces

Here is a high code similarity, take one of them.

GlLineWidth (2.0 f); lineLoopBatch.Draw(); GlLineWidth (1.0 f);Copy the code

Draw using the line loop batch class.

lineLoopBatch.Begin(GL_LINE_LOOP, 3);
lineLoopBatch.CopyVertexData3f(vCoast);
lineLoopBatch.End();
Copy the code

The line loop batch class is defined as GL_LINE_LOOP in SetupRC. And the same goes for everything else.

Here, the number of times to click the space is used to control the pixel assembly, and different pixel assembly methods will affect the shape of the object.

  • 6. Model view matrix stack restoration
modelViewMatrix.PopMatrix();
Copy the code

After each rendering, the model view matrix stack needs to be restored to ensure that the next rendering is pollution-free.

  • 7. Swap buffers
glutSwapBuffers();
Copy the code

Because there are double buffers, the buffers need to be swapped to keep the screen refreshed.

6. Matrix stack

Matrix stack is responsible for constructing and managing matrices that create complex scenes in 3D space. The corresponding class is GLMatrixStack.

The matrix stack contains the identity matrix by default when initialized. The default stack depth is 64.

Related commands are as follows:

  • GLMatrixStack: : LoadIdentity () : at the top of the load cell matrix
The function name instructions
GLMatrixStack::LoadIdentity() Load the element matrix at the top
GLMatrixStack.LoadMatrix(const float * mMatrix) Load any matrix at the top
GLMatrixStack::MultMatrix(const float * mMatrix) Multiply a matrix by the top matrix, and the result is stored at the top of the stack
modelViewMatrix.GetMatrix() Gets the top value of the matrix stack
modelViewMatrix.PushMatrix(**const** **float** *mMatrix) Push the matrix to the top of the matrix stack
modelViewMatrix.PopMatrix() The top matrix pops out of the matrix stack
modelViewMatrix.PopMatrix() The top matrix pops out of the matrix stack
modelViewMatrix.Rotate(GLfloat PFNGLPNTRIANGLESFATIPROC, GLfloat x, GLfloat y, GLfloat z) Top of stack matrix applies rotation transformation
modelViewMatrix.Translate(GLfloat x, GLfloat y, GLfloat z) The top of the stack matrix is translated
modelViewMatrix.Scale(GLfloat x, GLfloat y, GLfloat z) Scaling is applied to the top stack matrix

It can be seen that the matrix stack has the ability to push off the stack and affine transformation. It’s still a stack structure, but there’s a matrix in the stack.

Matrix stack is very beneficial to the connection and independence of multiple transformation operations in the process of complex model movement. Any complex motion can be disassembled into a simple one-step transformation, because all matrix manipulation functions only deal with the current matrix or the matrix at the top of the stack, leaving other matrices below the stack unaffected.

Write in the back

The above is a basic example of OpenGL rendering graphics. It involves viewports, model view matrix, projection matrix, transformation pipeline, fixed shader, matrix stack and other common concepts.