一、什么是纹理
纹理,英文是texture,中文可以翻译成纹理、纹理图、纹理映射等等一堆东西。不过不管翻译成啥,讲的都是一个东西。我们通常说的纹理,指的是一张二维的图片,把它像贴纸一样贴在什么东西上面,让那个东西看起来像我们贴纸所要表现的东西那样。举例来说,假如我们想绘制一面砖墙,我们该怎么办?根据我们已经掌握的知识来看,我们需要用成千上万的点来模拟它的颜色,我的天,这要搞到猴年马月才能搞出来?显然不现实!于是聪明的程序员们想出了一个好方法,就是用一张图“贴”到物体的表面上,让它看起来像是一面砖墙的样子,省时省力省心。
用一句话来总结,纹理就是一张贴到物体上的2维图像。
二、 纹理映射
规则是:以左下角为原点,向右伸展到1.0的位置,向上伸展到1.0的位置,表示一整张的纹理图像,具体我们是怎么映射到顶点数据的是需要我们在顶点数据上加一个映射关系.
三、 纹理参数
1.设置过滤方式
我们在日常开发中经常碰到这样一种情况,加入设计师给我们的图片是40x40的,但是我们需要渲染的View是100x100的,很明显这个view需要一张更大的纹理图,那么这种情况下是怎么读取的文理呢?OpenGL给我们提供了两种方式
GL_NEAREST
最近点过滤。指的是纹理坐标最靠近哪个纹素,就用哪个纹素。这是OpenGL默认的过滤方式,速度最快,但是效果最差。
GL_LINEAR
(双)线性过滤。指的是纹理坐标位置附近的几个纹素值进行某种插值计算之后的结果(其实就是颜色混合计算)。这是应用最广泛的一种方式,效果一般,速度较快。
两种过滤方式我们可以根据下图做一下比较
第一张是采用GL_NEAREST, 第二张为GL_LINEAR,通过比较我们还是可以很明显的区分出过滤方式的
1.设置环绕方式
通常,纹理坐标的范围在(0,0)到(1,1)之间,但是如果我们制定的坐标在这之外呢?OpenGL会如何做出反应?默认情况下,OpenGL会重复绘制纹理图,不过,OpenGL也提供了更多的选择方案:
GL_REPEAT: 默认方案,重复纹理图片。
GL_MIRRORED_REPEAT:类似于默认方案,不过每次重复的时候进行镜像重复。
GL_CLAMP_TP_EDGE:将坐标限制在0到1之间。超出的坐标会重复绘制边缘的像素,变成一种扩展边缘的图案。(通常很难看)
GL_CLAMP_TO_BORDER:超出的坐标将会被绘制成用户指定的边界颜色。
每种方案的显示效果截然不同,不必担心你会搞混了,看看效果就知道了。
四、使用
纹理加载步骤我们可以总结为以下几点
1.读取文理 对应代码以及参数解释
这些参数均为我们 定义的变量,把变量地址给到读取函数,函数会吧读取到的结果返回到变量里.
参数1:x,矩形左下角的窗⼝坐标
参数2:y,矩形左下角的窗口坐标
参数3:width,矩形的宽,以像素为单位
参数4:height,矩形的高,以像素为单位
参数5:format,OpenGL 的像素格式,
参数6:type,解释参数pixels指向的数据,告诉OpenGL 使⽤用缓存区中的什么 数据类型来存储颜⾊色分量,像素数据的数据类型,
参数7:pixels,指向图形数据的指针
void glReadPixels(GLint x,GLint y,GLSizei width,GLSizei
height, GLenum format, GLenum type,const void * pixels);
glReadBuffer(mode);—> 指定读取的缓存 glWriteBuffer(mode);—> 指定写⼊入的缓存
这一步就是从图片里获取到了文理数据和对应的参数
2.分配文理对象
例如:GLuint textID;
void glGenTextures(1,&textID);
3.绑定纹理
4.载入纹理
target:GL_TEXTURE_2D
* Level:指定所加载的mip贴图层次。一般我们都把这个参数设置为0。//这个参数后面会学习到
* internalformat:每个纹理单元中存储多少颜色成分。
* width、height、depth参数:指加载纹理的宽度、⾼度、深度。==注意!==这些值必须是 2的整数次⽅方。(这是因为OpenGL 旧版本上的遗留留下的⼀一个要求。当然现在已经可以⽀支持不不是 2的整数次方。但是开发者们还是习惯使用以2的整数次⽅去设置这些参数。)
* border参数:允许为纹理贴图指定⼀个边界宽度。一般为0
* format、type、data参数 均为我们加载文理时获取到的值 其中data 为 函数返回值,表示文理数据
5.纹理参数设置
最后 因为OpenGL是状态机模式,所以我们需要用完以后清除这些纹理对象