美文网首页IOS转载
OpenGLES学习之路-纹理(三)

OpenGLES学习之路-纹理(三)

作者: Justin910 | 来源:发表于2017-04-05 12:02 被阅读131次

    学习之路系列

    OpenGLES学习之路

    上篇文章在最后提了一下, 给立方体添加纹理, 下面就来实现下那个效果。

    本篇主要内容

    立方体纹理贴图

    效果图

    实现过程

    这里把上篇文章的效果拷贝过来,直接在上面进行添加纹理

    static const float Texture[] = {
        
        0, 0,
        1, 0,
        0, 1,
        1, 1,
        
        0, 0,
        1, 0,
        0, 1,
        1, 1,
    };
    

    上期的顶点坐标为8个, 前面和后面各4个, 纹理坐标我们也对应的设置为前面和后面各4个


    compileShaders方法中新增下面代码

    //获取着色器中的纹理变量
    _textureSlot  = glGetAttribLocation(_program, "TexCoordIn");
    glEnableVertexAttribArray(_textureSlot);
    
    //获取纹理单元
    _textureUniform  = glGetUniformLocation(_program, "ourTexture");
    //获取纹理对象
    _texture = [TextureManager getTextureImageName:@"Texture3_1.png"];
    

    render:中新增下面代码

    //使用纹理单元
    glActiveTexture(GL_TEXTURE0);
    //绑定纹理对象
    glBindTexture(GL_TEXTURE_2D, _texture);
    //这里的参数要对应纹理单元(如果纹理单元为0,这里也要给0)
    glUniform1i(_textureUniform, 0);
    

    当然着色器也需要修改一下
    Texture3Vertex.glsl如下

    attribute vec4 Position;
    
    attribute vec4 InColor;
    varying   vec4 OutColor;
    
    uniform mat4 ModelView;
    
    attribute vec2 TexCoordIn;  //new
    varying   vec2 TexCoordOut; //new
    
    void main(void){
        
        OutColor = InColor;
        
        gl_Position = ModelView * Position;
        
        TexCoordOut = vec2(TexCoordIn.x, 1. - TexCoordIn.y); //new
    }
    
    

    Texture3Fragment.glsl如下

    varying lowp vec4 OutColor;
    
    uniform sampler2D ourTexture;   //new
    varying lowp vec2 TexCoordOut;  //new
    
    void main(void){
    
    //    gl_FragColor = OutColor;
        
        gl_FragColor = texture2D(ourTexture, TexCoordOut);  //modify
    }
    
    

    如果设置纹理这一块还有小伙伴不明白的话,可以看下前面的这篇文章

    运行看下效果

    发现一个问题,就只有两面有图案 前面后面.
    我在前面的文章中提到过纹理坐标是(0,0)(1,1)
    看了下刚才设置的纹理坐标,只有前面后面满足这个要求
    为了让大家更直观更容易的理解,每个面弄4个坐标,4 x 6 == 24个坐标


    将下面顶点数据

    //4个顶点(分别表示xyz轴)
    static const float Vertices[] = {
        
        //前面4个坐标
        -0.5, -0.5,  0.5,
         0.5, -0.5,  0.5,
        -0.5,  0.5,  0.5,
         0.5,  0.5,  0.5,
        
        //后面4个坐标
        -0.5, -0.5, -0.5,
         0.5, -0.5, -0.5,
        -0.5,  0.5, -0.5,
         0.5,  0.5, -0.5,
    };
    
    static const float Texture[] = {    
        0, 0,
        1, 0,
        0, 1,
        1, 1,
        
        0, 0,
        1, 0,
        0, 1,
        1, 1,
    };
    

    修改为

    //4个顶点(分别表示xyz轴)
    static const float Vertices[] = {
        
        //前面4个坐标
        -0.5, -0.5,  0.5,
         0.5, -0.5,  0.5,
        -0.5,  0.5,  0.5,
         0.5,  0.5,  0.5,
        
        //后面4个坐标
        -0.5, -0.5, -0.5,
         0.5, -0.5, -0.5,
        -0.5,  0.5, -0.5,
         0.5,  0.5, -0.5,
        
        //左边4个坐标
        -0.5, -0.5, -0.5,
        -0.5, -0.5,  0.5,
        -0.5,  0.5, -0.5,
        -0.5,  0.5,  0.5,
        
        //右边4个坐标
         0.5, -0.5, -0.5,
         0.5, -0.5,  0.5,
         0.5,  0.5, -0.5,
         0.5,  0.5,  0.5,
        
        //上边4个坐标
         0.5,  0.5, -0.5,
        -0.5,  0.5, -0.5,
         0.5,  0.5,  0.5,
        -0.5,  0.5,  0.5,
        //下边4个坐标
         0.5, -0.5, -0.5,
        -0.5, -0.5, -0.5,
         0.5, -0.5,  0.5,
        -0.5, -0.5,  0.5,
        
    };
    static const float Texture[] = {
        
        0, 0,
        1, 0,
        0, 1,
        1, 1,
        
        0, 0,
        1, 0,
        0, 1,
        1, 1,
        
        0, 0,
        1, 0,
        0, 1,
        1, 1,
        
        0, 0,
        1, 0,
        0, 1,
        1, 1,
        
        0, 0,
        1, 0,
        0, 1,
        1, 1,
        
        0, 0,
        1, 0,
        0, 1,
        1, 1,
    };
    

    绘制的索引数组也需要修改一下

    static const GLubyte Indices[] = {
        
        0,  1,  2,
        2,  3,  1,
        
        4,  5,  6,
        6,  7,  5,
        
        2,  3,  6,
        6,  7,  3,
        
        0,  1,  4,
        4,  5,  1,
        
        0,  4,  2,
        2,  6,  4,
        
        1,  5,  3,
        3,  7,  5
    };
    

    修改为

    static const GLubyte Indices[] = {
        
        //前面
        0,  1,  2,
        2,  3,  1,
        
        //后面
        4,  5,  6,
        6,  7,  5,
        
        //左面
        8,  9, 10,
        10, 11, 9,
        
        //右面
        12, 13, 14,
        14, 15, 13,
        
        //上面
        16, 17, 18,
        18, 19, 17,
        
        //下面
        20, 21, 22,
        22, 23, 21
    };
    
    运行看下效果

    这样子6个面的渲染就出来了,就是如此的简单O(∩_∩)O哈哈~


    接下来将6个面渲染成不同的画面

    compileShaders中的单个纹理对象修改下

    //获取纹理对象
    _texture = [TextureManager getTextureImageName:@"Texture3_1.png"];
    

    改成

    //获取纹理对象
    for(int i = 0; i < 6; i++) {
        
        NSString *imageName = [NSString stringWithFormat:@"Texture3_%d.png", i + 1];
        _texture[i] = [TextureManager getTextureImageName:imageName];
    }
    

    渲染里面的代码也需要修改下

    
    //使用纹理单元
    glActiveTexture(GL_TEXTURE0);
    //绑定纹理对象
    glBindTexture(GL_TEXTURE_2D, _texture);
    //这里的参数要对应纹理单元(如果纹理单元为0,这里也要给0)
    glUniform1i(_textureUniform, 0);
    
    glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, Indices);
    

    改成

    for(int i = 0; i < 6; i++) {
        
        //使用纹理单元
        glActiveTexture(GL_TEXTURE0 + i);
        //绑定纹理对象
        glBindTexture(GL_TEXTURE_2D, _texture[i]);
        //这里的参数要对应纹理单元(如果纹理单元为0,这里也要给0)
        glUniform1i(_textureUniform, i);
        
        GLubyte *p = (GLubyte *)&Indices[6*i];
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, p);
    }
    
    运行看下效果

    Demo链接

    相关文章

      网友评论

        本文标题:OpenGLES学习之路-纹理(三)

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