简述
纹理是一个2D/1D/3D图片,可以更加逼真的描述物体,把一张砖的图片贴合到3d的房子上,这样房子看起来就像有砖墙了。OpenGL支持多类型多维数的纹理对象,每个纹理对象表示一组可以组成纹理的一组图象,纹理可以包括1维,2维或多维的数组,称为纹理数组。
纹理环绕方式
纹理坐标的范围通常是0倒1,如果超出后,可以设置不同的环绕方式处理。
环绕方式 |
描述 |
|
GL_REPEAT |
对纹理的默认行为。重复纹理图像。 |
|
GL_MIRRORED_REPEAT |
和GL_REPEAT一样,但每次重复图片是镜像放置的 |
|
GL_CLAMP_TO_EDGE |
|
|
GL_CLAMP_TO_BORDER |
超出的坐标为用户指定的边缘颜色。 |
通过调用函数glTexParameteri()设置
void glTexParameteri(GLenum target, GLenum pname, const GLint *params) 返回值:void 参 数:target 纹理目标 buffers 水平或垂直方向 params 环绕方式 |
一般需要调用两次,一次设置垂直方向(y轴),一次设置水平方向(x轴)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
效果
纹理顶点坐标设置为大于1的坐标,即
float texture[] =
{
2.0f, 2.0f, // 右上
2.0f, 0.0f, // 右下
0.0f, 0.0f, // 左下
0.0f, 2.0f // 左上
}
环绕方式GL_CLAMP_TO_BORDER时的效果
环绕方式GL_MIRRORED_REPEAT时的效果
环绕方式GL_CLAMP_TO_EDGE时的效果
环绕方式GL_REPEAT时的效果
纹理过滤
纹理过滤对于分辨率很低比较重要。OpenGL也有对于纹理过滤处理方式。其中最常见的有两种:GL_NEAREST和GL_LINEAR。
GL_NEAREST也叫邻近过滤,是OpenGL默认的纹理过滤方式
GL_LINEAR也叫线性过滤,它会基于纹理坐标附近的纹理像素,计算出一个插值,近似出这些纹理像素之间的颜色。
GL_NEAREST方式对于分辨率较低的纹理渲染时会有较强颗粒感,能够清晰看到组成纹理的像素,而GL_LINEAR能够产生更平滑的图案。
如下图
纹理的基本使用流程
与其他的缓存对象使用类似,OpenGL中使用纹理必须使用纹理缓存对象。相关的API有glGenTextures(),glBindTexture(),glTexImage2D(),glActiveTexture(),glDeleteTexture()。
1,创建纹理缓存对象
为纹理对象保存名称,设置个数和保存的名称数组
void glGenTextures(GLsizei n, GLuint *textures) 返回值:void 参 数:n 需要返回缓存对象的个数 buffers 纹理缓存对象 |
2,绑定到OpenGL环境中
名称保留后,还没有表示纹理,所以没有维数和类型,接下来必须绑定到相应的纹理目标
void glBindTexture(GLenum target, GLuint textures) 返回值:void 参 数:target 纹理目标 textures纹理缓存缓存对象 |
3,为纹理缓存对象输入数据
绑定完成后,纹理单元还没有大小和数据,须传入纹理数据
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) 返回值:void 参 数:target 需要返回缓存对象的个数 level 纹理单元的层次,非mipmap纹理level设置为0,mipmap纹理设置为纹理的层级 internalformat 纹理单元中的数据格式 width 纹理单元的宽 height 纹理单元的高 border 纹理单元的边框 format data 所指向的数据的格式 type data 所指向的数据的格式 pixels 实际指向的数据 |
4,激活纹理对象
一个纹理可以同时绑定多个纹理单元,默认会使用第一个纹理单元,即GL_TEXTURE0。如果绑定了多个纹理单元就需要显式的声明所激活的纹理单元,纹理单元遵循GL_TEXTURE0 + i的方式递增
void glActiveTexture(GLenum texture) 返回值:void 参 数:texture 当前激活的纹理单元
|
5,使用完后删除纹理对象
void glDeleteTexture(GLsizei n, GLuint *textures) 返回值:void 参 数:n 需要删除缓存对象的个数 buffers 纹理缓存对象指针 |
创建纹理源码
// ---------------纹理1 --------------- unsigned int texture1, texture2; // 创建纹理 glGenTextures(1, &texture1); //绑定纹理 glBindTexture(GL_TEXTURE_2D, texture1); //设置环绕方式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //设置纹理过滤 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //向纹理单元输入图象数据 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 200, 200, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
效果
纹理坐标正常时的效果