- 收藏
- 加入书签
基于OpenGL的纹理技术
摘要:纹理是一种图形数据,它类似一张皮肤,可以贴在OpenGL空间指定区域,实现需要的视觉效果,使用纹理技术大大降低了建模工作量,减小了存储空间,提高了读取速度。本文介绍了纹理的相关概念,并探讨了几种常用的纹理技术。
关键词:纹理;纹理缓冲区;纹理映射;着色器
1、引言
OpenGL中,纹理主要用于在屏幕上包装不同的物体,展现物体细节特征,它类似一张皮肤,可以贴在OpenGL空间指定区域,从而实现需要的视觉效果。相比使用庞大的顶点矩阵来实现真实的图片效果,纹理将节省很大开销。
2、概述
2.1 纹理及纹理缓冲区
纹理是一种特殊的图形数据,和uniform数据一样,可以传输到着色器中,它需要填充数据,但又不是一个缓冲区的概念。GL_TEXTURE_BUFFER Object才是真正的纹理缓冲区对象,能够用来提供对片段着色器和顶点着色器中的顶点数组的访问,还能直接填充来自其他渲染结果(如变换反馈、像素读取操作或顶点数据)的数据。OpenGL为我们提供了三种纹理:1维纹理、2维纹理和3维纹理。
2.2 纹理映射
纹理坐标(二维)采用归一化坐标(s,t),默认左下角为(0,0),右上角为(1,1)。OpenGL中所有复杂图形都是由一堆三角形拼凑成的,只要为每个三角形顶点设定好对应的纹理坐标,就知道了对应纹理上哪个区域。根据这个对应关系,片元着色器在着色时,每个片元会去纹理上对应的坐标点去采样颜色,这样每个片元就知道了自己该显示什么颜色,它们合在一起就是最终显示的画面。这个过程称为纹理采样或纹理映射。
2.3 纹理映射方式
如何将纹理值与片元颜色值合并起来,OpenGL使用glTexEnv*来设置纹理的映射方式GL_TEXTURE_ENV_MODE。常用有3种:GL_MODULATE模式会根据当前的光照系统调整物体的色彩和明暗;GL_DECAL模式下光照效果无效,将仅依据纹理贴图来绘制物体的表面;GL_BLEND模式通过设置映射颜色,将其与当前纹理混合成一个新纹理。
2.4 纹理过滤与环绕模式
OpenGL使用glTexParameter*来设置纹理的参数。如果图元大小不等于纹理大小,可以设置纹理滤镜对纹理缩放以适应图元尺寸,放大滤镜用GL_TEXTURE_MAG_FILETER,缩小滤镜用GL_TEXTURE_MIN_FILTER。GL_NEAREST表示使用纹理中坐标最接近的一个像素的颜色作为需要绘制的像素颜色,GL_LINEAR表示使用纹理中坐标最接近的若干个颜色,通过加权平均算法得到需要绘制的像素颜色。
纹理坐标在0~1之间,如果坐标大于这个值可以设置环绕方式(边界处理),环绕模式能被独立的设定为s 坐标和t坐标。GL_REPEAT是对纹理坐标进行重置而得到的重复图像,GL_MIRRORED_REPEAT是镜像重复,GL_CLAMP_TO_EDGE/BORDER,将对超出纹理坐标的区域使用纹理图像的边界颜色或用户指定颜色来代替。
3、常用纹理技术
纹理操作前首先要创建并绑定纹理,多个纹理对象时用glActiveTexture激活要使用的纹理单元(默认纹理单元是TEXTURE0),然后将已激活的纹理单元的操作目标与指定纹理绑定。
3.1 使用图像生成纹理
BMP格式图片可以使用辅助库函数auxDIBImageLoad获得位图信息,也可以根据不同位图底层结构读取文件头、信息头和数据信息,再去除每行尾4字节对齐的无效像素,将BGR存放改为RGB。工作中我们常常要使用更多格式的图片生成纹理,而OpenGL并没有提供相关API将这些图片文件转换成我们需要的图像数组,因此我们需要使用第三方库来解决这个问题。SOIL提供的库函数SOIL_load_image可以将指定的任意格式图片文件加载并生成纹理数据。纹理数据使用完毕后记得释放。
获取了图像数组,接下来就是将这些像素数据传给OpenGL生成纹理。基本的装载纹理函数是glTexImage2D,它的参数分别是纹理类型、等级、每个像素的字节数、纹理图像的宽度和高度、边框大小、像素数据的格式、像素值的数据类型、像素数据。当纹理数据被glTexImage2D 装载时,默认数据行4 位一组对齐,也可以使用glPixelStorei去设定压缩或解压阵列的对齐模式,压缩阵列参数不会影响贴图图像的装载。
3.2 使用纹理缓冲区
纹理缓冲区是作为普通缓冲区来创建的,当它被绑定到一个纹理单元或者纹理缓冲区绑定点时会成为真正的纹理缓冲区。将纹理缓冲区绑定到一个纹理上可以用glTexBuffer。
纹理缓冲区创建后使用glBufferData来初始化或更新缓冲区数据,数据参数为空代表存储的值未初始化。这个函数还告诉应用怎样使用存储在缓冲区对象中的数据,通常设置为GL_STATIC_DRAW,表示缓冲区对象数据一旦被应用程序指定,多次使用去绘制基元。使用glBufferData后客户数据存储区将不再需要,能够被释放,对静态几何图形,应用能够释放客户存储区减小系统内存消耗,对动态几何图形这是不可能的。
3.3 使用帧缓冲区
帧缓冲区可以使用纹理作为附加图像,附加纹理时,OpenGL直接渲染到这个纹理图像,在着色器中可以访问这个纹理对象。一个帧缓冲区有一个深度附着点,一个模板附着点,以及多个颜色附着点,各种2D图像都可以挂接到帧缓冲区的颜色附着点。
创建并绑定帧缓冲区后,我们使用glFramebufferTexture2D来附加纹理到帧缓冲区。它直接渲染生成纹理,相比于glCopyTexImage2D先渲染到帧缓冲区,再复制帧缓冲区中指定区域的像素产生纹理要高效的多。要注意的是,它们都要求纹理尺寸小于或等于帧缓冲区尺寸,且纹理格式不能比颜色缓冲区组成复杂。
4、结语
基于纹理对着色器便捷访问以及纹理缓冲区宽松的大小限制等优点,使得OpenGL中使用纹理渲染、多重采样等技术,大大降低了建模工作量,减小了存储空间,提高了读取速度。
京公网安备 11011302003690号