系列推荐文章:
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];
复制代码