![v2-391331812448b3c33c83ba52d7261851_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=c647c525-482e-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-391331812448b3c33c83ba52d7261851_b.jpg)
顶点缓存的重复利用
上一篇文章中,向多边形的三个顶点中添加了颜色这个新的顶点属性,给多边形涂抹了颜色。而且知道,使用新的VBO可以给对顶点属性进行自由的扩张。
那么,这次来挑战一下同时绘制多个模型。但是,不准备新的VBO,还利用上次的VBO,就是说,重复利用VBO,只操作坐标变换矩阵,来绘制多个模型。
所以,这次着色器相关的内容完全不变,完全使用上次的顶点着色器和片段着色器,javascript代码变更的地方也不多,下面重点说一下变更的部分。
坐标变换矩阵的重复利用
这次绘制多个模型,坐标变换矩阵相关也是重复利用。
也就是说,在实际中,将多个模型绘制到不同的位置的时候,必须要操作的坐标变换矩阵只有模型变换矩阵,而决定镜头的位置的视图变换矩阵和决定屏幕范围的投影变换矩阵这两个坐标变换矩阵,都可以使用同一个。
步骤如下,按照下面这样操作矩阵的话就可以了。
- 准备好视图和投影两个坐标变换矩阵
- 提前将两个矩阵相乘并保存起来(以下、pv)
- 准备第一个模型坐标变换矩阵(以下、m1)
- m1和pv相乘,传给uniform
- 绘制第一个模型
- 准备第二个模型坐标变换矩阵(以下、m2)
- m2和pv相乘,传给uniform
- 绘制第二个模型
- 刷新context
主要是,视图坐标变换矩阵和投影坐标变换矩阵提前相乘并保存起来,然后等模型坐标变换矩阵准备好之后,再与之前的结果相乘,传给uniform,然后绘图。
那么,来看一下实际的代码吧。
//各种矩阵的生成和初始化
重点是,为了暂时保存视图和投影坐标变换矩阵,新声明了一个tmpMatrix这样的使用方法。使用matIV.multiply将视图坐标变换矩阵和投影坐标变换矩阵相乘,然后结果保存到tmpMatrix中。
然后,使用matIV.translate来操作模型坐标变换矩阵,将第一个模型向X方向移动1.5,然后将这个模型坐标变换矩阵和tmpMatrix相乘,传给uniform并进行绘图。
第二个模型的坐标矩阵,和之前相反,向X方向上移动-1.5,然后和第一个一样,和tmpMatrix相乘,传给uniform并进行绘图。
最后,刷新context,在canvas上绘制两个多边形。这样,利用VBO和一部分坐标变换矩阵,省去了不必要的代码,绘制了两个多边形。
需要注意的是,对第二个模型准备模型坐标变换矩阵的时候,首先在最初的时候使用matIV.identity对矩阵进行初始化。如果,不进行初始化直接使用matIV.translate的话,会受前一回移动的影响,导致结果改变。进行完初始化之后再进行操作,是为了避免类似这样的错误发生。
附加:attribute属性添加的函数化
上次的文章中也涉及到了,增加顶点属性的时候,如果将相应的处理函数化的话可以提高效率,虽然和这次的主题(绘制多个模型)没有关系,但是因为demo中进行了函数化,所以简单的解说一下。
// 绑定VBO相关的函数
这个函数有三个参数,三个参数都是数组。使用for ~ in来循环VBO中的属性,并进行绑定和添加。一般,需要准备很多个VBO,所以将这里函数化,以后可以省略很多代码了吧。
总结
这次操作的是模型坐标变换矩阵,介绍了重复利用VBO,视图和投影坐标变换矩阵,进行多个模型的绘制的方法。
绘制很多个简单的模型,图形的时候,像这次的做法一样,可以使处理变的简洁一些,避免写很多多余的代码。
这次的demo,HTML的代码和上一次是完全一样的,就是说,顶点着色器和片段着色器没有做任何调整。javascript代码有了一些变化,所以贴出所有代码。另外,在文章的最后面,添加了demo的链接,有支持WebGL的浏览器的话,可以直接打开链接看一下效果。
下次,进一步操作模型坐标变换矩阵,对绘制的模型进行各种各样的处理。
onload