Android OpenGL ES(七)----理解纹理与纹理过滤
1.理解纹理
OpenGL中的纹理能够用来表示图像。照片,甚至由一个数学算法生成的分形数据。每一个二维的纹理都由很多小的纹理元素组成。它们是小块的数据,类似于我们前面讨论过的片段和像素。要使用纹理,最经常使用的方式是直接从一个图像文件载入数据。
每一个二维纹理都有其自己的坐标空间,其范围是从一个拐角的(0,0)到还有一个拐角的(1。1)。依照惯例,一个维度叫做S,而还有一个称为T。当我们想要把一个纹理应用于一个三角形或一组三角形的时候。我们要为每一个顶点指定一组ST纹理坐标,以便OpenGL知道须要用那个纹理的哪个部分画到每一个三角形上。
这些纹理坐标有时也会被称为UV纹理坐标。如图:

图1 OpenGL二维纹理坐标
对一个OpenGL纹理来说,它没有内在的方向性,因此我们能够使用不同的坐标把它定向到不论什么我们喜欢的方向上。
然而,大多数计算机图像都有一个默认的方向。它们通常被规定为Y轴向下,Y的值随着向图像的底部移动而添加。仅仅要我们记住,假设想用正确的方向观察图像,那纹理坐标就必需要考虑这点。这就不会给我们带来不论什么麻烦。
在标准OpenGL ES 2.0中。纹理不必是正方形,可是每一个维度都应该是2的幂(POT)。
这就意味着每一个维度都是这种一个数字,如128,256,512等。这样规定的原因在于非POT纹理能够被使用的场合很有限,而POT纹理使用于各种情况。
纹理的尺寸也有一个最大值,它依据不同的实现而变化。可是通常都比較大,比方2048*2048。
2.理解纹理过滤
当纹理的大小被扩大或者缩小时,我们还须要使用纹理过滤明白说明会发生什么。当我们在渲染表面上绘制一个纹理时,那个纹理的纹理元素可能无法精确地映射到OpenGL生成的片段上。
有两种情况:缩小和放大。
当我们尽力把几个纹理元素挤进一个片段时,缩小就发生了;当我们把一个纹理元素扩展到很多片段时。方法就发生了。针对每一种情况,我们能够配置OpenGL使用一个纹理过滤器。
首先。讲述两个主要的过滤模式:近期邻过滤和双线性插值。还有其它的过滤模式,以后的博文会解说。我们会使用以下的图像阐述每一种过滤模式。

近期邻过滤
这个方式为每一个片段选择近期的纹理元素。当我们放大纹理时,它的锯齿效果看起来相当明显,例如以下图所看到的。

每一个纹理单元都清楚的显示为一个小方块。
当我们缩小纹理时。由于没有足够的片段用来绘制全部的纹理单元,很多细节将会丢失。

双线性过滤
双线性过滤使用双线性插值平滑像素之间的过渡。而不是为每一个片段使用近期的纹理元素。OpenGL会使用四个邻接的纹理元素。并在它们之间用一个线性插值算法做插值,这个算法与前面所讲的平滑坐在着色一样。我们之所以称它为双线性插值。是由于它是沿着两个维度插值的。以下是使用双线性差值放大后的图像。它採用的纹理与前面的同样。

这个纹理如今看起来比曾经平滑多了。
但还是有些锯齿显现出来,由于我们把这个纹理扩展得太多。可是锯齿不像使用近期邻过滤那么明显。
MIP贴图
虽然双线性过滤非常适合处理放大,可是对于缩小到超过一定的大小时,它就不好用了。一个纹理在渲染表面所占大小降低得越多。就会有越多的纹理元素拥挤到每个片段上。
由于OpenGL的双线性过滤仅仅给每个片段使用四个纹理元素。我们将会丢失非常多细节。
由于每一帧都要选择不同的纹理元素。这还会引起噪音以及移动中的物体闪烁。
为了克服这些缺陷。能够使用MIP贴图技术,它能够用来生成一组优化过的不同大小的纹理。当生成这组纹理的时候,OpenGL会使用全部的纹理元素生成每一个级别的纹理,当过滤纹理时,还要确保全部的纹理元素都能被使用。在渲染时,OpenGL会依据每一个片段的纹理元素数量为每一个片段选择最合适的级别。
下图是一组MIP贴图的纹理,把它们合并在一当个图上是为了方便对照。

图2 MIP贴图的纹理
使用MIP贴图。会占用很多其它的内存,可是渲染也会更快,这是由于较小级别的纹理在GPU的纹理缓存中占用较少的空间。
为了更好地理解MIP贴图是怎样提高缩小情况下的质量,我们比較一下那个可爱的机器人。使用双线性过滤把纹理元素尺寸缩小到其原来的12.5%。例如以下图:

图3 使用双线性过滤缩小
就这样的质量,可能还不如近期邻过滤。看一下当我们增加MIP贴图时会得到什么。例如以下图:

