一些游戏程序的基础知识(二)

  在《游戏主循环、帧数控制》中提到了游戏主循环中最主要执行的两个方法updateEverything()drawEverything(),就是游戏程序中【逻辑更新】和【图形绘制】两件最重要的工作。这里再聊聊图形绘制又是怎么做的吧。

管理场景的节点(drawEverything)

  游戏场景中的物件通过树的结构组织更方便做操作和扩展。在Cocos2d-x中可能会组织成这样的游戏场景节点树:

The node tree example

  CCDirector可以认为是程序的入口,CCScene节点才是整棵树的根节点,各种游戏对象则按照一定的方式从根节点开始连接成树的结构。当你操作每一个对象的坐标时,它的实际位置只会相对于父节点的坐标进行变化;当你设置了父节点的可见性以后,它的子节点的可见性也会传递下来。
  熟悉图形学就知道,其实内部实现中每个节点的几何信息,各自是由一个4x4float的变换矩阵来储存和处理的。通过矩阵乘法就可以从相对变换计算得在跟节点上的绝对变换,并且将每一个树分支上的节点几何信息传递下来。计算得的最终变换就可以提供给图形接口,然后就能把图形绘制到正确的位置上。
  这个图形几何信息的计算和绘制过程,在程序里也就是一个节点树的递归遍历的过程。具体工作是通过CCNode::getChildren(), CCNode::visit()以及CCNode::transform()三个函数的组合来完成的,具体逻辑详见源码,简单说就是个树的递归遍历。当每一个节点的变换计算完成就顺便执行一下CCNode::daw()方法调用绘图的接口,这样就可以完成整个游戏所有物件几何信息的计算和图形的绘制了(注:Cocos2d-x 2.0的版本计算完成就会马上进行绘制,到了3.0版本的draw()不会直接绘制,而是变为发送一个绘图指令到渲染队列中进行集中处理和优化,又是更进一步的管理了)。

Draw函数

  有个很复杂的函数叫做Draw函数,为什么说它很复杂呢,让我给你稍微解释一下。
  我们都知道图片文件是什么对吧,那些.png、.jpg结尾等等的图片在电脑上一般双击就可以显示到屏幕上了。事实才没有这么简单了,一个图片的显示在程序中一般可能要经过这样的流程(With OpenGL):

The render pipeline

  我们在前文中提到的遍历节点树和生成变换矩阵的过程就是完成图里所示的,CPU程序部分的“变换矩阵”的这一个环节。那么剩余的选择纹理,生成顶点数据,设置渲染参数,应用Shader程序和执行各种渲染的环节都只能放在这个Draw函数里来完成了。再具体是怎么做的呢,那就是一般计算机图形学所学的内容啦。

标题目录