文档章节

DXUT框架剖析(1)

rise-worlds
 rise-worlds
发布于 2016/06/20 13:38
字数 1879
阅读 6
收藏 0

DXUT(也称sample framework)是建立在Direct3D API之上的Direct3D应用程序框架,有了DXUT这样一个Direct3D程序框架,只需在这个框架的基础上编写相应的代码,从而简化了windows和Direct3D API的使用,可以高效地进行Direct3D程序设计。

生成一个Direct3D程序框架

第一步,运行Direct3D示例程序浏览器:

第二步,单击"EmptyProject"中的"Installl Project"安装工程:

第三步,在弹出的对话框中输入新工程的名称,修改该工程的创建路径,单击Install即可创建工程:

第四步,系统将自动完成工程的创建,然后弹出对话框询问是否查看创建的工程文件夹中的内容:

若选择是,则可以查看新创建的工程文件夹的内容:

使用Direct3D程序框架

通过上面的操作,Direct3D已经为我们创建好了一个应用程序框架,该框架主要包括以下文件:

其中最主要的两个文件是DXUT.h和DXUT.cpp。

除了上面这些通用文件外,Direct3D还生成了一个主程序文件,该文件的名字和工程名字相同,在此即是AppFrame.cpp。该文件主要由以下几个回调函数构成:

bool CALLBACK IsD3D9DeviceAcceptable(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, 
bool bWindowed, void* pUserContext);
bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings, void* pUserContext);
HRESULT CALLBACK OnD3D9CreateDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
void* pUserContext);
HRESULT CALLBACK OnD3D9ResetDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, 
void* pUserContext);
void CALLBACK OnFrameMove(double fTime, float fElapsedTime, void* pUserContext);
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, 
bool* pbNoFurtherProcessing, void* pUserContext );
void CALLBACK OnD3D9LostDevice( void* pUserContext );
void CALLBACK OnD3D9DestroyDevice( void* pUserContext );

函数名前使用"CALLBACK"表示声明的是一个回调函数,也就是说,这是DXUT框架为我们设置好的接口,DXUT框架将在合适的时机调用相应的回调函数。现在我们需要做的就是在这些回调函数中填写相应的代码完成所需要的功能。为了使DXUT框架能够调用这些回调函数,还需要在WinMain函数中为DXUT框架设置这些回调函数,代码如下:

// Set the callback functions
DXUTSetCallbackD3D9DeviceAcceptable(IsD3D9DeviceAcceptable);
DXUTSetCallbackD3D9DeviceCreated(OnD3D9CreateDevice);
DXUTSetCallbackD3D9DeviceReset(OnD3D9ResetDevice);
DXUTSetCallbackD3D9FrameRender(OnD3D9FrameRender);
DXUTSetCallbackD3D9DeviceLost(OnD3D9LostDevice);
DXUTSetCallbackD3D9DeviceDestroyed(OnD3D9DestroyDevice);
DXUTSetCallbackDeviceChanging(ModifyDeviceSettings);
DXUTSetCallbackMsgProc(MsgProc);
DXUTSetCallbackFrameMove(OnFrameMove);

DXUT框架程序的整个“生命周期”可划分为三个阶段:启动、运行和结束。

第一阶段:启动

DXUT框架依次执行IsD3D9DeviceAcceptable()、ModifyDeviceSettings()、OnD3D9CreateDevice()、OnD3D9ResetDevice()这4个函数。

在创建某个Direct3D渲染设备之前,如果需要对渲染设备的特征进行检查,查看设备是否支持需要的功能,可将检查代码写在函数IsD3D9DeviceAcceptable()中。

在某个渲染设备创建之前,如果需要修改该渲染设备的设置,可将代码写在函数ModifyDeviceSettings()中。DXUT框架接下来就根据设置(或者是默认设置)创建最适合当前硬件的Direct3D渲染设备。例如,当硬件不支持某些功能时,可以通过使用参考设备进行模拟,设置使用参考设备代码通常写在该函数中。

DXUT框架创建了Direct3D设备之后,接下来会调用OnD3D9CreateDevice()回调函数,可在OnD3D9CreateDevice()回调函数中创建所有内存池类型为D3DPOOL_MANAGED或D3DPOOL_SYSTEMMEM的资源。以类型D3DPOOL_MANAGED创建的设备由Direct3D系统代替管理(位于显存或系统内存中),以类型D3DPOOL_SYSTEMMEM创建的设备位于系统内存中,在程序退出之前,这些资源常驻内存,不会出现设备丢失的现象。也就是说,以这两种内存类型创建的资源不需要程序员进行管理。

