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