First, know EAGL

1, EGL&EAGL

I mentioned in my introduction to OpenGL ES, what is EGL, what is EAGL. Here is a brief overview:

EGL:

Cause: The OpenGL ES command requires a rendering context and a drawing surface to complete the drawing of a graphic image.

However, the OpenGL ES API does not provide information on how to create a rendering context or how the context is connected to the native windowed system.

EGL thus provides us with an interface for linking between the rendering API and the native windowing system.

Render context: Stores the relevant OpenGL ES state. Draw surface: A surface used to draw primitives that specifies the type of cache required for rendering, such as color cache, depth buffer, and template cache.

EAGL:

EGL is not supported on iOS. So Apple provides its own iOS implementation of the EGL API, called EAGL.

2. Main functions of EGL/EAGL

  1. Talking to native Windowing systems;
  2. Query available configurations.
  3. Create “drawing surfaces” available in OpenGL ES.
  4. Synchronize rendering between different classes of apis, such as between OpenGL ES and OpenVG, or between

Between OpenGL and local window drawing commands; Manage “rendering resources”, such as rendering map.

GLSL

OpenGL specifies that the GLSL language is a programming language for programmable shaders (vertices, slices). For iOS development, Xcode does not support the creation and compilation of GLSL language, requiring developers to manually compile.

1. Precautions

  1. Since manual compilation is required, we typically create two empty files and use the.vshThe suffix for vertex shaders, to.fshThe suffix represents the slice shader. (There is no restriction to only use VSH and FSH to mark, as long as you can distinguish them)
  2. The VSH/FSH file is essentially a string and is ultimately converted to a string for compilation.
  3. Do not use Chinese annotations in VSH and FSH files, because it will be difficult to troubleshoot when compiled into strings.
  4. It is not recommended to use NSString directly, because the code is not legible without a clear structure. If you spend a lot of time typesetting, there’s no need

2. Vector data types

The only common ones are vec2, VEC3, and VEC4. GSLS is a strongly typed syntax, and inconsistency will cause compilation failures.

3. Matrix data types

Mat3,mat4. Square matrix for short type float.

4. Qualifiers used for variable storage

Attribute, Uniform, and VARYING are commonly used.

5. Three common variable modifiers

Attribute:

  1. Can only be passed to and used in vertex shaders
  2. Purpose: Modify vertices, texture coordinates, colors, normals, etc., data related to coordinates and colors (e.g.attribute vec4 position;)
  3. By calling the clientglVertex...The opening method is passed (for example:glVertexAttribPointer)
  4. Texture coordinates are not available here. The purpose of the text is to bridge to the fragment shader using the same declaration of the vertex and the fragment shader with the VARYING modifier

Uniform:

  1. Can be passed to both vertex shaders and slice shaders. Pass some variable that will not change in the shader, which can also be thought of as a constant
  2. Purpose: View matrix, projection matrix, projection view matrix (e.g.uniform mat4 viewProMatrix;)
  3. Used on the clientglUniform...Method to pass
  4. If you pass uniform from the client to both vertex and slice shaders, you need to declare exactly the same in vertex and slice shaders

Varying:

  1. Attribute cannot pass texture coordinates to the fragment shader. In this case, varying is used as a bridge (e.g.varying lowp vec2 varyTextCoord;)
  2. But you have to make sureVertex shaderandChip shaderIn order for the pixel shader to get texture coordinates, keep the same declaration.

Vertex shader. VSH

// Note: Do not use Chinese annotations in real projects, as they will cause problems when compiled into strings. attribute vec4 position; //4 dimensional vector - vertex coordinate attribute ve2 textCoordinate; Varying LOWp VEC2 varyTextCoord; Void main() {varyTextCoord = textCoordinate; // bridge texture coordinates to FSH gl_Position = position; // The final vertex result is assigned to the GLSL built-in variable 'gl_Position'}Copy the code

Chip shader. FSH

// Note: Do not use Chinese annotations in real projects, as they will cause problems when compiled into strings. precision highp float; Varying lowp VEC2 varyTextCoord specifies a small error. Varying lowp VEC2 varyTextCoord specifies a variable. Uniform sampler2D colorMap; // Uniform sampler2D colorMap; // Texture void main() {** ** Note ** If there are 1000 pixels, the shard shader will execute 1000 times. There is no GPU when the emulator is running. It's the CPU that simulates the GPU. */ / Finally, the color of each individual pixel is assigned to the built-in variable gl_FragColor //texture2D (texture, texture coordinates) return pixel. Gl_FragColor = texture2D(colorMap,varyTextCoord); }Copy the code

6, OpenGL ES error handling

