OpenGL/OpenGL ES入门:iOS纹理翻转策略解析

栏目: IOS · 发布时间: 5年前

内容简介:在上一篇文章第一种也是在上篇文章思路:让图形的所有顶点都旋转180度,纹理坐标不用改变

在上一篇文章 OpenGL/OpenGL ES入门: 使用OpenGL ES 渲染图片 的案例二中渲染图片时,CGContextDrawImage 使用的是Core Graphics框架,坐标系与UIKit不一样。UIKit框架的原点在屏幕的左上角,Core Graphics框架的原点在屏幕的左下角,导致了图片翻转的问题,同时也提出了一种解决方案,这篇文章,我们总结一下关于解决图片翻转的策略。

纹理翻转策略

第一种:解压图片时,将图片源文件翻转

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,传入一个旋转矩阵,使每个顶点都进行旋转

attribute vec4 position;
uniform mat4 rotationMatrix;

void main() {
    vec4 vPos;
    vPos = position * rotationMatrix;
    gl_Position = vPos;
}
复制代码

然后获取这个旋转矩阵的入口通道,进行赋值:

// 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轴旋转的矩阵

OpenGL/OpenGL ES入门:iOS纹理翻转策略解析

第三种:修改片元着色器,纹理坐标

思路:改变顶点数据的纹理坐标,翻转y值(用1减去y坐标)

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;
}
复制代码

第五种:直接从源纹理坐标数据修改

思路:最后一种方法是在生成顶点数组的时候,直接改变纹理坐标的映射方式

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, // 右下
     };
复制代码

个人感觉这种方式是最实在的方式,在一开始就杜绝了图片翻转的问题。

总结: 以上5种方法,都可以解决我们遇到的图片翻转的问题,在实际开发当中,具体使用哪一种方式,看大家的心情。

OpenGL/OpenGL ES入门: GLKit使用以及案例 文章中,在使用GLKit渲染图片的过程里,其实我们也遇到了图片翻转的问题,只不过因为GLKit封装的原因,我们使用一段代码设置纹理属性的过程中就能解决图片翻转问题,感兴趣的小伙伴也可以区查看一下。

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];    
GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

产品型社群

产品型社群

李善友 / 机械工业出版社 / 2015-3-1 / CNY 69.00

传统模式企业正在直面一场空前的“降维战争”, 结局惨烈,或生或死。 传统模式很难避免悲惨下场, 诺基亚等昔日庞然大物轰然倒塌, 柯达发明了数码成像技术却依然破产, 新商业的兴起到底遵循的是什么模式? 微信轻而易举干掉了运营商的短信业务, “好未来”为何让传统教育不明觉厉? 花间堂为什么不是酒店,而是入口? 将来不会有互联网企业与传统企业之分, ......一起来看看 《产品型社群》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具