OpenGL的紋理坐標是左下角的,而圖片的坐標是在左上角的,所以畫上去的時候會是倒立的,有五種方法可以使圖片正過來
1.直接修改源紋理坐標數(shù)據(jù)
//前3個是頂點坐標,后2個是紋理坐標
翻轉前:
GLfloat attrArr[] =
{
0.5f, -0.5f, -1.0f, 1.0f, 0.0f,//右下
-0.5f, 0.5f, -1.0f, 0.0f, 1.0f,//左上
-0.5f, -0.5f, -1.0f, 0.0f, 0.0f,//左下
0.5f, 0.5f, -1.0f, 1.0f, 1.0f,//右上
-0.5f, 0.5f, -1.0f, 0.0f, 1.0f,//左上
0.5f, -0.5f, -1.0f, 1.0f, 0.0f,//右下
};
翻轉后:
GLfloat attrArr[] =
{
0.5f, -0.5f, -1.0f, 1.0f, 1.0f,
-0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, -1.0f, 0.0f, 1.0f,
0.5f, 0.5f, -1.0f, 1.0f, 0.0f,
-0.5f, 0.5f, -1.0f, 0.0f, 0.0f,
0.5f, -0.5f, -1.0f, 1.0f, 1.0f,
};
2.修改片元著色器紋理坐標
只需要修改y軸的坐標即可。
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
修改前:
void main()
{
gl_FragColor = texture2D(colorMap, varyTextCoord);
}
修改后:
void main()
{
gl_FragColor = texture2D(colorMap, vec2(varyTextCoord.x,1.0-varyTextCoord.y));
}
3.修改頂點著色器紋理坐標
片元著色器的紋理坐標是通過頂點著色器傳遞過去,同理修改頂點著色器的紋理坐標。
attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;
修改前:
void main()
{
varyTextCoord = textCoordinate;
gl_Position = position;
}
修改后:
void main()
{
varyTextCoord = vec2(textCoordinate.x,1.0-textCoordinate.y);
gl_Position = position;
}
4.旋轉矩陣翻轉圖形,不翻轉紋理
讓圖形頂點坐標旋轉180°. 而紋理保持原狀
- (void)rotateTextureImage
{
//注意,想要獲取shader里面的變量,這里記得要在glLinkProgram后面,后面,后面!
//rotate等于shaderv.vsh中的uniform屬性,rotateMatrix
GLuint rotate = glGetUniformLocation(self.myPrograme, "rotateMatrix");
float radians = 180 * 3.14159f / 180.0f;
float s = sin(radians);
float c = cos(radians);
GLfloat zRotation[16] = {
c,-s,0,0,
s,c,0,0,
0,0,1,0,
0,0,0,1
};
glUniformMatrix4fv(rotate, 1, GL_FALSE, zRotation);
}
//對應的shaderv.vsh
attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;
varying lowp vec2 varyTextCoord;
void main()
{
varyTextCoord = textCoordinate;
//讓每一個頂點坐標應用旋轉矩陣
gl_Position = position * rotateMatrix;
}
上面主要參考的是圍繞Z軸旋轉

image.png
5.圖片解壓縮時,翻轉源文件
CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage;
size_t width = CGImageGetWidth(spriteImage);
size_t height = CGImageGetHeight(spriteImage);
//獲取圖片字節(jié)數(shù) 寬*高*4(RGBA)
GLubyte * spriteData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
//創(chuàng)建上下文
/*
參數(shù)1:data,指向要渲染的繪制圖像的內存地址
參數(shù)2:width,bitmap的寬度,單位為像素
參數(shù)3:height,bitmap的高度,單位為像素
參數(shù)4:bitPerComponent,內存中像素的每個組件的位數(shù),比如32位RGBA,就設置為8
參數(shù)5:bytesPerRow,bitmap的沒一行的內存所占的比特數(shù)
參數(shù)6:colorSpace,bitmap上使用的顏色空間 kCGImageAlphaPremultipliedLast:RGBA
*/
CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4,CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
//在CGContextRef上--> 將圖片繪制出來
/*
CGContextDrawImage 使用的是Core Graphics框架,坐標系與UIKit 不一樣。
UIKit框架的原點在屏幕的左上角,Core Graphics框架的原點在屏幕的左下角。
CTM(current transformation matrix當前轉換矩陣)
*/
CGContextTranslateCTM(spriteContext, 0, rect.size.height);
CGContextScaleCTM(spriteContext, 1.0, -1.0);
CGContextDrawImage(spriteContext, rect, spriteImage);
CGContextRelease(spriteContext);
//綁定紋理到默認的紋理ID
glBindTexture(GL_TEXTURE_2D, 0);
free(spriteData);