10.GLKit & GLSL loading images

OpenGL ES method for using shaders

GLuint glCreateShader(GLenum type) type: the type of shader created GL_VERTEX_SHADER /GL_FRAGMENT_SHADER Void glDeleteShader(GLuint Shader) shader: Void glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, GLuint shader, GLsizei count, const GLchar *const *string, Const GLint *length) shader: handle to the shader count: Number of source strings used by the shader. A shader can consist of multiple source strings, but each shader has only one main function. String: pointer length to an array of source strings: Void glCompileShader(GLuint Shader) shader: Void glGetShaderiv(GLuint Shader,GLenum pname,GLint *params) shader: shader object to query pname: Params: a pointer to the result of the query information

Pname Enumeration of query information Params Query result
GL_SHADER_TYPE(shader type) GL_VERTEX_SHADER(vertex shader), GL_FRAGMENT_SHADER(slice shader)
GL_DELETE_STATUS(whether shader is deleted) GL_TRUE(deleted), GL_FALSE(not deleted)
GL_COMPILE_STATUS GL_TRUE(compile succeeded), GL_FALSE(compile failed)
GL_INFO_LOG_LENGTH(length of shader information log) Returns the length of the information log for the shader, including null terminating characters (that is, the size of the character buffer needed to store the information log). If the shader has no information log, the value 0 is returned
GL_SHADER_SOURCE_LENGTH(shader source length) Returns the shader source length, or 0 if none exists

Void glGetShaderInfoLog(GLuint shader, GLsizei maxLength, GLsizei * Length, GLchar *infoLog) shader: MaxLength: Specifies the size of the character buffer used to store the returned information log. Length: Specifies the length of the string (excluding NULL terminators) of the returned information log. If length is not required, this parameter can be set to NULL infoLog: CreateProgram GLuint glCreateProgram(void) Program object is a handle to return program that can be attached to the shader object delete Program void glDeleteProgram(GLuint) Void glAttachShader(GLuint Program, GLuint Shader) program: Void glDetachShader(GLuint Program, GLuint Shader) Program: Program handle shader: Void glLinkProgram(GLuint Program) program: Void glGetProgramiv(GLuint Program, GLenum pname, GLint *params) program: program handle pname: Params: a pointer to the result of the query information

Pname Enumeration of query information Params Query result
GL_DELETE_STATUS(delete or not) GL_TRUE, GL_FALSE
GL_LINK_STATUS(was the last link operation of program successful) GL_TRUE, GL_FALSE
GL_VALIDATE_STATUS(program last validation was successful) GL_TRUE, GL_FALSE
| GL_INFO_LOG_LENGTH(Log length) Returns the number of characters in the Program information log, including null terminating characters (the size of the character buffer required to store the information log). If the program has no information log, the value 0 is returned
GL_ATTACHED_SHADERS(number of shader objects) Returns the number of shader objects appended to program
GL_ACTIVE_ATTRIBUTES Returns the number of program’s active state property variables
GL_ACTIVE_ATTRIBUTE_MAX_LENGTH Returns the length of the property name for the longest active state of program, including null terminating characters (the size of the character buffer needed to store the longest property name). If no active attribute exists, 0 is returned
GL_ACTIVE_UNIFORMS Returns the number of uniform variables for program’s active state
GL_ACTIVE_UNIFORM_MAX_LENGTH Returns the length of the uniform variable name for the longest active state of program, including null terminating characters (the size of the character buffer required to store the longest uniform variable name). If no active uniform variable exists, 0 is returned

GLint glGetAttribLocation(GLuint Program,const GLchar *name) program: Program handle name: Void glGetProgramInfoLog(GLuint Program, GLsizei maxLength, GLsizei *length, GLuint program, GLsizei *length, GLchar *infoLog) shader: program handle to be queried maxLength: specifies the size of the character buffer used to store the returned information log length: The string length of the returned information log (excluding the NULL terminator). If no length is required, this parameter can be set to NULL. InfoLog: The returned information log uses program void glUseProgram(GLuint Program)

FrameBuffer & RenderBuffer

The RenderBuffer object (RBO) is a 2D image cache allocated by the application. Renderbuffers can be used to store colors, depths, or template values. It can also be used as a color, depth, template attachment in the framebuffer. The RenderBuffer is similar to the drawable surface provided by the screen window system. For example, pBuffer. Renderbuffers cannot be used directly like GL textures. The FrameBuffer object (FBO) is a color, depth, and attachment point to the template cache area. The state of the description attribute, such as color, depth, and size and format of the template cache, is associated with the Frame Buffer Object (FBO). The texture name and the renderBuffer object are also associated with the FBO. A variety of 2D graphics can be attached to points by colors attached to the framebuffer object. They contain color values stored by the RenderBuffer object, a 2D texture, or a cube map. Or a MIP-level 2d slice in 3D texture. Also, various 2D graphics containing current depth values can be attached to an FBO depth attachment point. The only two-dimensional image that can be attached to FBO’s template attachment point is a RenderBuffer object that stores template values.

