OpenGL ES纹理翻转策略

在OpenGL ES中按常规加载一张纹理后,会发现纹理图片在渲染后显示在屏幕上是倒置的

那么如何解决这种现象的发生了,我们应该能做的就是将图片翻转过来,就可以解决这个问题了。那么有几种实现方法可以解决这个问题。

1.从加载图片处将图片翻转

    加载纹理图的时候,我们通常是要把其转化为位图才可以给OpenGl ES使用,那么在解压缩后,将其翻转。

    //1、将 UIImage 转换为 CGImageRef

    CGImageRefspriteImage = [UIImageimageNamed:fileName].CGImage;

    //2、读取图片的大小,宽和高

    size_twidth =CGImageGetWidth(spriteImage);

    size_theight =CGImageGetHeight(spriteImage);

    //3.获取图片字节数 宽*高*4(RGBA)

    GLubyte* spriteData = (GLubyte*)calloc(width * height *4,sizeof(GLubyte));

    //4.创建上下文

    CGContextRefspriteContext =CGBitmapContextCreate(spriteData, width, height,8, width*4,CGImageGetColorSpace(spriteImage),kCGImageAlphaPremultipliedLast);

    //5、在CGContextRef上--> 将图片绘制出来    CGRectrect =CGRectMake(0,0, width, height);

    //6.使用默认方式绘制

    CGContextDrawImage(spriteContext, rect, spriteImage);

    //加入位移,缩放,完成图片翻转

    CGContextTranslateCTM(spriteContext,0, rect.size.height);

    CGContextScaleCTM(spriteContext,1.0, -1.0);

    CGContextDrawImage(spriteContext, rect, spriteImage);

    //7、画图完毕就释放上下文

    CGContextRelease(spriteContext);


    //8、绑定纹理到默认的纹理ID

    glBindTexture(GL_TEXTURE_2D, 0);

    //9.设置纹理属性

    /*

     参数1:纹理维度

     参数2:线性过滤、为s,t坐标设置模式

     参数3:wrapMode,环绕模式

     */

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


    floatfw = width, fh = height;


    //10.载入纹理2D数据

    /*

     参数1:纹理模式,GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D

     参数2:加载的层次,一般设置为0

     参数3:纹理的颜色值GL_RGBA

     参数4:宽

     参数5:高

     参数6:border,边界宽度

     参数7:format

     参数8:type

     参数9:纹理数据

     */

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fw, fh, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);


    //11.释放spriteData

    free(spriteData); 

2.加入旋转矩阵

    然而通过加入旋转矩阵,让顶点着色器的顶点坐标与旋转矩阵的叉乘 也可以实现纹理旋转。

//注意,想要获取shader里面的变量,这里记得要在glLinkProgram后面,后面,后面!

    //1. rotate等于shaderv.vsh中的uniform属性,rotateMatrix

    GLuintrotate =glGetUniformLocation(self.myPrograme,"rotateMatrix");


    //2.获取渲旋转的弧度

    floatradians =180*3.14159f/180.0f;


    //3.求得弧度对于的sin\cos值

    floats =sin(radians);

    floatc =cos(radians);


    //4.因为在3D课程中用的是横向量,在OpenGL ES用的是列向量

    /*

     参考Z轴旋转矩阵

     */

    GLfloatzRotation[16] = {

        c,-s,0,0,

        s,c,0,0,

        0,0,1,0,

        0,0,0,1

    };


    //5.设置旋转矩阵

    /*

     glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)

     location : 对于shader 中的ID

     count : 个数

     transpose : 转置

     value : 指针

     */

    glUniformMatrix4fv(rotate,1,GL_FALSE, zRotation);

3.着色器代码变换纹理坐标

在顶点着色器代码中通过变换纹理坐标,只要将其y的坐标取为1 - y。即可取到翻转后的纹理坐标

attribute vec4 position;

attributevec2textCoordinate;

varyinglowpvec2varyTextCoord;

voidmain()

{

    //varyTextCoord = textCoordinate;

    varyTextCoord =vec2(textCoordinate.x,1.0-textCoordinate.y);

    gl_Position= position;

}

4.在外面传入纹理坐标时,直接按翻转后的坐标传入,也可以实现翻转图片。

你可能感兴趣的:(OpenGL ES纹理翻转策略)