美文网首页
OpenGL ES之旅(三)-- OpenGL ES 纹理翻转解

OpenGL ES之旅(三)-- OpenGL ES 纹理翻转解

作者: Daniel_Harvey | 来源:发表于2019-06-18 11:28 被阅读0次

    纹理翻转概述

    在使用OpenGL ES函数加载纹理到图形时,经常遇到纹理上下颠倒的问题。原因是因为OpenGL ES要求纹理坐标原点在图片最下面,如图:


    image

    OpenGL要求y轴0.0坐标是在图片的底部的,但是图片的y轴0.0坐标通常在顶部,因此,我们的策略:

    • 可以改变顶点数据的纹理坐标,翻转y值(用1减去y坐标)
    • 可以编辑顶点着色器来自动翻转y坐标,替换TexCoord的值为TexCoord = vec2(texCoord.x, 1.0f - texCoord.y)

    纹理翻转解决策略

    第一种:旋转矩阵翻转图形,不翻转纹理

    让图形顶点坐标旋转180°. 而纹理保持原状.

    GLuint rotate = glGetUniformLocation(self.myPrograme, "rotateMatrix");
        float radians = 180 * 3.14159f / 180.0f;
        float s = sin(radians);
        float c = cos(radians);
        
      
        GLfloat zRotation[16] = {
            c, -s, 0, 0,
            s, c, 0, 0,
            0, 0, 1.0, 0,
            0.0, 0, 0, 1.0
        };
        
       glUniformMatrix4fv(rotate, 1, GL_FALSE, (GLfloat *)&zRotation[0]);
    

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

    CGImageRef spriteImage = [UIImage imageNamed:fileName].CGImage;
    
    size_t width = CGImageGetWidth(spriteImage);
    size_t height = CGImageGetHeight(spriteImage);
    GLubyte * spriteData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
    
    CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width*4,CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
      
    CGRect rect = CGRectMake(0, 0, width, height);
    CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
    
    CGContextTranslateCTM(spriteContext, rect.origin.x, rect.origin.y);
    CGContextTranslateCTM(spriteContext, 0, rect.size.height);
    CGContextScaleCTM(spriteContext, 1.0, -1.0);
    CGContextTranslateCTM(spriteContext, -rect.origin.x, -rect.origin.y);
    CGContextDrawImage(spriteContext, rect, spriteImage); 
    
    CGContextRelease(spriteContext);
    glBindTexture(GL_TEXTURE_2D, 0);
    

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

    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, // 右下
         };
         */
    

    系列文章:

    相关文章

      网友评论

          本文标题:OpenGL ES之旅(三)-- OpenGL ES 纹理翻转解

          本文链接:https://www.haomeiwen.com/subject/yogxqctx.html