OpenGL rendering architecture

First, there are a few concepts that need to be clarified when rendering graphics in OpenGL:

  • Client: The Client is the code that we store on the CPU. For example, we will write C/C++ code and use OpenGL apis.
  • Server: The Server is actually our GPU.
  • Vertex Shader: Vertex Shader is a program in OpenGL that computes Vertex attributes and handles transformations (translation, rotation, scaling, etc.) for each Vertex of a graph.
  • Primitive Assembly is actually a process of turning a geometric figure into a 2-digit figure. It is also called the process of turning vertex data into tiles.
  • Fragment Shader: a Fragment Shader is a program in OpenGL that calculates the color of a Fragment (pixel). It is generally used to calculate and fill each pixel in a graph.
  • -Leonard: Well, let’s just Render the graphics.

See Section 2 below for information about Attributes and Texture Data, which are simply understood as a Data transmission channel.

The Client passes Data to our Vertex Shader and Fragment Shader in three formats: Attributes derated and Texture Data. Texture Data is rarely passed to the Fragment Shader during development.

OpenGL data transfer in three ways

The way we pass data is called a channel in OpenGL. The most common channels are Attribute, Uniform, Texture and so on. They can store multiple parameter values and fill them as needed.

  • Attribute (used by vertex shaders) Values that can be stored:

    • Color data
    • Vertex data
    • Texture coordinates
    • Light normal
  • Uniform standard arguments (both vertex shaders and slice shaders are available) can store values:

    • Vertex transformation calculation matrix (vertex shader computes vertex coordinate transformation)
    • Color space conversion matrix (slice shader converts YUV color space of video into RGBA used by OpenGL by matrix calculation)
  • Texture (vertex shader and slice shader are available, usually empty is used by slice shader) can store values:

    • Filter (make changes to the image itself, such as changing the color value of the image)
    • Render a shape (directly render the triangle with the set color value, without filling it with a triangle image to render)
    • Pixel Fill (Blend layer color fill)

OpenGL provides storage shaders

OpenGL provides a storage shader called GLShaderManager, which is initialized by calling InitializeStockShaders(). The nice thing about using GLShaderManager is that we don’t have to know which work is done by the vertex shader and which work is done by the slice shader. We just need to use GLShaderManager to call the UserStockShader() method and pass different arguments. Here are some different shaders.

  • Unit shader UserStockShader(GLT_SHADER_IDENTITY, GLfloat vColor[4])

    • Parameter 1: Storage shader type – unit shader
    • Parameter 2: color array of length 4 (each element represents R, G, B, A)

    Usage scenario: Draw the graph in the default OpenGL coordinate system (-1, 1), all the fragments of the graph will be filled with one color.

  • Flat shader UserStockShader(GLT_SHADER_FLAT, GLfloat MVP [16], GLfloat vColor[4])

    • Parameter 1: Storage shader type – flat shader
    • Parameter 2:4×4 matrix that allows variation
    • Parameter 2: color array of length 4 (each element represents R, G, B, A)

    Usage scenario: When drawing graphics, it can be used for transformation (model, projection change). M represents model, V represents view, p represents projection perspection!

  • Coloring shader UserStockShader(GLT_SHADER_SHADED, GLfloat MVP [16])

    • Parameter 1: Store shader type – coloring shader
    • Parameter 2:4×4 matrix that allows variation

    Usage scenario: When drawing graphics, it can be used for transformation (model, projection change). The colors will be smoothly inserted between vertices called smooth shading.

  • Default light shader UserStockShader(GLT_SHADER_DEFAULT_LIGHT, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vColor[4])

    • Parameter 1: Storage shader type – default light shader
    • Parameter 2: model 4×4 matrix
    • Parameter 3: projection 4×4 matrix
    • Parameter 4: Color array of length 4 (each element represents R, G, B, A)

    Use scenarios: Can be used for transformations (model, projection changes) when drawing graphics. This shader creates shadows and lighting effects on graphics.

  • Point light shader UserStockShader(GLT_SHADER_POINT_LIGHT_DIEF, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vLightPos[3], GLfloat vColor[4])

    • Parameter 1: Storage shader type – point light shader
    • Parameter 2: model 4×4 matrix
    • Parameter 3: projection 4×4 matrix
    • Parameter 4: Position of point light source (x, y, z)
    • Parameter 5: Array of color values of diffuse length 4 (each element representing R, G, B, A)

    This shader gives shadows and lighting effects to the graphics. It is very similar to the default light shader, except that the light position may be specific.

  • Texture replacement shader UserStockShader(GLT_SHADER_TEXTURE_REPLACE, GLfloat mvMatrix[16], GLint nTextureUnit)

    • Parameter 1: Store shader type – Texture replacement shader
    • Parameter 2: model 4×4 matrix
    • Parameter 3: Texture unit

    Use scene: When drawing graphics, can be used for transformation (model, projection change) This shader projects a matrix through a given model view, using texture units to fill in color, where the color of each pixel is taken from the texture.

  • Texture adjustment shader UserStockShader(GLT_SHADER_TEXTURE_MODULATE, GLfloat mvMatrix[16], GLfloat vColor[4], GLint nTextureUnit)

    • Parameter 1: Store shader type – Texture adjustment shader
    • Parameter 2: model 4×4 matrix
    • Parameter 3: color array of length 4 (each element represents R, G, B, A)
    • Parameter 4: Texture unit

    This shader projects a matrix through a given model view. The shader multiplies a base color by a texture taken from the texture unit nTextureUnit, and colors mix with the texture before filling the fragment.

  • Texture light shader UserStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIEF, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vLightPos[3], GLfloat vBaseColor[4], GLint nTextureUnit)

    • Parameter 1: Store shader type – Texture light shader
    • Parameter 2: model 4×4 matrix
    • Parameter 3: projection 4×4 matrix
    • Parameter 4: Position of point light source (x, y, z)
    • Parameter 5: A color array of length 4 (each element represents R, G, B, A), the basic color of the geometry
    • Parameter 6: Texture unit

    Use scenarios: When drawing graphics, it can be used for transformation (model, projection change). This shader projects a matrix through a given model view, and the shader adjusts a texture by a diffuse lighting calculation (multiplied).