DXUT框架在调用OnD3D9CreateDevice()回调函数之后,将调用OnD3D9ResetDevice()回调函数。我们可在函数OnD3D9ResetDevice()中创建所有内存池类型为D3DPOOL_DEFAULT的资源,这一类资源将尽可能存放在显存中,这样可以提高程序的运行速度。但是,这类资源在程序运行时会出现设备丢失的现象,因此需要程序员自己管理。在设备丢失时释放它的内存,当设备恢复时重新为它分配内存。此外,观察变换矩阵和投影变换矩阵以及在整个程序运行期间保持不变的渲染状态通常也在该回调函数中设置。

如果性能不是很重要,使用D3DPOOL_MANAGED内存类型资源永远是一种安全的选择。

第二阶段:运行

DXUT框架调用回调函数MsgProc()处理各类消息,并在空闲时间反复调用OnFrameMove()和OnFrameRender()两个函数进行场景渲染。

在每一帧中,程序为实现对场景的刷新,为用户输入的响应而编写的代码通常写在函数OnFrameMove()中,例如设置世界变换矩阵实现物体的运动,它相当于“update”的性质,真正进行渲染的代码写在函数OnFrameRender()中。

需要说明的是,在应用程序运行期间,当Direct3D设备变为丢失状态时,DXUT框架会调用OnD3D9LostDevice()函数,释放所有在回调函数OnD3D9ResetDevice()中创建的设备资源。也就是说,这时释放的资源都是D3DPOOL_DEFAULT类型的。当Direct3D设备从丢失状态恢复时,DXUT框架会调用回调函数OnD3D9ResetDevice()重新创建所有类型为D3DPOOL_DEFAULT的资源。也就是说,在程序运行时,如果出现设备丢失现象,OnD3D9LostDevice()和OnD3D9ResetDevice()这一对函数就需要分别调用一次。

第三阶段:退出

在退出程序时,DXUT框架会依次调用OnD3D9LostDevice()和OnD3D9DestroyDevice()回调函数,在函数OnD3D9LostDevice()中释放由函数OnD3D9ResetDevice()创建的资源,在函数OnD3D9DestroyDevice()中释放由函数OnD3D9CreateDevice()创建的资源。

AppFrame.cpp的全部代码如下:

#include "DXUT.h"
#include "resource.h"
//--------------------------------------------------------------------------------------
// Rejects any D3D9 devices that aren't acceptable to the app by returning false.
//--------------------------------------------------------------------------------------
bool CALLBACK IsD3D9DeviceAcceptable(D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
bool bWindowed, void* pUserContext)
{
// Typically want to skip back buffer formats that don't support alpha blending
    IDirect3D9* pD3D = DXUTGetD3D9Object();
/*
    HRESULT CheckDeviceFormat(
      UINT Adapter,
      D3DDEVTYPE DeviceType,
      D3DFORMAT AdapterFormat,
      DWORD Usage,
      D3DRESOURCETYPE RType,
      D3DFORMAT CheckFormat
    );
    /*/
if(FAILED(pD3D->CheckDeviceFormat(pCaps->AdapterOrdinal, pCaps->DeviceType, AdapterFormat,
            D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat)))
    {
return false;
    }
return true;
}
//--------------------------------------------------------------------------------------
// Before a device is created, modify the device settings as needed.
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings(DXUTDeviceSettings* pDeviceSettings, void* pUserContext)
{
return true;
}
//--------------------------------------------------------------------------------------
// Create any D3D9 resources that will live through a device reset (D3DPOOL_MANAGED)
// and aren't tied to the back buffer size.
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9CreateDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext)
{
return S_OK;
}
//--------------------------------------------------------------------------------------
// Create any D3D9 resources that won't live through a device reset (D3DPOOL_DEFAULT)
// or that are tied to the back buffer size.
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9ResetDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext)
{
return S_OK;
}
//--------------------------------------------------------------------------------------
// Handle updates to the scene.  This is called regardless of which D3D API is used.
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove(double fTime, float fElapsedTime, void* pUserContext)
{
}
//--------------------------------------------------------------------------------------
// Render the scene using the D3D9 device
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
    HRESULT hr;
// Clear the render target and the zbuffer
    V( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 5, 5, 5), 1.0f, 0) );
