WebGL教程:你的第一个立方体(3)
文章目录
在上一篇文章中,我们介绍了如何使用glMatrix.js来处理3D图形里面的数学运算,主要谈到了MVP的应用。同时,我们还简单地提到了如何使用JQuery来丰富我们的WebGL应用。
本文将介绍如何使用WebGL来制作一个旋转的立方体。在这篇教程里面,我们会提到以下内容:
VBO(Vertex Buffer Object)和IBO(Index Buffer Object)
如何绘制3D立方体
VBO和IBO
VBO就是我们常说的“顶点缓冲区对象”,这个在之前的三角形教程中已经介绍过了。而IBO则是索引缓冲区对象,全称是Index Buffer Object。它主要用来保存顶点的索引数据。
如果我们不使用IBO,而直接使用VBO的话,那么要绘制一个立方体,一共需要6*6=36个顶点。而使用IBO的话,每一个面只需要4个顶点即可,因为两个相邻的三角形是共用两个顶点的。任何复杂的几何模型都可以通过指定顶点和顶点索引定义出来。
首先,让我们看一下立方体的顶点数据定义,这里我们使用的是javascript数组:
|
|
每一个顶点有x,y,z三个坐标,每一个面由两个三角形组成,所以需要6个顶点。不过我们可以这里使用的是IBO来共用顶点,所以每个面只需要4个顶点即可。下面是IBO的定义:
|
|
绑定VBO和IBO并传递数据
首先,当然是创建VBO和IBO了:
|
|
接来是往这两个buffer里面填充数据,WebGL是不能直接把Js的数组传递给GPU的,必须把它们转换成WebGL规定的类型,比如Float32Array和Uint16Array。 具体的代码如下所示:
|
|
vertex shader
指定vertex shader如何读取VBO和IBO里面的数据。 这次我们使用gl.vertexAttribPointer函数时需要注意,最后一个参数是读取数据时的起始偏移量。
|
|
绘制立方体
要绘制立方体,只需要调用gl.drawElements这个函数即可:
|
|
注意这个函数的第1个参数是指绘制几何图元的类型,第2个参数是指索引的个数,第3个参数一定要是gl.UNSIGNED_SHORT或者gl.UNSIGNED_BYTE中的一个,最后一个参数是指索引数据的读取起始偏移量。
这样子绘制出来的立方体它是没有颜色的,如果我们需要每一个顶点指定颜色,则还需要创建一个VBO,然后绑定这个VBO,再通过vertex shader把这个颜色数据传递过去。
传递颜色数据
如果按照传递的c/c++程序的做法,我们一般会定义一个顶点属性的结构体:
|
|
但是,js里面是不能这些定义的。我们可以直接把顶点和颜色放置在一个数组里面就行了:
|
|
此时,如果使用gl.vertexAttribPointer时,strid的计算如下:
|
|
比如,本例中,每一个顶点属性是7个数(3个顶点+4个颜色位):
|
|
Animation Loop
使用requestAnimationFrame制作Animation Loop,避免使用setTimeOut方法。
|
|
程序运行结果:
本文源代码:传送门
结语
这里的顶点数据我们除了使用Javascript数组来存取外,还可以使用json格式的数据。由于json可以给不同的数据命名,比如一个立方体的数据可以描述为以下json文件:
|
|
另外,json文件还可以使用AJAX来加载,这样我们就可以把需要绘制的顶点数据存在服务器上,需要的时候发一个AJAX请求即可。该方法特别适合于复杂模型的加载。