OpenGL
的紋理坐標(biāo)是左下角的,而圖片的坐標(biāo)是在左上角的冰沙,所以畫(huà)上去的時(shí)候會(huì)是倒立的,有五種方法可以使圖片正過(guò)來(lái)
1.直接修改源紋理坐標(biāo)數(shù)據(jù)
//前3個(gè)是頂點(diǎn)坐標(biāo)执虹,后2個(gè)是紋理坐標(biāo)
翻轉(zhuǎn)前:
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,//右下
};
翻轉(zhuǎn)后:
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.修改片元著色器紋理坐標(biāo)
只需要修改y軸的坐標(biāo)即可拓挥。
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.修改頂點(diǎn)著色器紋理坐標(biāo)
片元著色器的紋理坐標(biāo)是通過(guò)頂點(diǎn)著色器傳遞過(guò)去,同理修改頂點(diǎn)著色器的紋理坐標(biāo)袋励。
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.旋轉(zhuǎn)矩陣翻轉(zhuǎn)圖形,不翻轉(zhuǎn)紋理
讓圖形頂點(diǎn)坐標(biāo)旋轉(zhuǎn)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);
}
//對(duì)應(yīng)的shaderv.vsh
attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;
varying lowp vec2 varyTextCoord;
void main()
{
varyTextCoord = textCoordinate;
//讓每一個(gè)頂點(diǎn)坐標(biāo)應(yīng)用旋轉(zhuǎn)矩陣
gl_Position = position * rotateMatrix;
}
上面主要參考的是圍繞Z軸旋轉(zhuǎn)
image.png
5.圖片解壓縮時(shí)赁炎,翻轉(zhuǎn)源文件
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,指向要渲染的繪制圖像的內(nèi)存地址
參數(shù)2:width,bitmap的寬度,單位為像素
參數(shù)3:height,bitmap的高度钾腺,單位為像素
參數(shù)4:bitPerComponent,內(nèi)存中像素的每個(gè)組件的位數(shù)徙垫,比如32位RGBA讥裤,就設(shè)置為8
參數(shù)5:bytesPerRow,bitmap的沒(méi)一行的內(nèi)存所占的比特?cái)?shù)
參數(shù)6:colorSpace,bitmap上使用的顏色空間 kCGImageAlphaPremultipliedLast:RGBA
*/
CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4,CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
//在CGContextRef上--> 將圖片繪制出來(lái)
/*
CGContextDrawImage 使用的是Core Graphics框架,坐標(biāo)系與UIKit 不一樣松邪。
UIKit框架的原點(diǎn)在屏幕的左上角坞琴,Core Graphics框架的原點(diǎn)在屏幕的左下角。
CTM(current transformation matrix當(dāng)前轉(zhuǎn)換矩陣)
*/
CGContextTranslateCTM(spriteContext, 0, rect.size.height);
CGContextScaleCTM(spriteContext, 1.0, -1.0);
CGContextDrawImage(spriteContext, rect, spriteImage);
CGContextRelease(spriteContext);
//綁定紋理到默認(rèn)的紋理ID
glBindTexture(GL_TEXTURE_2D, 0);
free(spriteData);