OPenGL纹理基础

简述

纹理是一个2D/1D/3D图片,可以更加逼真的描述物体,把一张砖的图片贴合到3d的房子上,这样房子看起来就像有砖墙了。OpenGL支持多类型多维数的纹理对象,每个纹理对象表示一组可以组成纹理的一组图象,纹理可以包括1维,2维或多维的数组,称为纹理数组。

 

纹理环绕方式

纹理坐标的范围通常是0倒1,如果超出后,可以设置不同的环绕方式处理。

环绕方式

描述

GL_REPEAT

对纹理的默认行为。重复纹理图像。

GL_MIRRORED_REPEAT

和GL_REPEAT一样,但每次重复图片是镜像放置的

GL_CLAMP_TO_EDGE

纹理坐标会被约束在0到1之间,超出的部分会重复纹理坐标的边缘,产生一种边缘被拉伸的效果。

 

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);

效果

纹理坐标正常时的效果

猜你喜欢

转载自blog.csdn.net/niu2212035673/article/details/78954747
今日推荐