OpenGL & Metal

OpenGL中的纹理

2020-07-22  本文已影响0人  黑眼豆豆_

什么是纹理

纹理(texture),通常来说,纹理就是一张二维的图片。给一个模型贴一个纹理,就像在iOS代码中添加UIImage一样。

图像存储空间 = 图像的宽度 * 图像的长度 * 每个像素的字节数

其实任何图片在绘制的时候都会被解压成位图,最终以位图的形式“贴在”模型上。

常用纹理函数

//参数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);—> 指定写⼊的缓存

//纹理为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。函数每个参数的意义如下:

由于,图片通常为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);

上面的方法很类似,参数分别代表

设置过滤方式

在OpenGL中过滤方式有2各种,一种叫做临近过滤(GL_NEAREST),一种叫做线性过滤(GL_LINEAR)

临近过滤和线性过滤

我们可以看到,临近过去看起来会更加清晰,但是有锯齿状;而线性过滤则有点模糊的感觉,但是会平滑许多。
所以究竟选临近过滤还是线性过滤,其实需要根据当前的实际情况来判断。而且,在真实的案例中,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);

设置环绕方式,

当一个纹理坐标超出默认范围时,我们需要设置环绕方式,举个例子,假如我们的纹理为(44)的大小,但是我们的模型是(88),那么图片肯定不能铺满,那么就需要进行设置。

环绕方式.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);

纹理坐标系

对于一纹理来说,默认左下角为(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);

下图为OpenGL的像素格式,我们常用GL_RGBGL_RGBA这两种格式。

图1.png

下图为OpenGL的像素数据的数据类型。我们常用GL_UNSIGNED_BYTE

图2.png
上一篇 下一篇

猜你喜欢

热点阅读