第一遍看第九章纹理的时候,是非常难以理解的,一维纹理,二维纹理,三维纹理,以及纹理对坐标的对应关系,不仔细研究真的是很难弄明白
在OPENGL一书中,并没有讲到如何用磁盘上的图片制作纹理,全篇都是采用自己创建数据矩阵的方式作为纹理,应用到物体对象上去。于是这里就有个问题,究竟什么是一维纹理二维纹理三维纹理呢?
二维纹理其实是最容易理解的,以创建的矩阵为例,创建一个checkImage[checkImageHeight][checkImageWidth][4]的数组,数组的i,j对应的正好是图像上的一个个像素,每个i,j下的四个数据代表了该像素点的RGBA值
一维纹理,其实就是i=0或者j=0的二维数组
三维纹理拿书上的话来说,可以看成是一层层的二维子图像矩形构成的
而理解它们最好的方式,就是找到他们和物体对象坐标的对应关系。纹理对应到对象坐标如下所示:
这里采用的是二维纹理,其中纹理坐标(0,0)的点,被绑定到坐标为(-2.0,-1.0,0.0)的物体顶点上,剩下的三个纹理坐标按照逆时针顺序完成绑定对应关系。注意:
1,这里(0,0)原点坐标的位置始终在左下角
2,纹理坐标始(s,t)始终在[0,1]之间,要和对应的矩阵数组的i,j区别开来
那么下面的问题就是,(s,t)与(i,j)的对应关系是怎样的?只有了解了,才能让我们正确的去构造纹理矩阵或者是纹理坐标绑定。下面给出了两张图
第一张是矩阵赋值的示意图。i代表了列,而j代表了行,这里i和j的定义由以下代码实现
#define checkImageWidth 16
#define checkImageHeight 16
很明显,这里i代表了从第0列到第15列,j代表了从第0行到第15行。上门的代码由于是先增量j再增量i的循环,因此这里j对应了纹理坐标的s即x轴,i对应了纹理坐标的t即y轴。因此当我们把纹理坐标s=0,t=1绑定到正方形的顶点(-2,1,0)的时候,即该顶点的颜色应该是j=0,i=15的数组元素,即该顶点为红色。程序的运行也证明了如下图。
当然程序本身也已经指出,i对应的是高度height,j对应的是宽度width。注意这里的高度和宽度是针对纹理图案而并非数组。另外也说明了纹理坐标(甚至于整个OPENGL中的矩阵行列)与C++中多维数组的行列是正好相反的,for循环中i和j的循环顺序没有关系,关键是数组的书写,[i][j] 的形式代表了j为x轴i为y轴。之所以要提到这个,是因为只有明确了这个关系,当我们面对三维纹理的时候,才不会混乱。如该形式的三维数组[r][t][s],其s,t,r正好分别对应了x,y,z,因此赋值的时候要加以注意!
至此,当我们搞清楚了纹理坐标和物体坐标以及相应的数组下标的关系,我们就可以很清楚的看出代码中,某个绑定纹理的物体顶点应该是什么颜色的了,这时候三维纹理的引入就不是那么难以想象的。例如以下代码:
}
我们几乎可以闭着眼睛说出这四个三维顶点对应的颜色,因为他们分别对应着s=t=r=0的纹理数组,s=r=0,t=1的纹理数组.....在这种情况下,纹理是三维还是二维的,又有什么区别呢?