My OpenGL thematic learning directory, hope to learn with you exchange progress!
- OpenGL Learning (I) – Terminology understanding
- OpenGL learning (2) — Xcode build OpenGL environment
- OpenGL learning (three) – OpenGL base rendering
- OpenGL learning (4) – front & back culling and depth testing
- OpenGL Learning (5) – Cropping and Blending
- OpenGL Learning (6) – Base textures
- OpenGL Learning (7) — Summary of basic change Comprehensive Exercise practice
- OpenGL ES Learning (8)
- OpenGL learning (nine) — OpenGL ES preliminary exploration (next) GLKit
- OpenGL learning (10) – GLSL syntax introduction
- OpenGL learning (11) – using GLSL to load pictures
- OpenGL learning (12) — OpenGL ES texture flipping strategy comparison
One, foreword
If you use GLSL to load an image, but finally found that the image is loaded upside down, this is why?
Because OpenGL requires the y coordinate to be at the bottom of the image, the y coordinate is usually at the top of the image. How do you solve this? Here are five strategies to choose from.
Second, texture flip strategy
1. Modify the mapping between texture coordinates and vertex coordinates
The reason why the image is inverted is that the mapping between texture coordinates and vertex coordinates is wrong, so we just need to correct the mapping. This method is the most direct, the most primitive, and once and for all, but easy to make confused mistakes in the corresponding time.
//6. Set vertex and texture coordinates // the first three are vertex coordinates and the last two are texture coordinates // GLfloatAttrArr [] = / / {f/f / 0.5, 0.5, 1.0 f, f 1.0, 0.0, f/f / 0.5, 0.5 f to 1.0 f, f 0.0, 1.0, f/f / 0.5, 0.5, f to 1.0 f, 0.0 f, 0.0 f, / / / f / 0.5, 0.5 f to 1.0 f, f 1.0, 1.0, f/f / 0.5, and 0.5 f to 1.0 f, f 0.0, 1.0, f/f / 0.5, - 0.5 f to 1.0 f, f 1.0, 0.0, f / /}; GLfloatAttrArr [] = {0.5 f to 0.5 f to 1.0 f to 1.0 f to 1.0 f to 0.5 f to 0.5 f to 1.0 f to 0.0 f to 0.0 f to 0.5 f to 0.5 f to 1.0 f to 0.0 f to 1.0 f to 0.5 f, 0.5 f to 1.0 f, f, 1.0 0.0 f to 0.5 f, 0.5 f to 1.0 f, 0.0 f, f 0.0, 0.5, f - 0.5 f to 1.0 f, f 1.0, 1.0, f};Copy the code
2. Rotate matrix to flip graph, not texture
- In the vertex shader shaderv.vsh, we pass in a rotation matrix rotateMatrix. Because matrices cannot be modified after passing in, we use uniform to modify the matrix mat4 with 4 rows and 4 columns. Then multiply the rotateMatrix rotation matrix by the vertex coordinates vPos, applying the rotation changes to each vertex.
⚠️ note that it can only be vPos * rotateMatrix, the order cannot be reversed, because the vertices are 1 row and 4 columns, and the rotation matrix is 4 rows and 4 columns. Shaderv. In VSH:
attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;
varying lowp vec2 varyTextCoord;
void main() {
varyTextCoord = textCoordinate;
vec4 vPos = position;
vPos = vPos * rotateMatrix;
gl_Position = vPos;
}
Copy the code
Source code:
- (void)rotateTextureImage { Rotate = uniform property in shaderv. VSH. RotateMatrix GLuint rotate = glGetUniformLocation(self.myame,"rotateMatrix"); //2. Obtain the shading rotation radian, degree radianfloatRadians = 180 * 3.14159f / 180.0f; //3. Find the sine and cosine values for radiansfloat s = sin(radians);
floatc = cos(radians); OpenGL ES uses column vectors /* reference z-axis rotation matrix */ GLfloat zRotation[16] = {
c,-s,0,0, s,c,0,0, 0,0,1, 0,0,0,1}; /* glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) transpose value: Rotate */ glUniformMatrix4fv(rotate, 1, GL_FALSE, zRotation); }Copy the code
3. When unzipping the image, flip the source file
Use the following three lines of code to pan and scale the image and then redraw it.
CGContextTranslateCTM(spriteContext, 0, rect.size.height);
CGContextScaleCTM(spriteContext, 1.0, -1.0);
CGContextDrawImage(spriteContext, rect, spriteImage);
Copy the code
The overall code for loading a texture from an image is as follows:
SetupTexture :(NSString *)fileName {//1, convert UIImage to CGImageRef CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage; Size_t width = CGImageGetWidth(spriteImage); size_t height = CGImageGetHeight(spriteImage); GLubyte * spriteData = (GLubyte *) calloc(width * height *4, sizeof(GLubyte)); CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4,CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast); CGRect rect = CGRectMake(0, 0, width, height); //CGContextDrawImage(spriteContext, rect, spriteImage); // Render CGContextTranslateCTM(spriteContext, 0, rect.sie.height); CGContextScaleCTM (spriteContext, 1.0, 1.0); CGContextDrawImage(spriteContext, rect, spriteImage); CGContextRelease(spriteContext); // bind texture to default texture ID glBindTexture(GL_TEXTURE_2D, 0); GlTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);floatfw = width, fh = height; GlTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, fw, fH, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData); //11. Free spriteData free(spriteData);return 0;
}
Copy the code
4. Modify texture coordinates in the slice shader
Here is the code to modify the slice shader, the x coordinate is not moving, change the y coordinate to 1-y, so that the flip effect is achieved. Leave the rest of the code untouched.
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main() {
//gl_FragColor = texture2D(colorMap, varyTextCoord);
gl_FragColor = texture2D(colorMap, vec2(varyTextCoord.x,1.0-varyTextCoord.y));
}
Copy the code
5. Modify texture coordinates in the vertex shader
When the vertex shader comes in, it flips. The number of executions is much less than the above slice shader, with several vertices executed several times.
attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;
void main() {
varyTextCoord = vec2(textCoordinate.x,1.0-textCoordinate.y);
gl_Position = position;
}
Copy the code
The above five methods can solve the problem of image inversion. The first method is the most direct and original modification method, but it is easy to make mistakes in mapping relationship. The second and third are more troublesome. The latter two are the easiest to change with just one line of code, so it’s up to you. Finally, you have the image of the head!
Reprint please note the original source, shall not be used for commercial communication – any more