音视频开发系列(37)OpenGL ES之纹理

本文介绍了OpenGL ES中的纹理概念,包括纹理坐标、纹理映射、纹理单元和纹理环绕、过滤方式。详细阐述了纹理加载流程和关键方法,并通过实践展示了如何加载纹理,实现二分屏、三分屏、镜像等效果,同时探讨了纹理与颜色混合的应用。文章最后总结了学习收获,加深了对OpenGL ES纹理理解。
摘要由CSDN通过智能技术生成

一、基本概念

纹理
纹理(Texture)是一个2D图片(甚至也有1D和3D的纹理),它可以用来添加物体的细节;把它像贴纸一样贴在什么东西上面,让那个东西看起来像我们贴纸所要表现的东西那样。从而使图形更加真实

纹理坐标

OpenGL中纹理坐标系是以纹理左下角为坐标原点的,而图片中像素的存储顺序是从左上到右下的,因此我们需要对我们的坐标系进行一次Y轴的“翻转”。

图片坐标系的(0,0)在图片左上角,纹理坐标的(0,0)在纹理左下角

纹理映射

为了能够把纹理映射(Map)到三角形上,我们需要指定三角形的每个顶点各自对应纹理的哪个部分。这样每个顶点就会关联着一个纹理坐标(Texture Coordinate),用来标明该从纹理图像的哪个部分采样。之后在图形的其它片段上进行片段插值(Fragment Interpolation)。

纹理单元

纹理单元是能够被着色器采样的纹理对象的引用, 纹理通过调用glBindTexture函数绑定到指定的纹理单元。没有明确指定使用哪个纹理单元时纹理被默认绑定到GL_TEXTURE0_

glActiveTexture:激活纹理单元

为什么sampler2D变量是个uniform,我们却不用glUniform给它赋值。使用glUniform1i?
使用glUniform1i,我们可以给纹理采样器分配一个位置值,这样的话我们能够在一个片段着色器中设置多个纹理

纹理环绕方式

GL_REPEAT:默认方案,重复纹理图片。
GL_MIRRORED_REPEAT:类似于默认方案,不过每次重复的时候进行镜像重复。
GL_CLAMP_TP_EDGE:将坐标限制在0到1之间。超出的坐标会重复绘制边缘的像素,变成一种扩展边缘的图案。(通常很难看)
GL_CLAMP_TO_BORDER:超出的坐标将会被绘制成用户指定的边界颜色。

纹理过滤

GL_NEAREST:最近点过滤:
纹理坐标最靠近哪个纹素,就用哪个纹素。这是OpenGL默认的过滤方式,速度最快,但是效果比较差。
GL_LINEAR:(双)线性过滤:
纹理坐标位置附近的几个纹素值进行某种插值计算之后的结果。这是应用最广泛的一种方式,效果一般,速度较快。

多级渐进纹理(多级渐远纹理)
mipmaps,就是一系列的纹理图片,每一张纹理图的大小都是前一张的1/4,直到剩最后一个像素为止

它简单来说就是一系列的纹理图像,后一个纹理图像是前一个的二分之一。多级渐远纹理背后的理念很简单:距观察者的距离超过一定的阈值,OpenGL会使用不同的多级渐远纹理,即最适合物体的距离的那个。由于距离远,解析度不高也不会被用户注意到。同时,多级渐远纹理另一加分之处是它的性能非常好。

GL_NEAREST_MIPMAP_NEAREST:采用最近的mipmap图,在纹理采样的时候使用最近点过滤采样。
GL_LINEAR_MIPMAP_NEAREST:采用最近的mipmap图,纹理采样的时候使用线性过滤采样。
GL_NEAREST_MIPMAP_LINEAR:采用两张mipmap图的线性插值纹理图,纹理采样的时候采用最近点过滤采样。
GL_LINEAR_MIPMAP_LINEAR:采用两张mipmap图的线性插值纹理图,纹理采样的时候采用线性过滤采样。
生成mimap对应方法如下

二、纹理绘制流程和关键方法

 final int[] textureObjectIds = new int[1];
//初始化纹理
        glGenTextures(1, textureObjectIds, 0);

        if (textureObjectIds[0] == 0) {
            return 0;
        } 

        //获取纹理图片
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;

        final Bitmap bitmap = BitmapFactory.decodeResource(
            context.getResources(), resourceId, options);

        if (bitmap == null) {
            glDeleteTextures(1, textureObjectIds, 0);
            return 0;
        } 
        // 绑定纹理 2D纹理和纹理id
        glBindTexture(GL_TEXTURE_2D, textureObjectIds[0]);

        //设置纹理环绕方式为 GL_REPEAT
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
        
      //设置纹理过滤 缩小和放大的filter
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        // 加载纹理图片
        texImage2D(GL_TEXTURE_2D, 0, bitmap, 0);


        //生成多级渐变纹理
        glGenerateMipmap(GL_TEXTURE_2D);

        //回收bitmap
        bitmap.recycle();

        // 解绑纹理
        glBindTexture(GL_T
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值