If the OpenGL ES command is not used correctly, the application will generate an error encoding. This error code will be logged and can be queried using glGetError. No other error code is logged until the application queries the first error code with glGetError. Once the error code is queried, the current error code is reset to GL_NO_ERROR

Custom shaders & custom application apis

1. Compilation and linking of shaders and programs

To render using a shader, you need to create two basic objects: a shader object and a degree object. The general compilation & linking of the shader object after obtaining the link is divided into 6 steps:

  1. Create a vertex shader object and a fragment shader object
  2. Link the source code to each shader object
  3. Compile the shader object
  4. Create a program object
  5. Connects the compiled shader object to the program object
  6. Linker object

2. Custom shader API

Let’s first look at the general steps for using shaders:

  1. Create vertex shader and slice shaderglCreateShader
  2. Specify the source for the shaderglShaderSource
  3. Compile the shaderglCompileShader

Create shader (handle is an ID)

GLuint glCreateShader(GLenum type); Type - the type of shader to create,GL_VERTEX_SHADER or GL_FRAGMENT_SHADER return value - is a handle to the new shader object (the handle is an ID).Copy the code

delete

void glDeleteShader(GLuint shader); Shader - Handle to the shader object to deleteCopy the code

Specifies the shader’s source (count is usually 1)

void glShaderSource(GLuint shader , GLSizei count ,const GLChar * const *string, const GLint *length); Shader -- Handle to the shader object count -- Number of shader source strings. Shaders can consist of multiple source strings, but each shader has only one main function string -- Pointer to array length of the shader source string that holds the number count -- Pointer to an array of integers holding the size of each shader string and the number of elements countCopy the code

Compiler shader

void glCompileShader(GLuint shader); Shader - Handle to the shader object to compileCopy the code

Gets a parameter to the shader

void glGetShaderiv(GLuint shader , GLenum pname , GLint *params ); Shader - shader object handle pname to be compiled - information parameters can be GL_COMPILE_STATUS/GL_DELETE_STATUS/ GL_INFO_LOG_LENGTH/GL_SHADER_SOURCE_LENGTH/ GL_SHADER_TYPE params - Pointer to the integer storage location of the query result.Copy the code

Get shader information log

void glGetShaderInfolog(GLuint shader , GLSizei maxLength, GLSizei *length , GLChar *infoLog); Shader - shader object handle to get information log maxLength - size of cache to hold information log length - length of information log to be written (minus null terminator); If you don't need to know the length. This parameter can be Null infoLog - a pointer to the character cache where information logs are stored.Copy the code

3, custom program API

Let’s take a look at the general steps used for the program:

  1. Create a Program objectglCreateProgram
  2. The shader is attached to the programglAttachShader
  3. Link to the programglLinkProgram
  4. Use the programglUseProgram

Create a program object

GLUint glCreateProgram() returns a handle to execute the new program objectCopy the code

delete

Void glDeleteProgram(GLuint Program) Program: Refers to the handle of the program object to be deletedCopy the code

Attaching shaders to programs (attaching shaders to programs)

void glAttachShader( GLuint program , GLuint shader ); Shader: Handle to the shader object connected to the programCopy the code

Disconnect the link

void glDetachShader(GLuint program); Shader: Handle to the shader object from which the program is disconnectedCopy the code

Link to the program

GlLinkProgram (GLuint Program) Program: Handle to a program objectCopy the code

Check whether the link was successful

void glGetProgramiv (GLuint program,GLenum pname, GLint *params); Program: handle to the program object that needs to obtain information pname: parameter to obtain information, which can be: GL_ACTIVE_ATTRIBUTES GL_ACTIVE_ATTRIBUTES_MAX_LENGTH GL_ACTIVE_UNIFORM_BLOCK GL_ACTIVE_UNIFORM_BLOCK_MAX_LENGTH GL_ACTIVE_UNIFROMS GL_ACTIVE_UNIFORM_MAX_LENGTH GL_ATTACHED_SHADERS GL_DELETE_STATUS GL_INFO_LOG_LENGTH GL_LINK_STATUS GL_PROGRAM_BINARY_RETRIEVABLE_HINT GL_TRANSFORM_FEEDBACK_BUFFER_MODE GL_TRANSFORM_FEEDBACK_VARYINGS GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH GL_VALIDATE_STATUS params: pointer to the integer storage location of the query resultCopy the code

Get information from the program information log

void glGetPorgramInfoLog( GLuint program ,GLSizei maxLength, GLSizei *length , GLChar *infoLog ) program : MaxLength: specifies the size of the cache where the information log is stored. Length: Specifies the length of the information log to be written (minus the null terminator). If the length is not required, this parameter can be null.infolog: Pointer to the character cache where information logs are storedCopy the code

Use the program

Void glUseProgram(GLuint Program) Program: Program object handle set to the active programCopy the code