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的坐标系上下翻转,其他旋转方式则根据翻转后的坐标系确定。

下面是我总结的不同旋转方式对应的坐标:

对应的代码为:

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的原始坐标系,但是旋转的坐标不能简单地据此确定,而要考虑到最终上下翻转后可以得到预期的效果。举例来说,如果要实现翻转后是右转的效果,那么翻转前对应的应该是左转。其他旋转方式可以类似地推理得到。

下面是我总结的不同旋转对应的坐标:

GPUImage源码阅读(二):texture顶点设置_第1张图片

对应的代码为:

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,
};

三、参考文献

  • 官方文档:Coordinate Systems and Drawing in iOS
  • GPUImage项目地址:https://github.com/BradLarson/GPUImage

你可能感兴趣的:(GPUImage源码阅读(二):texture顶点设置)