纹理
一、什么是纹理?
引用百度百科的定义:
计算机图形学中的纹理既包括通常意义上物体表面的纹理即使物体表面呈现凹凸不平的沟纹,同时也包括在物体的光滑表面上的彩色图案,通常我们更多地称之为花纹。对于花纹而言,就是在物体表面绘出彩色花纹或图案,产生了纹理后的物体表面依然光滑如故。对于沟纹而言,实际上也是要在表面绘出彩色花纹或图案,同时要求视觉上给人以凹凸不平感即可。 凹凸不平的图案一般是不规则的。在计算机图形学中,这两种类型的纹理的生成方法完全一致, 这也是计算机图形学中把他们统称为纹理的原因所在。
在上节中我们给每个顶点都添加了一个颜色值,从而使每个顶点都有对应的颜色,纹理的其实就是指定了每一个顶点对应的颜色,存储在一张2D或者3D的图片当中,然后把某个顶点对应的颜色在图片中的位置定义为纹理坐标,也就是说,知道了一个顶点的纹理坐标,我们就可以在图片中查找得到该顶点对应的颜色。有了纹理,我们就能够给物体添加更多的细节。
二、纹理映射
纹理映射 (Texture Mapping) 是一种将物体空间坐标点转化为纹理坐标,进而从纹理上获取对应点的值,以增强着色细节的方法。
以2D纹理举例说明,2D的纹理一般对应的纹理坐标从左下角到右上角分别为(0,0)和(1,1),例如下面这张图片:
如果我指定三角形的三个顶点对应的纹理坐标如下:
float vertices[3 * 8] =
{
//pos //Color //texcoord
-0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.5f, 1.0f
};
正确渲染得到的结果是这样的:
为了便于观察,我把两张图放到一起对比一下:
左边这张是我们的纹理图片,右边这张是给三角形指定纹理坐标后输出的结果,可以看到,根据我们设定的纹理坐标,三角形左面的顶点对应(0 , 0),所以对应纹理中的左下角,右面的顶点对应(1 ,0),对应纹理中的右下角,上面顶点同理对应纹理中上边缘的中间,因此三角形被绘制成了右图所示的样子。此外,还记得上节中指定了三角形三个顶点的颜色后输出的图形是彩色的吗,是因为顶点属性被进行了插值处理,这节中纹理坐标也是相同的原理,虽然我们仅指定了三个顶点的纹理坐标,但是经过插值后可以得到三角形区域对应的所有纹理坐标,从而在纹理中找到对应的颜色值输出,我们看到的输出结果就正好是纹理本身的样子了,输出图像也是纹理映射的结果。
三、创建纹理
想要使用纹理,首先需要创建并绑定纹理对象,和之前的顶点数组以及缓冲区一样:
unsigned int texture;
glGenTexture(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glBindTexture
函数的第一个参数指定了要绑定的纹理格式,是2D还是3D纹理,第二个参数是我们的纹理对象。
四、纹理的加载
使用纹理之前,首先要做的事情就是将准备好的图片文件加载到我们的应用中,这里使用图像加载库stb_image
来实现,有关stb_image
的配置这里不多做介绍,可以参阅: stb_image库及使用
将图片加载到应用中:
//load image
int width, height, channels;
stbi_set_flip_vertically_on_load(1);
unsigned char* data = stbi_load("Asset/texture/leidian.jpg", &wi