GPUImage源碼閱讀(二):texture頂點設置

一、UIKit和Core Graphics的坐標系不同

在iOS中,存在兩個坐標系:

  • 左上角為原點的坐標系(upper-left-origin,ULO),例如UIKit和Core Animation
  • 左下角為原點的坐標系(lower-left-origin,LLO),例如Core Graphics

如下圖所示:

由于兩個坐標系不同,如果直接在屏幕顯示由Core Graphics加載的圖片,那么看到的圖片效果是「上下顛倒」的。

因此在圖片顯示之前,需要手動將圖片「上下翻轉」以達到預期的效果。有兩種方式:

  1. 通過修改CTM(current transformation matrix)來翻轉默認坐標系

    代碼示例:

     CGContextSaveGState(graphicsContext);
     CGContextTranslateCTM(graphicsContext, 0.0, imageHeight);
     CGContextScaleCTM(graphicsContext, 1.0, -1.0);
     CGContextDrawImage(graphicsContext, image, CGRectMake(0, 0, imageWidth, imageHeight));
     CGContextRestoreGState(graphicsContext);
    
  2. 在圖片顯示時手動翻轉

GPUImage采用的是第二種方式。

二、GPUImage中的texture頂點設置

在OpenGL ES中,texture的原始坐標系如下:

可以看到,左下角是原點,從左到右、從下到上坐標依次遞增。

對于用來render的GPUImageView來說,kGPUImageNoRotation對應的就是將texture的坐標系上下翻轉,其他旋轉方式則根據(jù)翻轉后的坐標系確定。

下面是我總結的不同旋轉方式對應的坐標:

對應的代碼為:

static const GLfloat noRotationTextureCoordinates[] = {
    0.0f, 1.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,
    1.0f, 0.0f,
};

static const GLfloat rotateRightTextureCoordinates[] = {
    1.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    0.0f, 0.0f,
};

static const GLfloat rotateLeftTextureCoordinates[] = {
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
};
    
static const GLfloat verticalFlipTextureCoordinates[] = {
    0.0f, 0.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,
};

static const GLfloat horizontalFlipTextureCoordinates[] = {
    1.0f, 1.0f,
    0.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 0.0f,
};

static const GLfloat rotateRightHorizontalFlipTextureCoordinates[] = {
    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,
};

static const GLfloat rotateRightVerticalFlipTextureCoordinates[] = {
    0.0f, 1.0f,
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f,
};

static const GLfloat rotate180TextureCoordinates[] = {
    1.0f, 0.0f,
    0.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 1.0f,
};

那么對于GPUImageFilter中的坐標呢?kGPUImageNoRotation對應的當然是texture的原始坐標系,但是旋轉的坐標不能簡單地據(jù)此確定,而要考慮到最終上下翻轉后可以得到預期的效果。舉例來說,如果要實現(xiàn)翻轉后是右轉的效果,那么翻轉前對應的應該是左轉。其他旋轉方式可以類似地推理得到。

下面是我總結的不同旋轉對應的坐標:

對應的代碼為:

static const GLfloat noRotationTextureCoordinates[] = {
    0.0f, 0.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 1.0f,
};

static const GLfloat rotateLeftTextureCoordinates[] = {
    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 0.0f,
    0.0f, 1.0f,
};

static const GLfloat rotateRightTextureCoordinates[] = {
    0.0f, 1.0f,
    0.0f, 0.0f,
    1.0f, 1.0f,
    1.0f, 0.0f,
};

static const GLfloat verticalFlipTextureCoordinates[] = {
    0.0f, 1.0f,
    1.0f, 1.0f,
    0.0f,  0.0f,
    1.0f,  0.0f,
};

static const GLfloat horizontalFlipTextureCoordinates[] = {
    1.0f, 0.0f,
    0.0f, 0.0f,
    1.0f,  1.0f,
    0.0f,  1.0f,
};

static const GLfloat rotateRightHorizontalFlipTextureCoordinates[] = {
    0.0f, 0.0f,
    0.0f, 1.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
};

static const GLfloat rotateRightVerticalFlipTextureCoordinates[] = {
    1.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 1.0f,
    0.0f, 0.0f,
};

static const GLfloat rotate180TextureCoordinates[] = {
    1.0f, 1.0f,
    0.0f, 1.0f,
    1.0f, 0.0f,
    0.0f, 0.0f,
};

三、參考文獻

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容