28 WebGL绘制立方体

案例查看地址:点击这里

到现在为止,一直学的都是绘制一些简单的三角形。下面,我们将学习如何绘制如图所示的一个立方体,目标:

28 WebGL绘制立方体_第1张图片

如果按以前所学的知识,制作这个正方体就需要使用三角形两个拼一个矩形,最后拼出来六个正方形来组成这个立方体,由于绘制三角形需要重复调用顶点,虽然只需要8个顶点的位置,但是,绘制三角形的时候,却需要多次调用,所以给我们提供了一个gl.drawElements()函数的解决方案。使用该函数替代gl.drawArrays()函数进行绘制,能够避免重复定义顶点,报错顶点数量最小。为此,你需要知道模型的每一个顶点的坐标,这些顶点坐标描述了整个模型。

我们将立方体拆成顶点和三角形,如图7.32所示。立方体呗拆成6个面:前、后、左、右、上、下,每个面都由两个三角形组成,与三角形列表中的两个三角形相关联。每个三角形都有3个顶点,与顶点列表中的3个顶点相关联。三角形列表中的数字表示该三角形的3个顶点在顶点列表中的索引值。顶点列表中共有8个顶点,索引值为从0到7。

28 WebGL绘制立方体_第2张图片

而现在新的gl.drawElements()方法就是通过顶点索引绘制物体,首先我们来看一下如何使用gl.drawElements(),我们需要在gl.ELEMENT_ARRAY_BUFFER(而不是之前一直使用的gl.ARRAY_BUFFER)中指定顶点的索引值。所以两种方法最重要的区别就在于gl.ELEMENT_ARRAY_BUFFER,它管理这具有索引结构的三位模型数据。

28 WebGL绘制立方体_第3张图片

如果传入的type参数和gl.ELEMENT_ARRAY_BUFFER中的数据类型(Uint8Array或Uint16Array)不一致,也并不会出现错误。但是如果两者不一致,比如缓冲区是Uint16Array类型的,而传入的参数为gl.UNSIGNED_SHORT,那么程序会错误地理解缓冲区中的数据,并会绘制出一些不可预测的东西。

下面书写一个案例:

28 WebGL绘制立方体_第4张图片




    
    
    
    Title
    









在124行:

本案例不再使用verticesColor中的顶点顺序来进行绘制,所以必须额外注意每个顶点的索引值,我们要通过索引值来指定绘制的顺序。比如说,第1个顶点的索引为0,第2个顶点的索引为1,等等。

183行:

缓冲区对象indexBuffer中的数据来自于数组indices,该数组以索引值的形式存储了绘制顶点的顺序。索引值是整型数,所以数组的类型是Uint8Array(无符号8位整型数)。如果有超过256个顶点,那么就应该使用Uint16Array。indices中的元素如图7.33中的三角形列表所示,每3个索引值为1组,指向3个顶点,由这3个顶点组成1个三角形。通常我们不需要手动创建这些顶点和索引数据,因为三维建模工具会帮助我们创建它们。

28 WebGL绘制立方体_第5张图片

在调用gl.drawElements()时,WebGL首先充绑定到gl.ELEMENT_ARRAY_BUFFER的缓冲区(也就是indexBuffer)中获取索引值,然后根据该索引值,从绑定到gl.ARRAY_BUFFER的缓冲区(即vertexColorBuffer)中获取顶点的坐标、颜色等信息,然后传递给attribute变量并执行顶点着色器。对每个索引值都这样做,最后就绘制出了整个立方体,而且值调用了一次gl.drawElements()。这种方式通过索引来访问顶点数据,从而循环利用顶点信息,控制内存的开销,但代价是你需要通过索引来简介地访问顶点,在某种程度上使程序赋值话了,所以,两个绘制方法各有优劣,具体用哪一个取决于具体的需求。

你可能感兴趣的:(webgl,3d模型,立方体,WebGL)