OpenGL/OpenGL ES入門:iOS紋理翻轉策略解析

系列推薦文章:
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];
複製代碼
相關文章
相關標籤/搜索