首先,这个框架有3个文件组成,d3dUtility.h/cpp与d3dinit.cpp。编写的时候应该首先从d3dUtility.h开始。
在这个头文件中,包含了5个函数:initD3D, EnterMsgLoop, WndProc, Release和Delete。其中后两个是两个模板函数,主要用于Release和Delete对象,这两个函数比较简单,这里就不说明了。
接下来,就需要在d3dUtility.cpp中实现这几个函数。由于WndProc牵扯到对游戏的控制(WM_KEYDOWN消息的处理在WndProc这个回调函数中),所以作者选择将这个函数放到d3dinit.cpp中进行编写。先看EnterMsgLoop这个函数:
这个函数中,主要就是对MSG的对象msg的判断,根据其消息类型判断,如果没有消息,那么就调用绘图函数进行绘制,这个对于有过Windows游戏编程经验的人来说,应该不会陌生。
接下来是最关键的D3D初始化部分代码,d3dInit()这个函数。这个函数可以看成两大部分,第一部分是对Windows窗口的初始化,分为4步:
1.填充WNDCLASS结构体,并调用RegisterClass注册这个结构体。
2.利用CreateWindow这个函数创建HWND对象。
3.调用ShowWindow方法显示窗体。
4.调用UpdateWindow方法更新窗体。
需要注意的是,由于作者把d3dUtility放到了d3d这个命名空间中,因此这里我们需要使用::来应用以上的这些函数。
然后就该初始化D3D了。初始化D3D的目的是为了创建IDirect3DDevice对象,这个对象用于之后的绘制图像等功能。为了初始化D3D,也有四步:
1.创建IDirect3D9对象,这个对象主要用于获取设备的能力以及创建IDirect3DDevice对象。
2.利用D3DCAPS9对象获取显示卡的能力,并判断使用硬件顶点处理还是软件顶点处理。使用一个int数vp记录结果。其实这个vp还可以记录其他的设备信息,但是作为一本教程的实例代码,作者没有判断其他的Behavior。
3.填充D3DPRESENT_PARAMETERS结构。这个主要是设置显示的效果。
4.利用d3d9->CreateDevice创建device。
至此初始化工作就完成了。咱们的d3dUtility也实现的差不多了,只有一个WndProc函数没有实现,放到了d3dinit.cpp中来实现。
最后我们来看一下d3dinit.cpp这个文件。大体浏览一下代码,发现了WinMain这个函数。这个函数内部的执行思路非常清晰,首先初始化D3D,然后Setup,之后EnterMsgLoop,当用户选择退出之后(从EnterMsgLoop这个函数返回),则执行Cleanup方法,最后是释放IDirect3DDevice9对象,并返回。