// Render the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
    {
        V( pd3dDevice->EndScene() );
    }
}
//--------------------------------------------------------------------------------------
// Handle messages to the application
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool* pbNoFurtherProcessing, void* pUserContext )
{
return 0;
}
//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9ResetDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9LostDevice( void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9CreateDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
{
}
//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
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
// Set the callback functions
    DXUTSetCallbackD3D9DeviceAcceptable(IsD3D9DeviceAcceptable);
    DXUTSetCallbackD3D9DeviceCreated(OnD3D9CreateDevice);
    DXUTSetCallbackD3D9DeviceReset(OnD3D9ResetDevice);
    DXUTSetCallbackD3D9FrameRender(OnD3D9FrameRender);
    DXUTSetCallbackD3D9DeviceLost(OnD3D9LostDevice);
    DXUTSetCallbackD3D9DeviceDestroyed(OnD3D9DestroyDevice);
    DXUTSetCallbackDeviceChanging(ModifyDeviceSettings);
    DXUTSetCallbackMsgProc(MsgProc);
    DXUTSetCallbackFrameMove(OnFrameMove);
// TODO: Perform any application-level initialization here
// Initialize DXUT and create the desired Win32 window and Direct3D device for the application
    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"AppFrame Sample" );
    DXUTCreateDevice( true, 640, 480 );
// Start the render loop
    DXUTMainLoop();
// TODO: Perform any application-level cleanup here
return DXUTGetExitCode();
}

运行效果图:

下载示例工程

本文转载自:http://www.cnblogs.com/flying_bat/archive/2008/05/17/1201301.html

rise-worlds

rise-worlds

粉丝 3
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
如何使用DXUT框架

DXUT是什么? DXUT即DirectX Utility Library,它是微软为DirectX Samples写的一个框架,有了这个框架,Sample的构建就方便多了,这个框架实际上抽取了构建Sample的公共代码,比如处理窗口消...

吞吞吐吐的
2017/10/12
0
0
Direct3D学习(三):光影贴图

刚看完了DXUT,拿来练练手 这个框架却实方便啊,终于不用写那些令人恶心的API函数了 光影贴图,说白了就是在纹理上表现出来光影效果,并不是实时计算的,所以适用于固定的场影平面,如地面,...

长平狐
2012/11/12
77
0
DXUT

DXUT 是一个建立在 Direct3D 之上的一个层,简化 了 Windows 和 Direct3D 的 API。它能帮助开发者建立一个更健壮、更易于生成的示例,原型,工具或游戏,...

大胖森
2015/04/30
723
0
《Artech的WCF技术剖析系列》系列技术文章整理收藏

《Artech的WCF技术剖析系列》系列技术文章整理收藏 WCF技术剖析系列来自博客园的Artech,Artech在这个系列中帮助大家对WCF有更全面的认识。收藏在这里供大家学习参考 1WCF技术剖析之一:通过...

开元中国2015
2015/06/22
24
0
libevent源码深度剖析

作者:http://blog.csdn.net/sparkliang/article/category/660506 libevent源码深度剖析十三——libevent信号处理注意点 libevent源码深度剖析十三——libevent信号处理注意点前面讲到了lib...

晨曦之光
2012/03/09
2.7K
0

没有更多内容

加载失败,请刷新页面

加载更多

arcgis arcpy 克里金插值 掩膜 配置符号系统 自动生成图片

整体思路,最后要加载到mxd文件中,然后导出图片 首先加载mxd文件 mxd = mapping.MapDocument(r"./11.mxd") 然后读取数据 并加载到图层中 sr = arcpy.SpatialReference(4326) # 读取csv...

可达鸭Go
今天
4
0
漂亮有创意的思维导图模板分享

相信很多人使用在绘制思维导图时很喜欢使用模板进行编辑,它能够让你在短时间内快速创造出一个风格明显好看的思维导图,对绘制时间以及使用够感受影响都是较为深刻的,下面为大家分享几款漂亮...

干货趣分享
今天
4
0
使用js实现对cookie的增删改查

简单的操作cookie 存储cookie(key为test;value为testValue): document.cookie = "test=testValue"; 存储多个cookie: document.cookie = "test1=testValue1";document.cookie = "test2=te......

被毒打的程序猿_先瑞
今天
4
0
ApacheCN 公众号文章汇总 2019.9

ApacheCN 优质博文推荐计划正式启动 接受以下主题的博文: 人工智能(论文解读,比赛心得,面经,知识点讲解) 环材化生劝退 CS 留学申请,IT 外企求职 每日从所有投稿中精选两篇,在 Apache...

ApacheCN_飞龙
今天
5
0
Intellij Idea显示回退和前进按钮的方法

方法1:使用快捷键: 回到上一步 ctrl + alt + <-(左方向键) 回到下一步 ctrl + alt + ->(右方向键) 方法2:在界面显示: View -> 勾选ToolBar 方法3(推荐): (1)Preferences -> Ap...

孟飞阳
今天
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部