OpenGL basic primients

OpenGL supports many different primitive types. But they all boil down to one of three types: points, lines, or triangles. Line and triangle primitives can be recombined into strips, circular bodies (lines), or sectors (triangles). Points, lines, and triangles are also the basic primitive types supported by most graphics hardware devices (hardware support is the rasterization operations that directly provide these primitive types in the GRAPHICS processor. Other primitive types, such as Patch and adjacency primitive, cannot be rasterized directly).

The connection modes of primitives in OpeGL are as follows:

Figure yuan describe
GL_POINTS Each vertex is a separate point on the screen
GL_LINES Each pair of vertices defines a line segment
GL_LINE_STRIP A line drawn from the first vertex through each successive vertex
GL_LINE_LOOP Same as GL_LINE_STRIP, but the last vertex is joined to the first
GL_TRIANGLES A new triangle is defined for every three vertices
GL_TRIANGLE_STRIP A group of triangles that share vertices on a strip
GL_TRIANGLE_FAN A group of triangles fan-shaped around a dot and sharing adjacent vertices
. .

Part of the schematic diagram is shown below:

The instance

The next part of the connection is demonstrated in code and the rotation function is added.

The main codes are as follows:

GLShaderManager shaderManager; GLMatrixStack modelViewMatrix; GLMatrixStack projectionMatrix; GLFrame cameraFrame; GLFrame objectFrame; // GLFrustum viewFrustum; // Container class (7 different primiples correspond to 7 container objects) GLBatch pointBatch; GLBatch lineBatch; GLBatch lineStripBatch; GLBatch lineLoopBatch; GLBatch triangleBatch; GLBatch triangleStripBatch; GLBatch triangleFanBatch; GLGeometryTransform transformPipeline;Copy the code

The main function:

int main(int argc, char* argv[]) { gltSetWorkingDirectory(argv[0]); glutInit(&argc, argv); / / apply for a color area, depth buffer area, double buffer, stencil buffer area glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); // Set the size of window glutInitWindowSize(800, 600); // Create the window name glutCreateWindow("GL_POINTS"); GlutReshapeFunc (ChangeSize); GlutKeyboardFunc (KeyPressFunc); GlutSpecialFunc (SpecialKeys); // Display function glutDisplayFunc(RenderScene); GLenum err = glewInit(); // Check whether the glew library can be initialized to ensure that the project can use the OpenGL framework.if(GLEW_OK ! = err) { fprintf(stderr,"GLEW Error: %s\n", glewGetErrorString(err));
        return1; } // Initialize work SetupRC(); //runloop runs the loop glutMainLoop();return 0;
}
Copy the code

Among them, we control the rotation of the screen through the up, down, left and right arrow keys, related functions are as follows:

