本文最先发表在贴吧,现在整理到此处,之后所有更新将在这里进行。
by Chu @ XDU 2012/11/25
版权所有,禁止用于商业用途。
转载请注明出处。
用DX9做一个2D游戏显然不是一件容易的事情。本文主要面向所有初学者所写,因此会广而不精地讲解2D游戏编程中遇到的各方面东西,主要以API为讲解对象。至于算法,因为不同游戏涉及的不一样,所以不一定会在下文讨论到。
一、图形呈现过程
【注:这部分内容其实应该和D3D一起讲,但是既然写在了前面,就先讲掉了,等用到的时候再回来看。】
对于游戏而言,最重要的就是视觉效果,于是怎么呈现图像,图像怎么呈现的,这是游戏编程中最核心的地方。
计算机中表示三维图形的方法只能是使用三角形去表示一个面,对于长方体,就用两个三角形表示,对于球,就用一大堆三角形去近似表示,三角形数量越多越精细。而所谓的曲面细分也是如此,本质上就是产生一大堆三角形。
于是为了在空间显示三角形,就要指定三个顶点的坐标,为了让三角形填充上颜色,可以为三角形的顶点加上颜色,然后计算机会在光栅化过程中对三角形中的像素进
行插值,算出颜色再填上去。于是一个三角形就诞生了。然后,为了更加丰富表示色彩,又加上了贴图。为了方便定位,又给每个顶点加上了贴图坐标(u,v),
然后光栅化的时候就会在贴图上算出坐标进行插值。
在拥有三角形信息之后,需要把图形的坐标转换到屏幕坐标空间
于是矩阵的作用就在这里体现了,用一个矩阵去表示一种变换过程,再通过Shader或者固定的渲染管线去对每一个点进行一下矩阵变换,使之变换到屏幕坐标空间。
计算公式类似于:
V变换后 = V原始 * Matrix变换 【注:对于行式和列式,乘法顺序不同】
无论你家显示器是什么分辨率的,屏幕坐标空间的XY坐标范围都是(-1.0~1.0),而对于Z坐标,其取值通常是0.0~1.0(对于D3DVIEWPORT9里面的ZMin和ZMax),然后越往屏幕里面Z越大,OPENGL则与DX不同。
对于DX9和GL上的固定渲染管线而言,这一阶段,程序员要做的就是提供变换矩阵和要变换的这些点的信息(包括点数据,每个点的数据组成方式(FVF顶点格式)),然后管线会自动完成计算。而对于Shader可编程管线而言,这部分同样要提交上面的数据,而且这部分的变换交给程序员自己编写的Shader代 码负责(VertexShader)。GL同理。
接下来,显卡则会开始光栅化过程,而这部分,显卡会去读取提交给他的纹理数据以及上一步变换完成 的顶点数据,然后在绘图同时完成ZBuffer深度测试、模板测试、Alpha测试以检查三角形上的像素是否会被绘制。如果会被绘制,则会画到缓冲区上, 最后该阶段结束,缓冲区被刷到屏幕上呈现(Present)出来。
对于可编程渲染管线,该过程全程(各种测试依旧由显卡完成)由PixelShader负责,负责决定什么颜色会被画到屏幕上。
整个绘图过程大致就是这样。
1.1 2D与3D
对于所谓的2D游戏,也就是只要x,y坐标即可。通常,2D游戏会以窗口左上角为原点,右侧下侧为正方向。而现在我们要用3D空间去描述一个2D点。为了简单起见,我们要求2D坐标系和数学上的坐标系一致,以屏幕中间为坐标原点,上方右方为正方向。这样,我们的坐标系就和上图的屏