图4 使用MIP贴图缩小
随着MIP贴图的使用。OpenGL将选择最合适的纹理级别。然后用优化过的纹理做双线性插值。每一个级别的纹理都是用来自全部纹理元素的信息构建的。因此得到的图形看起来更好些。保留了很多其它的细节。
三线性过滤
假设OpenGL在不同的MIP贴图级别之间来回切换,当我们用双线性插值来使用MIP贴图时。在其渲染的场景中,在不同级别的MIP贴图切换时。我们有时候能看到明显的跳跃或者线条。我们能够切换到三线性插值。这样。每一个片段总共要使用8个纹理元素插值。
这有助于消除每一个MIP贴图级别之间的过渡,而且得到一个更平滑的图像。
3.程序中纹理參数表
方法GLES20.glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_FILTER。“纹理过滤模式”)。第二个參数指放大的情况。
方法GLES20.glTextParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,“纹理过滤模式”);第二个參数指缩小的情况。
第一个參数是告诉OpenGL这应该被作为一个二维纹理对待。
表1 OpenGL纹理过滤模式
|
GL_NEAREST |
近期邻过滤 |
| GL_NEAREST_MIPMAP_NEAREST |
使用MIP贴图的近期邻过滤 |
| GL_NEAREST_MIPMAP_LINEAR |
使用MIP贴图级别之间插值的近期邻过滤 |
|
GL_LINEAR |
双线性插值 |
|
GL_LINEAR_MIPMAP_NEAREST |
使用MIP贴图的双线性插值 |
|
GL_LINEAR_MIPMAP_LINEAR |
三线性插值(使用MIP贴图级别之间插值的双线性过滤) |
表2 每种情况同意的纹理过滤模式
| 缩小 | GL_NEAREST GL_NEAREST_MIPMAP_NEAREST GL_NEAREST_MIPMAP_LINEAR GL_LINEAR GL_LINEAR_MIPMAP_NEAREST GL_LINEAR_MIPMAP_LINEAR |
| 放大 | GL_NEAREST GL_LINEAR |
下一篇纹理的应用效果图例如以下:

Android OpenGL ES(七)----理解纹理与纹理过滤的更多相关文章
- 基于Cocos2d-x学习OpenGL ES 2.0之多纹理
没想到原文出了那么多错别字,实在对不起观众了.介绍opengl es 2.0的不多.相信介绍基于Cocos2d-x学习OpenGL ES 2.0之多纹理的,我是独此一家吧.~~ 子龙山人出了一个系列: ...
- Android OpenGL ES(七)基本几何图形定义 .
在前面Android OpenGL ES(六):创建实例应用OpenGLDemos程序框架 我们创建了示例程序的基本框架,并提供了一个“Hello World”示例,将屏幕显示为红色. 本例介绍Ope ...
- Android OpenGL ES 开发教程 从入门到精通
感谢,摘自:http://blog.csdn.net/mapdigit/article/details/7526556 Android OpenGL ES 简明开发教程 Android OpenGL ...
- Android OpenGL ES(十二):三维坐标系及坐标变换初步 .
OpenGL ES图形库最终的结果是在二维平面上显示3D物体(常称作模型Model)这是因为目前的打部分显示器还只能显示二维图形.但我们在构造3D模型时必须要有空间现象能力,所有对模型的描述还是使用三 ...
- [工作记录] Android OpenGL ES: non-square texture - continue
previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found ...
- Android OpenGL ES(十三)通用的矩阵变换指令 .
Android OpenGL ES 对于不同坐标系下坐标变换,大都使用矩阵运算的方法来定义和实现的.这里介绍对应指定的坐标系(比如viewmodel, projection或是viewport) An ...
- Android OpenGL ES(八)绘制点Point ..
上一篇介绍了OpenGL ES能够绘制的几种基本几何图形:点,线,三角形.将分别介绍这几种基本几何图形的例子.为方便起见,暂时在同一平面上绘制这些几何图形,在后面介绍完OpenGL ES的坐标系统和坐 ...
- Android OpenGL ES .介绍
引自:http://blog.csdn.net/hgl868/article/details/6971624 1. OpenGL ES 简介 Android 3D引擎采用的是OpenGL ES. ...
- Android OpenGL ES(六)创建实例应用OpenGLDemos程序框架 .
有了前面关于Android OpenGL ES的介绍,可以开始创建示例程序OpenGLDemos. 使用Eclipse 创建一个Android项目 Project Name: OpenGLDemos ...
随机推荐
- rpm方式在centos7中安装mysql
.安装MySQL server 首先下载好mysql的rpm安装包 使用rpm命令安装: rpm -ivh MySQL-server--.glibc23.i386.rpm #rpm -ivh MySQ ...
- nginx編譯
openssl源码安装后,编译nginx-1.9.7或者openresty找不到OpenSSL的解决办法 http://blog.csdn.net/zhiyuan_2007/article/detai ...
- linux文件与用户和群组
文件基本属性 在图片中alogrithm的文件属性为drwxrwxr-x,其中d代表此文件为目录. 后面rwx,rwx,r-x分别代表文件所属者(ower),组(group),其他用户(other)的 ...
- nodejs即时聊天
一直想做一个即时聊天的应用,前几天看到了socket.io,感觉还不错.自己略加改动,感觉挺不错的.官网上给的样例非常easy,以下改进了一点,实现了历史消息的推送. demo地址:chat.code ...
- linux 数据库
查看数据库状态:service mysqld status 启动数据库服务 service mysql start 如果出现:Another MySQL daemon already running ...
- 一个人的旅行 HDU杭电2066【dijkstra算法 || SPFA】
pid=2066">http://acm.hdu.edu.cn/showproblem.php? pid=2066 Problem Description 尽管草儿是个路痴(就是在杭电 ...
- android studio 、 as 如何导入eclipse项目
安卓项目有两种,一种是eclipse开发的,一种的android studio开发的.有些在github开源的安卓项目,下载下来之后不知道该如何处理了. 这个是Eclipse安卓项目的目录结构. 这个 ...
- 线程进阶:多任务处理(17)——Java中的锁(Unsafe基础)
在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...
- HTML基础——网站信息显示页面
1.语法和规范 HTML文件都是以.html或者.htm结尾的.建议使用.html结尾. HTML文件分为头部分(<head></head>)和体部分(<body> ...
- shell基础编程
首先要注意的是,Ubuntu里的shell的sh和bash命令是有区别的 如下所示,Ubuntu下的sh指向的dash程序,而bash是dash的增强版,一些bash上能执行的程序在dash上不行 如 ...