GLFrame objectFrame void SpecialKeys(int key, int x, int y) {GLFrame objectFrame void SpecialKeys(int key, int x, int y) {if(key == GLUT_KEY_UP) {
        objectFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0, 0.0, 0.0);
    }
    if(key == GLUT_KEY_DOWN) {
        objectFrame.RotateWorld(m3dDegToRad(5.0f), 1.0, 0.0, 0.0);
    }
    if(key == GLUT_KEY_LEFT) {
        objectFrame.RotateWorld(m3dDegToRad(-5.0f), 0.0, 1.0, 0.0);
    }
    if(key == GLUT_KEY_RIGHT) {objectFrame.rotateWorld (m3dDegToRad(5.0f), 0.0, 1.0, 0.0); } // Execute redraw glutPostRedisplay(); }Copy the code

Since we need to rotate, we need to use the corresponding MVP (modelViewPrejection) matrix, which is set in the ChangeSize callback

// The window has been resized or just created. Void ChangeSize(int w, int h) {glViewport(0, 0, w, h); / / set the perspective model viewFrustum. SetPerspective (35 f,float(w)/float(h), 1.0 f, 500. F); / / the perspective matrix loaded into the matrix stack perspective projectionMatrix. LoadMatrix (viewFrustum. GetProjectionMatrix ()); / / modelViewMatrix matrix stack loading unit matrix, this step can be omitted, because at the bottom of the stack modelViewMatrix. The default is a unit matrix LoadIdentity (); }Copy the code

We use different Settings for SetupRC functions and RenderScene callbacks to display different primitives.

GL_POINTS

The implementation effect is as follows:

SetupRC

// This function does any necessary initialization in the rendering context. // This is the first time to do any OpengL related tasks. voidSetupRC() {// Set the background color glClearColor(0.34f, 0.34f, 0.5f, 1.0f); / / initialize shader fixed shaderManager. InitializeStockShaders (); / / set the transformation pipeline to use the model view matrix and projection matrix transformPipeline. SetMatrixStacks (modelViewMatrix projectionMatrix); For obvious effect, move the observer's position Z 15 units into the screen // Parameter: represents the distance from the screen. Negative numbers are moving behind the screen; // camera Camerafame.MoveForward(-15.0f); GLfloatVCoast [9] = {3,3,0, 0,3,0, 0}; Pointbatch.begin (GL_POINTS, 3); pointBatch.CopyVertexData3f(vCoast); pointBatch.End(); }Copy the code

RenderScene

/ / call scenario void RenderScene (void) {glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); . / / model view matrix stack modelViewMatrix PushMatrix (); M3DMatrix44f mCamera; cameraFrame.GetCameraMatrix(mCamera); / / matrix multiply, the top of the stack matrices, the result of the multiplication Jane then stored on the top of the stack modelViewMatrix. MultMatrix (mCamera); M3DMatrix44f mObjectFrame; objectFrame.GetMatrix(mObjectFrame); / / matrix multiply, the top of the stack matrices, the result of the multiplication Jane then stored on the top of the stack modelViewMatrix. MultMatrix (mObjectFrame); / / surface shader shaderManager. UseStockShader (GLT_SHADER_FLAT, transformPipeline GetModelViewProjectionMatrix (), vBlack); GlPointSize (10.0 f); pointBatch.Draw(); GlPointSize (1.0 f); modelViewMatrix.PopMatrix(); glutSwapBuffers(); }Copy the code

Through the above code, you can achieve the function of rendering three vertices on the screen. Let’s explain the matrix-related operations in RenderScene, which are associated with the following:

  • GLShaderManager shaderManager; // Shader management class
  • GLMatrixStack modelViewMatrix; // Model view matrix stack
  • GLMatrixStack projectionMatrix; // Projection matrix stack
  • GLFrame cameraFrame; // Camera Angle, responsible for specifying the viewing Angle position
  • GLFrame objectFrame; // Object view, which controls the rotation of the object
  • GLFrustum viewFrustum; / / byviewFrustumTo get the projection matrix
  • GLGeometryTransform transformPipeline; // Combine model view matrix and projection matrix

The projection matrix is set in the ChangeSize callback, and it is the model view matrix that needs to be changed for each d-key operation to rotate the view.

The specific operations are as follows:

  1. Model view matrix stacks
  2. Get the camera matrix, multiply the top stack matrix by the camera matrix and replace the top stack matrix
  3. Get the object matrix, multiply the top stack matrix by the object matrix and replace the top stack matrix
  4. The model view matrix is combined with the projection matrix to generate a new matrix,shaderMangerRedraw the parameters using a flat shader and a new matrix.
  5. Model view matrix out of stack, back to original state.

The schematic diagram of the big guy is as follows:

This is the use of vertex primitives. The following other primitives are just schematic diagrams, and the implementation can be referred to in the demo code.

GL_LINES

GL_LINE_STRIP

GL_LINE_LOOP

GL_TRIANGLES

GL_TRIANGLE_FAN

GL_TRIANGLE_STRIP