关于DXUT框架:
DXUT(The DirectX Utility Library) 是建立在Direct3D9 和Direct3D10 API上的一个程序框架。它的目标是建立一个强大而容易使用的Direct3D 游戏开发的示例、原型和工具。它简化了典型的Windows和Direct3D API的使用。
DXUT是一种设计给游戏程序设计者用来节省编程时间和调试寻常问题(如:创建窗口、创建设备、处理窗口消息和控制设备事件)的程序框架。
特别和局限:
DXUT 帮助我们做以下工作:
1、创建窗口。
2、选择Direct3D设备。
3、创建Direct3D设备。
4、控制(操作)设备事件。
5、处理窗口事件。
6、连接(协调)窗口模式和全屏模式。
7、纹理GUI控件
8、附加功能类,比如简单的摄像机
DXUT框架支持Direct3D设备和窗口一一对应。所以对于同时使用多个设备或者显示多个Direct3D窗口的高级应用程序,该框架不支持。不过对于大多数的一对一应用程序,DXUT框架是完全适合的。
创建一个DXUT框架:
在Directx SDK的安装目录下打开Microsoft DirectX SDK (March 2009)SamplesSampleBrowserSampleBrowser.exe。这是DX sdk附带的案例集合。找到如下的项目:EmptyProject
这个就是DXUT的基础实例。在VS中打开项目sln的就可以看到源码。
上图就是项目结构了。其中的DXUT.h和DXUT.cpp是DXUT的主要文件。而EmptyProject.cpp就是项目主程序文件,在这里面编写了各种回调函数的处理,EmptyProject.cpp内容如下。
//--------------------------------------------------------------------------------------
// File: EmptyProject.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "DXUT.h"
#include "resource.h"
//--------------------------------------------------------------------------------------
// 创建设备时 对所有可用设备进行过滤的函数。通过返回false来否决应用程序不接受的D3D设备
//--------------------------------------------------------------------------------------
bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
bool bWindowed, void* pUserContext )
{
// 过滤不支持alpha混合的函数
IDirect3D9* pD3D = DXUTGetD3D9Object();
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
return false;
return true;
}
//--------------------------------------------------------------------------------------
// 更改设备的回调函数,用于处理更改设备所需要做的事情
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )
{
return true;
}
//--------------------------------------------------------------------------------------
// 创建设备的回调函数,用于创建D3DPool_Managed资源
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
return S_OK;
}
//--------------------------------------------------------------------------------------
// 重设设备的回调函数,用于创建D3DPool_Default资源
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
return S_OK;
}
//--------------------------------------------------------------------------------------
// 场景更新的回调函数,用于矩阵变换等操作处理
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// 渲染场景实现。
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
HRESULT hr;
//清除缓存
V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 45, 50, 170 ), 1.0f, 0 ) );
// 绘制场景
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
V( pd3dDevice->EndScene() );
}
}
//--------------------------------------------------------------------------------------
// 处理程序获得的消息
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool* pbNoFurtherProcessing, void* pUserContext )
{
return 0;
}
//--------------------------------------------------------------------------------------
// 出现设备丢失的处理函数,释放OnResetDevice创建的资源
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9LostDevice( void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// 设备析构的回调函数,释放OnCreateDevice创建的资源
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// 入口函数,初始化win窗口并进入消息循环和场景渲染
//--------------------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int )
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
// 设置回调函数
DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );
DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );
DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );
DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );
DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackFrameMove( OnFrameMove );
// TODO: 添加应用程序需要初始化的逻辑代码
// 初始DXUT窗口,创建Direct3D设备对象。
DXUTInit( true, true ); // Parse the command line and show msgboxes
DXUTSetHotkeyHandling( true, true, true ); // handle the default hotkeys
DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
DXUTCreateWindow( L"EmptyProject" );
DXUTCreateDevice( true, 640, 480 );
// 进入消息循环和场景渲染
DXUTMainLoop();
// TODO: 添加应用程序清除工作的代码
return DXUTGetExitCode();
}
从上面的代码可以看出,EmptyProject.cpp是基于DXUT框架的。它创建了一个窗口和一个Direct3D设备,处理消息循环。当事件发生的时候,就会调用应用程序提供的回调函数。
// File: EmptyProject.cpp
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "DXUT.h"
#include "resource.h"
//--------------------------------------------------------------------------------------
// 创建设备时 对所有可用设备进行过滤的函数。通过返回false来否决应用程序不接受的D3D设备
//--------------------------------------------------------------------------------------
bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
bool bWindowed, void* pUserContext )
{
// 过滤不支持alpha混合的函数
IDirect3D9* pD3D = DXUTGetD3D9Object();
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
return false;
return true;
}
//--------------------------------------------------------------------------------------
// 更改设备的回调函数,用于处理更改设备所需要做的事情
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )
{
return true;
}
//--------------------------------------------------------------------------------------
// 创建设备的回调函数,用于创建D3DPool_Managed资源
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
return S_OK;
}
//--------------------------------------------------------------------------------------
// 重设设备的回调函数,用于创建D3DPool_Default资源
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
return S_OK;
}
//--------------------------------------------------------------------------------------
// 场景更新的回调函数,用于矩阵变换等操作处理
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// 渲染场景实现。
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
HRESULT hr;
//清除缓存
V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 45, 50, 170 ), 1.0f, 0 ) );
// 绘制场景
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{
V( pd3dDevice->EndScene() );
}
}
//--------------------------------------------------------------------------------------
// 处理程序获得的消息
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool* pbNoFurtherProcessing, void* pUserContext )
{
return 0;
}
//--------------------------------------------------------------------------------------
// 出现设备丢失的处理函数,释放OnResetDevice创建的资源
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9LostDevice( void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// 设备析构的回调函数,释放OnCreateDevice创建的资源
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// 入口函数,初始化win窗口并进入消息循环和场景渲染
//--------------------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int )
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
// 设置回调函数
DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );
DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );
DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );
DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );
DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackFrameMove( OnFrameMove );
// TODO: 添加应用程序需要初始化的逻辑代码
// 初始DXUT窗口,创建Direct3D设备对象。
DXUTInit( true, true ); // Parse the command line and show msgboxes
DXUTSetHotkeyHandling( true, true, true ); // handle the default hotkeys
DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
DXUTCreateWindow( L"EmptyProject" );
DXUTCreateDevice( true, 640, 480 );
// 进入消息循环和场景渲染
DXUTMainLoop();
// TODO: 添加应用程序清除工作的代码
return DXUTGetExitCode();
}
从上面的代码可以看出,EmptyProject.cpp是基于DXUT框架的。它创建了一个窗口和一个Direct3D设备,处理消息循环。当事件发生的时候,就会调用应用程序提供的回调函数。
并且可以清楚的看到DXUT整个框架是模块化的。应用程序可以使用DXUT框架的所有函数或者其中的部分功能。由此我们可以简单的理解DXUT的生命周期就如下图。
而在退出程序时,DXUT框架会调用OnD3DLostDevice()和OnD3DDestroyDevice()。释放之前创建的资源。