通俗的说OpenGL画图原理3
我的上一篇创新文档讲解了OpenGL如何根据观察坐标系中的3D坐标点来计算得到2D屏幕坐标系的坐标点,其主要运算就是三个,即投影、图元剪裁和屏幕映射。在这篇文章里,我会给大伙说说观察坐标系的3D坐标点是如何得来的,以及OpenGL都做了哪些运算。
我们先从3DS MAX建模得到的模型文件讲起吧,这样对于理解的效果应该会好点。模型文件,如游戏中用到的MD2文件,里面保存了建模后的一些数据,最主要的数据就是模型的顶点数据,其他还有帧动画或者骨骼矩阵,法向量等。我们只需要把焦点放到顶点就可以了。最简单的,比如美工做了个三角形的模型文件,里面肯定有三个顶点的数据。比如:A(Ax、Ay、Az)、B(Bx、By、Bz)、C(Cx、Cy、Cz)。这种模型中的顶点,我们可以称之为位于局部坐标系或者模型坐标系中的顶点。事实上,程序处理的就是这些顶点,并通过OpenGL的图形运算来得到2D屏幕上的坐标点。除了刚刚说到的局部坐标系,我们还需要知道另外两个重要的坐标系:世界坐标系和观察坐标系。
局部坐标系中的坐标点,如刚刚提到的模型文件中的三角形的三个坐标点,通过一定的矩阵运算会被变换到世界坐标系中,位于世界坐标系中的这三个坐标点经过矩阵运算后,又被变换到观察坐标系中。这就是观察坐标系中3D坐标点的来源。我们结合一张图来解释一下,如下图所示,假设三角形ABC为局部坐
标系XOZ(大写)中的坐标点:A(-1, 0, 1)、B(1,0,1). C(0, 0, 0),这里暂且忽略Y轴,因为原理是一样的。观察坐标系则为图中的xoz(小写),嗯,世界坐标系去哪里啦?我们可以假设这里世界坐标系跟三角形所在的局部坐标系重合了,呵呵,这样又会简化许多,我画图也容易很多。可这句话应该怎么理解呢?正如我上面提到的:局部坐标系中的坐标点通过矩阵运算可以变换到世界坐标系中,而世界坐标系中的坐标点通过矩阵运算又可以变换到观察坐标系中(紧跟着发生的事情上一篇已经讲过了)。注意这里的矩阵运算,每一次坐标系之间的变换都需要通过矩阵来实现,而当这个矩阵为单位矩阵时,位于局部坐标系中的坐标点在经过矩阵运算之后,将不会发生任何变化,这时我们就可以理解为局部坐标系跟世界坐标系重合了。你也可以理解为这个三角形的中心刚好位于世界的中心了。可以想象,如果所有物体都在世界中心(矩阵都是单位矩阵),那意味着所有物体都画在一起了,看上去就是挤成一堆。因此,一般不会这样做,每一个三角形(你应该理解为一个模型文件的抽象形式,而不是模型文件中的每一个三角形)的中心,在世界中都会有自己的位置,只有这样,才能构成我们的游戏场景。
话说刚刚那张图,既然局部坐标系跟世界坐标系重合了,那局部坐标系中的坐标点也就算是世界坐标系中的坐标点了。接着,又会经过一定的矩阵运算(图中只需要平移就可以了),得到这三个坐标点在观察坐标系xoz中的值,大概瞄了一下,差不多是a(-3,0,3)、b(-1, 0, 3)、c(-2, 0, 2)。这样就完成了坐标点的转换。
上面的讲解涉及到两个矩阵运算,事实上,OpenGL在实现上只有一次矩阵运算,因为它把两个矩阵合并了,因为矩阵是可以相乘的(但不满足结合律)。但一般我们还是会从逻辑上进行分开,因为这样便于理解。比如第一个矩阵我们称之为模型变换矩阵,第二个矩阵为观察变换矩阵。每一个矩阵都是通过OpenGL的API进行设置并形成的,这些API对顶点的作用主要有三个:平移、旋转和缩放。比如上图中的变换就只需要平移就可以了。这些API具体怎么用,这里没必要详细解释了,只希望能给没接触过OpenGL的人做个大体上的入门讲解,属于概念上的普及吧。
通篇都是文字,让各位眼睛受苦了,我的OpenGL画图原理应该也就这样了。事实上OpenGL的细节远远不是我这三篇说得完的,甚至基本的都还没有介绍完。而一款大型3D游戏其效果上的制作也不是精通OpenGL的API就可以完成的,我认为关键还是在于游戏场景数据的组织和优化,毕竟PC机性能是有限的。