先讨论一下SDK中自带的例子:Meshes。该程序的效果是一个老虎模型绕世界坐标原点持续地旋转。
程序主循环
其程序流程如下:
WinMain()-> InitD3D()->InitGeometry()->Render()->cleanup() |
其中WinMain()是程序入口,MsgProc() 处理程序的消息的回调函数,InitD3D()做程序的初始化工作InitGeometry()负责模型的加载,材质纹理的设置等,Render()负责渲染操作,在Render()中调用的SetupMatrices()设置世界矩阵,视图矩阵以及投影矩阵。在MsgProc()中调用的cleanup()负责资源释放.
消息循环
添加系统接收外部事件的CInputSystem类,控制鼠标事件的CMouse类,控制键盘事件的CKeyboard类,由鼠标或键盘产生的事件消息可由漫游类Roam的updaye()函数处理。
渲染系统
设计一场景类Scene,不难发现,模型,材质,纹理,渲染等都属于场景里的东西,可将InitGeometry() 和Render()作为其成员函数,设计一模型类Model,再将SetupMatrices()中世界矩阵的操作分离出来,作为Model类的一个成员函数,再为Model设计一个实现模型加载的成员函数InitGeom(),该函数可由Scene类的InitGeometry()调用。为Scene设计一update()函数该函数是每帧均运行的,负责即时更新 Camera的信息和即时鼠标键盘事件的处理,故需在Scene::update()调用Camera的update()和漫游类Roam的update()
漫游系统
设计一漫游类Roam,用于处理系统接收的鼠标和键盘消息,为其设计一成员函数update()作为接收事件的接口,该函数可由Scene类的Rend()函数调用,这样可在Scene的Rend调用Scene的update(),Scene的update()调用Roam的update().
设计一摄像机类Camera,将SetupMatrices()中视图矩阵和投影矩阵的操作分离出来,作为Camera的一个成员函数update().
现通过Model类的InitGeom()函数加载数个老虎模型,并添加天空和地面模型,设置其在世界坐标系的位置,并在Roam的 update()函数实现处理鼠标和键盘事件的功能。最终完成了可通过触发鼠标和键盘事件控制整个场景上下左右旋转的D3D程序.
效果图如下:
绕Z轴旋转后: