Directx sdk版本:April 2006
Visual Studio 2005
可能因为版本问题,安装SDK后没有在Visual Studio中生成D3D项目的向导,所以选择从DirectX Sample Browser中安装EmptyProject项目。
下面就对EmptyProject的框架结构稍作解析,以备忘。
整个框架最重要的类是DXUTState类。
在它的内部定义了一个结构State,这个结构的成员变量包含了D3D程序所需要的绝大多数属性和变量,包括设备,消息句柄,键盘鼠标输入,窗口状态,游戏循环和渲染函数等诸多内容。(要注意的是这里的函数都是指函数指针,比如OnFrameMove,OnFrameRender,MsgProc等用户需要自定义的函数都将通过函数指针被连接到这个结构中)
DXUTState类中唯一的一个保护成员变量是State类型的m_state,其他所有的公有成员函数(除了构造和析构函数)都是在get和set m_state中的变量。
现在可以说,整个框架的核心是State结构,又只能通过DXUTState类来使用它。
然后,DXUTState类又只能通过 DXUTState& GetDXUTState()这个函数来调用。整个函数非常短小精悍,如下:
DXUTState& GetDXUTState()
{
// Using an accessor function gives control of the construction order
static DXUTState state;
return state;
}
它的功能很简单,就是获取并返回核心结构state的状态。它在DXUT.CPP中定义,在DXUT.h中没有声明,也就是说它只能在DXUT.CPP内部使用。而在DXUT.CPP中有5000多行代码,包含100多个函数,几乎都会用到它。
这100多个函数中控制了框架运行的全过程,从启动到退出,从初始化3D设备到释放内存等。
接下来进入EmptyProject.cpp文件,这里面定义了几个空函数,包括OnCreateDevice,OnResetDevice OnLostDevice,OnDestroyDevice,MsgProc,OnFrameRender,OnFrameMove等,我们可以在这里随意编辑这些函数的内容,随后它们都将在主函数中以函数指针的方式被连接到程序核心结构State中去。
下面找到WinMain函数,也就是程序的入口,代码如下:
INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
DXUTSetCallbackDeviceCreated( OnCreateDevice );
DXUTSetCallbackDeviceReset( OnResetDevice );
DXUTSetCallbackDeviceLost( OnLostDevice );
DXUTSetCallbackDeviceDestroyed( OnDestroyDevice );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackFrameRender( OnFrameRender );
DXUTSetCallbackFrameMove( OnFrameMove );
DXUTInit( true, true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes
DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
DXUTCreateWindow( L"A" );
DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 900, 600, IsDeviceAcceptable, ModifyDeviceSettings );
DXUTMainLoop();
return DXUTGetExitCode();
}
第一段代码的功能是在调试时检查内存泄漏。
第二段是设置回调函数,这七个函数都在DXUT.CPP中定义,括号中的参数就是我们上面提到的空函数,我们可以随意编辑其功能和内容。举DXUTSetCallbackDeviceCreated( OnCreateDevice )为例,它在DXUT.CPP中的定义如下:
void DXUTSetCallbackDeviceCreated( LPDXUTCALLBACKDEVICECREATED pCallbackDeviceCreated,
void* pUserContext )
{
GetDXUTState().SetDeviceCreatedFunc( pCallbackDeviceCreated );
GetDXUTState().SetDeviceCreatedFuncUserContext( pUserContext );
}
实际上功能非常简单,就是把我们编写的OnCreateDevice函数的指针赋给State结构中的m_DeviceCreatedFunc变量,这个变量是一个函数指针。
第三段代码是程序的初始化,包括建立设备和窗口等。
第四段就是最主要的游戏循环,以后将详细分析。
最后就是退出程序。