系列推薦文章:
OpenGL/OpenGL ES入門:圖形API以及專業名詞解析
OpenGL/OpenGL ES入門:渲染流程以及固定存儲着色器
OpenGL/OpenGL ES入門:圖像渲染實現以及渲染問題
OpenGL/OpenGL ES入門:基礎變換 - 初識向量/矩陣
OpenGL/OpenGL ES入門:紋理初探 - 經常使用API解析
OpenGL/OpenGL ES入門: 紋理應用 - 紋理座標及案例解析(金字塔)
OpenGL/OpenGL ES入門: 頂點着色器與片元着色器(OpenGL過渡OpenGL ES)
OpenGL/OpenGL ES入門: GLKit以及API簡介
OpenGL/OpenGL ES入門: GLKit使用以及案例
OpenGL/OpenGL ES入門: 使用OpenGL ES 渲染圖片
OpenGL/OpenGL ES入門:iOS紋理翻轉策略解析
OpenGL ES入門: 渲染金字塔 - 顏色、紋理、紋理與顏色混合填充以及GLKit實現數組
在上一篇文章OpenGL/OpenGL ES入門: 使用OpenGL ES 渲染圖片的案例二中渲染圖片時,CGContextDrawImage 使用的是Core Graphics框架,座標系與UIKit不同。UIKit框架的原點在屏幕的左上角,Core Graphics框架的原點在屏幕的左下角,致使了圖片翻轉的問題,同時也提出了一種解決方案,這篇文章,咱們總結一下關於解決圖片翻轉的策略。bash
CGRect rect = CGRectMake(0, 0, width, height);
CGContextTranslateCTM(spriteContext, 0, rect.size.height);
CGContextScaleCTM(spriteContext, 1.0, -1.0);
CGContextDrawImage(spriteContext, rect, spriteImage);
複製代碼
第一種也是在上篇文章OpenGL/OpenGL ES入門: 使用OpenGL ES 渲染圖片中使用的方案,具體的翻轉實現都有詳細的說明,須要瞭解的小夥伴能夠前去查看。框架
思路:讓圖形的全部頂點都旋轉180度,紋理座標不用改變
在頂點着色器中聲明一個uniform,傳入一個旋轉矩陣,使每一個頂點都進行旋轉post
attribute vec4 position;
uniform mat4 rotationMatrix;
void main() {
vec4 vPos;
vPos = position * rotationMatrix;
gl_Position = vPos;
}
複製代碼
而後獲取這個旋轉矩陣的入口通道,進行賦值:ui
// rotate等於shaderv.vsh中的uniform屬性,rotateMatrix
GLuint rotate = glGetUniformLocation(self.myProgram, "rotationMatrix");
// 獲取渲旋轉的弧度
float radians = 180 * 3.14159f / 180.0f;
// 求得弧度對於的sin\cos值
float s = sin(radians);
float c = cos(radians);
// z軸旋轉矩陣
GLfloat zRotation[16] = {
c, -s, 0, 0,
s, c, 0, 0,
0, 0, 1.0, 0,
0.0, 0, 0, 1.0
};
// 設置旋轉矩陣
/*
glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
location : 對於shader 中的ID
count : 個數
transpose : 轉置
value : 指針
*/
glUniformMatrix4fv(rotate, 1, GL_FALSE, (GLfloat *)&zRotation[0]);
複製代碼
蘋果文檔關於單元矩陣,平移,縮放,圍繞x,y,z軸旋轉的矩陣 spa
思路:改變頂點數據的紋理座標,翻轉y值(用1減去y座標)3d
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main()
{
gl_FragColor = texture2D(colorMap, vec2(varyTextCoord.x, 1.0 - varyTextCoord.y));
}
複製代碼
思路,同第三種同樣,只不過紋理座標的修改,放在了頂點着色器中指針
attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;
void main()
{
varyTextCoord = vec2(textCoordinate.x, 1.0 - textCoordinate.y);
gl_Position = position;
}
複製代碼
思路:最後一種方法是在生成頂點數組的時候,直接改變紋理座標的映射方式code
GLfloat attrArr[] =
{
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, //右下
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, // 左上
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // 左下
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // 右上
-0.5f, 0.5f, 0.0f, 0.0f, 0.0f, // 左上
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, // 右下
};
複製代碼
我的感受這種方式是最實在的方式,在一開始就杜絕了圖片翻轉的問題。orm
總結: 以上5種方法,均可以解決咱們遇到的圖片翻轉的問題,在實際開發當中,具體使用哪種方式,看你們的心情。
在OpenGL/OpenGL ES入門: GLKit使用以及案例文章中,在使用GLKit渲染圖片的過程裏,其實咱們也遇到了圖片翻轉的問題,只不過由於GLKit封裝的緣由,咱們使用一段代碼設置紋理屬性的過程當中就能解決圖片翻轉問題,感興趣的小夥伴也能夠區查看一下。
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
複製代碼