API use of orthographic projection and perspective projection

Orthographic projection will not be much smaller than perspective projection.

  • Orthographic projection API: API CLFrumStum::SetOrthographic(GLfloat xMin, GLfloat xMax, GLfloat yMin, GLfloat yMax, GLfloat zMin, GLfloat zMax)

    • XMin: the minimum value of the x coordinate
    • XMax: the maximum value of the x coordinate
    • YMin: the minimum value of the y coordinate
    • YMax: indicates the maximum value of the y coordinate
    • ZMin: the minimum value of the Z coordinate
    • ZMax: the maximum value of the z coordinate
  • Perspective projection API: CLFrumStum: : SetPerspective (float fFov, float fAspect, float fNear, float fFar)

    • FFov: Vertical field of view Angle
    • FAspect: aspect ratio of window (W /h)
    • FNear: indicates the distance near the clipping surface
    • FFar: distance near the clipping surface

    Reference article: Perspective projection matrix

OpenGL common primitives

Primitives: is the connection of vertices, in OpenGL, only points, lines, triangles.

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_LINES_STRIP A line drawn from the first vertex through each successive vertex
GL_LINES_LOOP Same as GL_LINES_STRIP, but the last vertex is joined to the first vertex
GL_TRIANGLES A triangle is defined for every three vertices
GL_TRIANGLES_STRIP Sharing vertices on a strip forms a new set of triangles
GL_TRIANGLES_FAN Triangles fan-shaped around the origin and sharing adjacent vertices

The most popular form of OpenGL rasterization is triangles. Three vertices make a triangle. By default, OpenGL tasks with polygons that connect vertices counterclockwise are called faces, and those that connect vertices clockwise are called tails.

The advantage of OpenGL’s triangle strip is that after specifying the first triangle with the first three vertices, you only need to specify one vertex for each subsequent triangle. Using this method can save a lot of code and data storage space when a large number of triangles need to be drawn. Provides computing performance and bandwidth savings. Fewer vertices means faster data transfer from memory to graphics cards, and fewer vertex shaders need to process them.

OpenGL tool class GLBatch

  • Create GLBatch void GLBatch::Begin(GLenum primitive, GLuint nVerts, GLuint nTextureUnits = 0)

    • Parameter 1: indicates the primitive type
    • Parameter 2: number of vertices
    • Parameter 3:1 or 2 texture coordinates (optional, default is 0)
  • Copy the vertex data (a weight from 3 x, y, x vertex array) void GLBatch: : CopyVerterxData3f (GLfloat * vVerts)

  • Void GLBatch::CopyNormalDataf(GLfloat *vNorms)

  • Void GLBatch::CopyColorData4f(GLfloat *vColors)

  • Copy the texture coordinates data void GLBatch: : CopyTexCoordData2f (GLfloat * vTextCoords, GLuint uiTextureLayer)

  • Void GLBatch::End(void)

  • Void GLBatch::Draw(void)