I. Final effect
Follow the example and simply achieve the donut effect. The final result is as shown below:
Two. Code implementation
- The entry main function looks like this:
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800.600); // Set the size of the display window
glutCreateWindow("Geometry Test Program"); // Set the window name
glutReshapeFunc(ChangeSize); // ChanegSize is a custom function that is called when the window size changes
glutSpecialFunc(SpecialKeys); // Specialkeys is a custom function that is called when the keyboard is clicked
glutDisplayFunc(RenderScene); // RenderScene is a custom function that is called when rendering is triggered.
GLenum err = glewInit(a);if(GLEW_OK ! = err) {fprintf(stderr, "GLEW Error: %s\n".glewGetErrorString(err));
return 1;
}
SetupRC(a);// Set up the preparation of the vertex data/color data related to the graphics you need to render
glutMainLoop(a);return 0;
}
Copy the code
- ChangeSize function:
// Window changes
void ChangeSize(int w, int h)
{
glViewport(0.0, w, h);
viewFrustum.SetPerspective(20.0 f.float(w)/float(h), 1.0 f.100.0 f);
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix()); // Load the projection matrix
modelViewMatix.LoadIdentity(a);// Load the model view matrix
transformPipeline.SetMatrixStacks(modelViewMatix, projectionMatrix); // Put the two matrices into the transport pipe
}
Copy the code
ViewFrustum is the GLFrustum type used to define the projection type, because we need to display 3D images, so we need to use perspective projection (as opposed to orthographic projection, which is mainly used to display 2D images).
The GLFrustum class builds a flat-frustum for us through the setPerspective method, as shown below:
The function is described as follows:
CLFrustum::SetPerspective(float fFov , float fAspect ,float fNear ,float fFar); Parameter: fFov: vertical field Angle Angle fAspect: aspect ratio of window opening width to height fNear: aspect distance of near clipping fFar: Aspect distance of far clipping = Width (W)/ Height (h)Copy the code
- SetupRC function
void SetupRC(a) {
glClearColor(0.3 f.0.3 f.0.3 f.1.0 f); // Set the background color
glEnable(GL_CULL_FACE); // Enable front and back culling. The principle of front and back culling will be covered in the next article
shaderManager.InitializeStockShaders(a);// Initialize the fixed shader management class
cameraFrame.MoveForward(10.0 f); // Add 10 to the distance from the screen. You can also set the viewFrame to achieve the same effect.
gltMakeTorus(torusBatch, 1.0 f.0.3 f.52.26); // Generate the doughnut vertex data into torusBatch
glPointSize(4.0 f); // Set the size of the point
}
Copy the code
- RenderScene function
This function is the most critical part. It is called when the screen changes or when the developer renders actively, such as manually calling glutPostRedisplay(), to render the data into an image. Implementation is as follows: ` ` ` c + + void RenderScene () {glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear color and depth caches
modelViewMatix.PushMatrix(); // Press a cell matrix M3DMatrix44f mCamera; cameraFrame.GetCameraMatrix(mCamera); / / get view matrix, and Angle of rotation of the mobile modelViewMatix change MultMatrix (mCamera); // Multiply the element matrix at the top of the stack M3DMatrix44f mObjectFrame; viewFrame.GetMatrix(mObjectFrame); / / get the object matrix, said the change such as the rotation of the moving object modelViewMatix. MultMatrix (mObjectFrame); // Multiply the matrix at the top of the stack GLfloat vRed[] = {0.0f, 1.0f, 0.0f, 1.0f}; / / use the default light shader shaderManager. UseStockShader (GLT_SHADER_DEFAULT_LIGHT, transformPipeline GetModelViewMatrix (), transformPipeline.GetProjectionMatrix(), vRed); // Start drawing torusBatch.draw (); modelViewMatix.PopMatrix(); glutSwapBuffers(); } ` ` `Copy the code
Default light shader function description:
GLShaderManager::UserStockShader(GLT_SHADER_DEFAULT_LIGHT,GLfloat mvMatrix[16],GLfloat pMatrix[16],GLfloat vColor[4]); Parameter 1: Store color type - Default light Color Parameter 2: model 4*4 matrix parameter 3: Projection 4*4 matrix parameter 4: Color Color Value Usage Scenario: When drawing graphics, you can apply transform (model/projection change). This color can create shadow and light effects on the drawing graphics.Copy the code
3. To summarize
The donut effect is actually very simple, mainly to understand the entire rendering process, and the vertex data acquisition.
Above, there are three kinds of matrices: perspective matrix, model matrix and projection matrix. A simple graph can illustrate the relationship between the three:We are the little people in the figure above. When we present the object in our eyes, the object looks different when we look at it from the left or from the right, so we need a matrix to describe our own position, namely the perspective matrix. If the object is rotated, the image presented in our eyes is also different, so we also need a matrix to describe the position of the object, that is, the model matrix. The projection matrix determines whether the image will appear to us 2D or 3D, size and so on.
The Demo address