OpenGL ES Three variable modifiers (Uniform, attribute/ IN, VARYING/OUT)

Uniform passes values to vertex shaders and fragment shaders, but does not modify the values passed inside the shader, In 3.0, VARYING is only transmitted to the vertex shader. In 3.0, VARYING is out. Generally, the attribute is used to pass values from the vertex shader to the chip shader. Passing the value from the vertex shader to the fragment shader is accomplished by defining an input value of the same type and name, also modified with VARYING.

GLSL shader exploration

Try not to write comments in GLSL shaders, which may cause compilation errors in vertex shaders

attribute vec4 position; // Input the vertex coordinate attribute vec2 textCoordinate; // The input texture coordinates varying lowp VEC2 varyTextCoord; Void main() {varyTextCoord = textCoordinate; // Print the texture coordinates gl_Position = position with varyTextCoord varying. //gl_Position is a built-in variable that must be assigned to store vertex data}Copy the code

Chip shader

varying lowp vec2 varyTextCoord; Uniform sampler2D colorMap; // The input texture coordinates (varying modifiers, representing output from the vertex shader) are uniform sampler2D colorMap; Void main() {gl_FragColor = texture2D(colorMap, varyTextCoord); void main() {gl_FragColor = texture2D(colorMap, varyTextCoord); Vec4 texture2D(sampler2D sampler, vec2 coord) : a built-in function to obtain the texture coordinates of the pixel pixels (pixel color: pixel color) */Copy the code

GLSL precision modifier use

The vertex shader has default precision, and the chip shader does not need to set its own high precision lowp precision in Mediump. The lower the precision value, the more efficient the execution. But according to the length of the stored data to select the appropriate precision before the specified variable to modify the current variable precision

highp vec4 position;
varying lowp vec4 color;
mediump float specularExp;
Copy the code

At the beginning of the shader source, modifies the global default precision

precision precision-qualifier type; Precision: a fixed qualifier describing the default precision precision-Qualifier precision type Data type Example: Precision highp floatCopy the code

GLSL common data type

Vector (vec)

type describe
Vec2, VEC3, vec4 2 -, 3 -, 4 – dimensional floating point vectors
Ivec2, IVEC3, IVEC4 Two dimensional, three dimensional, four dimensional integral vector
Uvec2, UVEC3, uVEC4 2 -, 3 -, 4 – dimensional unsigned integer vector
Bvec2, BVEC3, bVEC4 2 -, 3 -, 4 – dimensional Boolean vectors

Matrix data type (MAT column x row)

type describe
Mat2, mat2x2 2 row, 2 column matrix
Mat3, mat3x3 3 row, 3 column matrix
Mat4, mat4x4 Four row, four column matrix
mat2x3 Three row, two column matrix
mat2x4 Four row, two column matrix
mat3x2 2 row, 3 column matrix
mat3x4 4 row, 3 column matrix
mat4x2 Two row, four column matrix
mat4x3 Three row, four column matrix

Variables store qualifiers

qualifiers describe
<none> No qualifier They are ordinary local variables that are not externally visible or accessible
const Compile constants, or read-only arguments to functions
, varying in Variables passed in from the previous stage
In CENTroID, VARYING CentroID Variables passed in from the previous stage. Centroid is the centroid sampling keyword used to avoid artifacts and is not available for vertex shaders
Out, the attribute Pass to the next stage or specify the return value in the function
Out centroID, attribute CentroID Variables passed to the next stage. Centroid is the centroid sampling keyword used to avoid artifacts and is not available for vertex shader interpolation
uniform A variable passed from client code that cannot be modified in the shader but can only be read

Precision qualifier (floating point, integer available)

qualifiers describe
highp High precision
mediump Medium accuracy
lowp Low accuracy

GLSL examples of common data types

Variables and data types

// Boolean true, false bool bValue = false; // Signed integer int iValue = 42; // unsigned integer uint uiValue = 34u; // float fValue = 3.14f;Copy the code

Vector data type

