Direct3D 10教程8:DXUT介绍
概览
本教程将介绍DXUT。DXUT是一个建立在Direct3D之上的一个层,它能帮助我们建立一个更健壮、更易于生成的示例,原型,工具或游戏,它基于典型应用简化了Windows和Direct3D的API。
本教程的显示结果与上一个教程相同,但是实现起来简单得多。
源代码
(SDK root)\Samples\C++\Direct3D10\Tutorials\Tutorial08
DXUT
DXUT提供了一个简化的过程用来创建窗口,创建(或选择)一个Direct3D设备,处理Windows消息,这可以让你节省实现这些标准任务所用的时间。
用于Direct3D的DXUT还是高度组件化的,DXUT的核心组件包括标准窗体的创建,设备创建和管理功能。可选组件包括相机控制,GUI系统和网格处理。本教程介绍DXUT核心组件,可选组件在后面的教程中介绍。本教程中介绍的功能包括设备创建,主循环和简单的键盘输入。
DXUT开放了很多用户可以挂钩的回调函数,在程序执行过程中回调函数可以被DXUT在逻辑点上进行调用。你可以将自定义代码插入到这些回调函数中。
DXUT支持程序包含Direct3D 9和/或Direct3D 10代码路径,这样就可以让DXUT选择最适合程序当前运行的系统的代码路径。但是,本教程只关注Direct3D 10绘制,让DXUT同时生成Direct3D 9和Direct3D 10程序的例子,可参见DirectX SDK中的BasicHLSL10示例。
设置Callback函数
修改程序的WinMain方法是第一步。在前面的教程中,WinMain调用initialization方法,然后进入消息循环。在DXUT框架中,WinMain的工作类似。
首先,由程序设置回调函数。这些函数是在当特定事件发生时由DXUT调用的,这些事件包括设备创建,交换链创建,键盘输入,帧更新(frame move)和帧绘制。
// Direct3D10回调函数 DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable ); DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice ); DXUTSetCallbackD3D10SwapChainResized( OnD3D10ResizedSwapChain ); DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10ReleasingSwapChain ); DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice ); DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender ); DXUTSetCallbackMsgProc( MsgProc ); DXUTSetCallbackKeyboard( KeyboardProc ); DXUTSetCallbackFrameMove( OnFrameMove ); DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
然后程序设置其他DXUT设置,例如下面的例子:
// 显示鼠标并在全屏模式时不显示 DXUTSetCursorSettings( true, true );
最后调用初始化函数。本教程和前面的基础教程中的区别在于你必须在初始化时处理本程序的专有代码,这是因为创建设备和窗口的操作是由DXUT处理的。程序专有代码会插入到对应的回调函数中,DXUT在初始化过程中会调用这些函数。
// 初始化DXUT并创建Win32窗口和Direct3D设备。 // 调用的每个函数都有相关选项,让你可以通过设置这些选项控制框架的行为方式。 DXUTInit( true, true ); // Parse the command line, handle the default hotkeys, and show msgboxes DXUTCreateWindow( L"Tutorial8" ); DXUTCreateDevice( true, 640, 480 );
使用DXUTTrace调试
DXUTTrace是一个可以被调用的宏,它可以创建调试输出,它的功能与标准的调试输出类似,但它可以包含许多参数。例如:
DXUTTRACE( L"Hit points left: %d\n", nHitPoints );
在这个教程中,上述代码放置在函数入口的下一行,用来报告程序的状态。例如,在OnD3D10ResizedSwapChain()开始时,调试器会报告“SwapChain Reset called”。
DXUTTRACE( L"SwapChain Reset called\n" );
设备管理和初始化
DXUT提供了多种方法用于创建和配置窗口和Direct3D设备。本教程用到的方法如下面的列表所示,要创建一个普通的Direct3D程序,这些方法已经足够了。
前面教程中的InitDevice()和CleanupDevice()方法中的代码会被分散到以下回调函数中。
- IsD3D10DeviceAcceptable Callback
- ModifyDeviceSettings Callback
- OnD3D10CreateDevice Callback
- OnD3D10DestroyDevice Callback
因为不是所有的资源都是同时创建的,我们可以通过减少重复调用的次数最小化总的开支。这里我们使用的方法是只重新创建哪些上下文依赖的资源。而上一个教程出于简化的考虑,当屏幕的大小发生改变时我们会重新创建所有资源。
IsD3D10DeviceAcceptable Callback
当找到设备设置的每个组合时就会调用这个函数。它可以让程序接受或拒绝每种组合。例如,程序可以拒绝所有REF设备,或者拒绝全屏模式。
因为本教程不需要高级功能,所以可以接受所有设备。
ModifyDeviceSettings Callback
这个回调函数让程序可以在DXUT创建设备前立即改变设备的设置。在本教程中,此过程中不进行任何操作,因为我们无需实现高级功能。
OnD3D10CreateDevice Callback
当创建Direct3D10设备后会调用这个函数。在设备创建后,程序可以使用这个函数分配资源,设置缓存,处理其他必须的任务。
在本教程中,将教程7的InitDevice()方法中的大部分代码复制到这个回调函数中。但是删去了创建设备和交换链的代码,因为这些功能是由DXUT处理的。在OnD3D10CreateDevice中创建了effect,顶点/索引缓存,纹理,变换矩阵。
OnD3D10DestroyDevice Callback
在DXUT释放ID3D10Device之前会调用这个函数,用来释放由这个设备使用的资源。
本教程中,OnD3D10DestroyDevice释放了我们在OnD3D10CreateDevice函数中创建的资源,这些资源包括顶点/索引缓存,顶点格式,纹理和effect。代码复制于CleanupDevice()方法,但用的是SAFE_RELEASE宏。
绘制
对于绘制来说,DXUT提供了两个回调函数。第一个是OnFrameMove,它在每一帧绘制之前调用,并使时间向前推移。第二个是OnD3D10FrameRender,它提供绘制功能。
这两个函数将Render()方法分成两个逻辑步骤。OnFrameMove更新用于动画的所有矩阵,OnD3D10FrameRender包含绘制调用。
OnFrameMove Callback
在绘制帧之前会调用这个函数,用来处理各种状态。但是,更新频率取决于系统的速度。在较快的系统中,每秒调用的次数会更多,这意味着必须根据时间调整状态更新代码,否则,在较慢的系统上的运行情况就会和快的系统上的不同。
在本教程中每次调用这个函数,会更新一次世界矩阵,还会改变网格的颜色。代码直接是从教程7的Render()方法中复制过来的,注意这里没有包含绘制调用。
OnD3D10FrameRender Callback
当重新绘制帧时会调用这个函数。在这个函数中会施加effects,链接资源,绘制场景。
本教程中,在这个函数中,我们清除了后备缓存和模版缓存,设置矩阵并绘制了立方体。
消息处理
消息处理是一个真正的所有window程序都具有的属性,DXUT开放这些消息用于高级程序。
MsgProc Callback
DXUT会在接收到窗体消息时调用这个函数,这个函数可以让程序处理消息。
本教程中,无需处理另外的消息。
KeyboardProc Callback
这个函数在键盘按下时由DXUT调用,可以用做一个处理键盘命令的简单方法。
因为不使用键盘交互,所以本教程不使用KeyboardProc。但是代码中有一个使用F1键的case语句,你可以在这里添加一些代码试着旋转立方体。
小结
本教程介绍的函数让你可以开始一个建立在DXUT上的项目,而教程9和10会介绍DXUT的高级功能。要开始一个使用DXUT新项目,你可以使用Sample Browser复制并重命名任何在DirectX SD中的示例项目,EmptyProject示例通常是开始一个空项目的最好选择。
文件下载(已下载 1257 次)发布时间:2012/6/9 上午8:26:13 阅读次数:9652