什么是纹理
纹理(texture),通常来说,纹理
就是一张二维的图片。给一个模型贴一个纹理,就像在iOS代码中添加UIImage一样。
- 像素包装
图像存储空间 = 图像的宽度 * 图像的长度 * 每个像素的字节数
-
tga文件
在OpenGL中,我们使用.tga
文件作为纹理的素材,该格式支持压缩,使用不失真的压缩算法,可以带通道图,另外还支持行程编码压缩。
但是在OpenGL ES里面,我们就可以使用正常的图片了,例如.png
,.jpg
等等了。
其实任何图片在绘制的时候都会被解压成位图,最终以位图的形式“贴在”模型上。
常用纹理函数
-
从颜色缓冲区读取像素
该方法就是把图片从帧缓冲区中读取出来并进行写入
//参数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);—> 指定写⼊的缓存
-
载入纹理
载入纹理有以下3个方法
//纹理为1D格式
void glTexImage1D(GLenum target,GLint level,GLint
internalformat,GLsizei width,GLint border,GLenum
format,GLenum type,void *data);
//纹理为2D格式
void glTexImage2D(GLenum target,GLint level,GLint
internalformat,GLsizei width,GLsizei height,GLint
border,GLenum format,GLenum type,void * data);
//纹理为3D格式
void glTexImage3D(GLenum target,GLint level,GLint
internalformat,GLSizei width,GLsizei height,GLsizei
depth,GLint border,GLenum format,GLenum type,void *data);
这3个方法很类似,从方法名我们可以得知,3个方法的区别在于载入纹理的格式,究竟是1D,2D还是3D。函数每个参数的意义如下:
-
target为别对应
GL_TEXTURE_1D
,GL_TEXTURE_2D
,GL_TEXTURE_3D
- Level指定所加载的mip贴图层次。⼀般我们都把这个参数设置为0。
- width、height、depth参数:指加载纹理的宽度、⾼度、深度。==注意!==这些值必须是2的整数次⽅。(这是因为OpenGL 旧版本上的遗留下的⼀个要求。当然现在已经可以⽀持不是2的整数次⽅。但是开发者们还是习惯使⽤以2的整数次⽅去设置这些参数。)
- border允许为纹理贴图指定⼀个边界宽度。
- format、type、data参数:与我们在讲glDrawPixels 函数对于的参数相同。
由于,图片通常为2D的,即有宽度和高度,所以我们通常使用** glTexImage2D**这个方法
- 分配纹理对象
//参数1:使用了几个纹理,n就填几
//参数2:纹理对象指针,表示申请了一个纹理对象
void glGenTextures(GLsizei n,GLuint * textTures);
- 绑定纹理
//参数1有以下几个类型GL_TEXTURE_1D,GL_TEXTURE_2D,GL_TEXTURE_3D,需要结合我们的纹理使用,一般使用GL_TEXTURE_2D。
//参数2表示需要绑定的纹理对象
void GLAPIENTRY glBindTexture (GLenum target, GLuint texture)
- 删除纹理
//参数1表示需要删除的纹理的个数。
//参数2表示需要删除的纹理对象,这是一个数组,表示可以删除多个纹理。
void glDeleteTextures (GLsizei n, const GLuint *textures);
设置纹理参数
设置纹理参数有以下几个方法:
GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params);
GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params);
上面的方法很类似,参数分别代表
- target有以下几个类型GL_TEXTURE_1D,GL_TEXTURE_2D,GL_TEXTURE_3D,需要结合我们的纹理使用,一般使用GL_TEXTURE_2D。
- pname指定需要设置哪个纹理参数
- params表示具体的参数的值
设置过滤方式
在OpenGL中过滤方式有2各种,一种叫做临近过滤(GL_NEAREST)
,一种叫做线性过滤(GL_LINEAR)
- 临近过滤(GL_NEAREST)表示某个像素点会取当前位置上的颜色。
-
线性过滤(GL_NEAREST)表情会取附近的颜色综合值,做混合后展示在屏幕上。
临近过滤.png
线性过滤.png
用上图可以看出,图1就是选取的它所在位置的颜色,图2就是对它周围取了一个综合值,计算后得出一个最接近的值。
接下来,我们可以看一个实际的图片:
我们可以看到,临近过去看起来会更加清晰,但是有锯齿状;而线性过滤则有点模糊的感觉,但是会平滑许多。
所以究竟选临近过滤还是线性过滤,其实需要根据当前的实际情况来判断。而且,在真实的案例中,2者并不会有太大差别。
- 用法
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- GL_TEXTURE_MAG_FILTER指当纹理图象被使用到一个大于它的形状上时的状态。
- GL_TEXTURE_MIN_FILTER 指当纹理图象被使用到一个小于或等于它的形状上时的状态。
设置环绕方式,
当一个纹理坐标超出默认范围时,我们需要设置环绕方式,举个例子,假如我们的纹理为(44)的大小,但是我们的模型是(88),那么图片肯定不能铺满,那么就需要进行设置。
我们来看下具体效果:
-
GL_REPEAT
GL_REPEAT.png
此时,图片会进行复制,然后铺满屏幕。 -
GL_MIRRORED_REPEAT
GL_MIRRORED_REPEAT.png
此时,图片会进行复制,然后进行翻转,就像照镜子一样,然后铺满屏幕。 -
GL_CLAMP_TO_EDGE
GL_CLAMP_TO_EDGE.png
此时,固定图片中心的位置,边缘部分会被拉伸。
-
GL_CLAMP_TO_BORDER
GL_CLAMP_TO_BORDER.png
此时,固定图片中心的位置,超出部分用用户指定的颜色进行填充。
- 用法
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- GL_TEXTURE_WRAP_S、 GL_TEXTURE_WRAP_R、 GL_TEXTURE_WRAP_T分别代表s,t,r坐标。而这里的s,t,r坐标分别对应x,y,z坐标。
- 如果不设置,OpenGL默认使用** GL_REPEAT**。
纹理坐标系
对于一纹理来说,默认左下角为(0,0),右上角为(1,1)。
坐标系
如图所示,整个图片在[0,1]的区间中。
但是,我们也可以对图片进行翻转
翻转.png
如图,我们把图片翻转了180度之后仍然可以使用。
Mip贴图
Mip贴图这项材质贴图的技术,是依据不同精度的要求,而使用不同版本的材质图样进行贴图,可以提高渲染性能和显示质量。
例如:当物体移近使用者时,程序会在物体表面贴上较精细、清晰度较高的材质图案,于是让物体呈现出更高层、更加真实的效果;而当物体远离使用者时,程序就会贴上较单纯、清晰度较低的材质图样,进而提升图形处理的整体效率。
- 用法
// 设置mip贴图基层
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
//设置mip贴图最⼤层
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
-
Mip贴图的纹理过滤方式
Mip贴图的纹理过滤.png
下图为OpenGL的像素格式,我们常用GL_RGB
或GL_RGBA
这两种格式。
下图为OpenGL的像素数据的数据类型。我们常用GL_UNSIGNED_BYTE
。
网友评论