// Vector declaration, declare a 4-component float vector vec4 V1; Vec4 V2 = vec4(1,2,3,4); // vec4v; Vec4 vOldPos = vec4 (1, 2, 3, 4); Vec4 vOffset = vec4 (1, 2, 3, 4); v = vOldPos; v = vOldPos + vOffset; V + = vec4,1,1,1 (1); v = vOldPos * vOffset; v *= 5; / / vector elements, which can be used (x, y, z, w) (r, g, b, a) (s, t, p, q) to pick up, but the three said cannot mix v.x y = vec2 (2.0 f to 3.0 f); V.xyz = vec3(1.0f, 1.0f, 1.0f); V.r = 3.0 f; V.r gba = vec4 (1, 2, 3, 4); V. t = vec2 (1, 2); v.st = v2.xt; //xt = v2.xy; V1.rgba = v2.bgra; v1.rgba = v2.bgra; v1.rgba = v2.bgra; v2.bgra = v1.rgba; // assign v1.r = v2.b; v1.a = v2.a; V1.x = v2.x + 3.0f; v1.x = v2.x + 3.0f; V1.xyz = v2.xyz + vec3(2,3,4);Copy the code

matrix

// create matrix mat4 m1,m2,m3; Mat4 m1 = mat4(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1); // initialize matrix mat m4 = mat4(1.0f); Mat m3 = mat4 (1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1); // m = m2 * m3;Copy the code

constant

Const float aaa = 0.2f;Copy the code

The structure of the body

struct forStruct{ vec4 color; float start; float end; }fogVar; ,0,0.5 fogVar = fogStruct (vec4 (1, 0), 0.1, 1.3); vec4 color = fogVar.color; float start = fogVar.start;Copy the code

An array of

float floatArray[4]; vect4 vectArray[]; Float a [4] = float [] (1,2,3.0, 4.0); Vec2 c [2] = vec2 [2] (vec2 (1.0, 1.0), vec2 (1.0, 3.0));Copy the code

Functions :GLSL does not support recursive functions

When the function is defined, three modifiers are given: in: (when not specified, the default qualifiers are qualified), passed into the function, and cannot be modified by the function. (When the function returns, Vec4 myFunc(inout float myFloat, out vec4 m1, mat4 m2) {// function calculation} vec4 diffuse(vec3 normal,vec3 light, vec4 baseColor) { return baseColor * dot(normal,light); }Copy the code

Control statements

Controls support if... else... Loops only support while loops /do... While loop /for loop but try to use less logical judgment and less loop iteration in GLSLCopy the code

Write your own shaders to render images

Create your own vertex shaders and slice shaders, with arbitrary names and suffixes, and just read the strings inside them

Vertex shaderChip shaderUse a custom View for rendering, so replace the controller View

The image to render



Concrete rendering implementation

We end up with a rendering of the Z-axis rotated 180 degrees, because OpenGL’s coordinate system is different from the one shown on screen

What we want is something like this:



So how to solve this rotation problem, here are several solutions:

1. Flip texture by slice shader calculation

Personally, I don’t think this is appropriate, because this is to put the calculation into the chip shader, and the calculation is performed every time the pixel color value is assigned

We can assign gl_FragColor to the color of the flipped texture coordinates

2. Flip texture by rotating matrix

Personally, I don’t think this is appropriate, because it puts the calculation into the vertex shader, and every vertex coordinate assignment takes place

Modify the vertex shader first by passing in the rotated vertex coordinates when assigning gl_PositionThe shader is then passed a rotation matrix to do the z-flip

3. Flip texture by vertex shader calculation

Personally, I don’t think this is appropriate, because this is to put the calculation into the vertex shader, each vertex texture coordinate assignment will be evaluated

We can flip texture coordinates when the vertex shader passes texture coordinates to the slice shader

4. Flip texture by modifying vertex texture coordinates

I think it is feasible but should be noted. It is not recommended. Although the computation is not increased, but directly modify the data is easy to forget or write wrong, error rate is too high

5. Flip the image directly when loading the texture by affine transformation

Personally recommended. When the texture is loaded, directly flip the image, the calculation will not increase, writing is not easy to make mistakes, once and for all

Using affine transformation processing drawing, specific affine transformation to achieve a variety of ways, as long as the effect is achieved

So let’s summarize the way we think about flipping

First, we know that the color of each rendered pixel is determined by the built-in gl_FragColor property of the fragment shader, so when we flip the image, we actually change the color value stored by gl_FragColor. Gl_FragColor is assigned by vec4 texture2D(sampler2D sampler, VEC2 coord). The texture2D method takes two parameters: the texture sampler and the texture coordinate coord. If we modify the texture sampler, we will modify the texture, which corresponds to scheme 5 above. If you change the texture coordinate coord, the direct modification is option 1. Since the texture coordinate is passed in by the vertex shader, it can be changed in the vertex shader, corresponding to option 3. The mapping between texture coordinates and vertex coordinates in vertices is modified, corresponding to schemes 2 and 4.

See Github for code information