前言
在上一個iOS開發(fā)之OpenGL ES(二) —— 快速了解并使用GLKit案例中艺栈,使用了如下代碼來做翻轉(zhuǎn),如果我們不做翻轉(zhuǎn),加載出來的圖片會是倒置的糙箍。
//紋理坐標原點是左下角,但是圖片顯示原點應(yīng)該是左上角.
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft,nil];
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
要翻轉(zhuǎn)的原因和上面的注釋所寫的差不多寸士,簡單理解一下檐什,是因為OpenGL要求y軸0.0坐標是在圖片的底部的,但是圖片的y軸0.0坐標通常在頂部弱卡。
1. 翻轉(zhuǎn)原始紋理坐標
原始頂點數(shù)組中的坐標如下:
//前3個是頂點坐標乃正,后2個是紋理坐標
GLfloat attrArr[] =
{
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
};
由于紋理坐標是0-1的,所以我們只需要用 1 減 原來的紋理坐標的y值婶博,即可完成翻轉(zhuǎn)瓮具,如下:
//前3個是頂點坐標,后2個是紋理坐標
GLfloat attrArr[] =
{
0.5f, -0.5f, -1.0f, 1.0f, 1 - 0.0f,
-0.5f, 0.5f, -1.0f, 0.0f, 1 - 1.0f,
-0.5f, -0.5f, -1.0f, 0.0f, 1 - 0.0f,
0.5f, 0.5f, -1.0f, 1.0f, 1 - 1.0f,
-0.5f, 0.5f, -1.0f, 0.0f, 1 - 1.0f,
0.5f, -0.5f, -1.0f, 1.0f, 1 - 0.0f,
};
2. 翻轉(zhuǎn)圖片源文件
在解壓過程中,可以對圖片的源文件進行翻轉(zhuǎn)名党,代碼如下:
// 第二種方法:解決翻轉(zhuǎn)問題叹阔,平移再翻轉(zhuǎn)Y軸
CGContextTranslateCTM(spriteContext, 0, rect.size.height);
CGContextScaleCTM(spriteContext, 1.0, -1.0);
CGContextDrawImage(spriteContext, rect, spriteImage);
第一步調(diào)CGContextTranslateCTM
是把spriteContext沿Y軸正方向移動圖片的高度,然后再調(diào)CGContextScaleCTM
是把圖片直接翻轉(zhuǎn)過來。
3. 通過旋轉(zhuǎn)矩陣直接旋轉(zhuǎn)圖形
在加載紋理時传睹,把圖形直接旋轉(zhuǎn)180度即可,如下先寫一個旋轉(zhuǎn)矩陣傳入頂點著色器
//解決紋理翻轉(zhuǎn)
- (void)rotateTextureImage{
//注意耳幢,想要獲取shader里面的變量,這里記得要在glLinkProgram后面欧啤,后面睛藻,后面!
//1. rotate等于shaderv.vsh中的uniform屬性邢隧,rotateMatrix
GLuint rotate = glGetUniformLocation(self.myPrograme, "rotateMatrix");
//2.獲取渲旋轉(zhuǎn)的弧度
float radias = 180 * 3.1415926 / 180.0f;
//3.求得弧度對于的sin\cos值
float s = sin(radias);
float c = cos(radias);
//4.在OpenGL ES用的是列向量
/*
參考Z軸旋轉(zhuǎn)矩陣
*/
GLfloat zRotation[16] = {
c,-s,0,0,
s,c,0,0,
0,0,1,0,
0,0,0,1
};
//5.設(shè)置旋轉(zhuǎn)矩陣
/*
glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
location : 對于shader 中的ID
count : 個數(shù)
transpose : 轉(zhuǎn)置
value : 指針
*/
glUniformMatrix4fv(rotate, 1, GL_FALSE, zRotation);
}
在頂點著色器中店印,代碼如下所示, 上面是把旋轉(zhuǎn)矩陣rotateMatrix傳入了,然后設(shè)置頂點坐標gl_Postion時倒慧,用傳入的原始頂點和傳入的roatateMatrix相乘即可完成旋轉(zhuǎn)180度按摘。
attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;
varying lowp vec2 varyTextCoord;
void main()
{
varyTextCoord = textCoordinate;
vec4 pox = position;
gl_Position = pox *rotateMatrix;
}
4. 修改著色器里的紋理坐標
我們可以修改頂點著色器里的紋理坐標或者修改片元著色器里的紋理坐標,兩種方式原理是一樣的迫靖。
修改頂點著色器
attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;
void main()
{
varyTextCoord = vec2(textCoordinate.x,1.0 - textCoordinate.y);
gl_Position = position;
}
修改片元著色器
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));
}