本章将使用GLStaticMesh对象绘制原id Software公司经典的Quake3引擎(雷神之锤3)的游戏场景(或关卡地图)。

之所以选择id Software公司相关的技术来演示GLStaticMesh的用法,一个主要的原因是Quake3 BSP关卡地图(或场景)使用二进制存储方式,能够让大家了解TS/JS中如何进行二进制文件的解析(演示ArrayBuffer和DataView对象的好时机)。

3D图形编程是一个非常庞大的主题,从宏观角度,笔者将整个3D图形编程分为三个层次,既画出来、画的美以及画的快。而本书的定位仅仅是画出来这个层次,因此并不实现BSP的材质渲染系统(属于画的美范畴)以及场景管理系统(属于画的快范畴)。

所以本章定位很明确,就是将Quake3 BSP场景画出来。

本章主要讲解了如下三个类的实现:

  • 首先是Q3BspApplication,该类继承自CameraApplication类,因此你可以任意的移动或旋转摄像机,从而达到在Quake3 BSP场景中进行漫游。Q3BspApplication内部的run虚函数被覆写(override),从而从服务器载入Quake3 BSP二进制文件,然后调用Quake3BspParser类进行Quake3 BSP文件的解析,当整个BSP文件解析完成后,再加载所有纹理,当整个渲染资源准备就绪后,就调用Q3BspScene的draw方法不停的渲染整个场景。

  • 接着了解Quake3BspParser类的实现,该类使用DataView对象,将从服务器获得使用ArrayBuffer存储的BSP二进制文件解析成相关的渲染数据结构的数组集合,为Quake3BspScene的绘制提供渲染数据源。整个BSP文件具有17个二进制数据块,但是本书仅解析了与渲染绘制相关的数据,并没有涉及到与场景管理、碰撞检测、光照图等相关的数据解析。

  • 最后为了能将Quake3BspParser解析后的数据符合GLStaticMesh对象的存储结构,需要进行相关的数据转换操作,该操作通过Quake3BspScene类的compileMap方式实现。一旦生成GLStaticMesh对象后,我们就将整个Quake3 BSP渲染流程并入到第5章实现的WebGLUtilLib库的架构中去,这样就整合了整个代码流程。

总结一下渲染Quake3 BSP场景的要点:

  • 如何使用DataView对象来操作ArrayBuffer数据,特别是如何计算字节偏移量?

  • Quake3 BSP文件中顶点坐标系与纹理坐标系与WebGL坐标系区别在哪里,如何进行转换?

  • Quake3 BSP三角形定义的手相性是顺时针还是逆时针,你将如何使用WebGL来处理三角形的背面剔除操作?

  • 如何寻址Quake3 BSP中的顶点数据和索引数据,从而能够进行正确的绘制操作?

如果能解答上述四个问题,那么你已经掌握了本章的主旨。