DXUT编程指南.doc_第1页
DXUT编程指南.doc_第2页
DXUT编程指南.doc_第3页
DXUT编程指南.doc_第4页
DXUT编程指南.doc_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

DXUT设计指南 DXUT是一个建立在Direct3D API之上的,被大部分Direct3D指南和例子所使用的层。 它的目标是创建Direct3D例子、原型、工具,更容易的建立坚固、专业的游戏。 DXUT概观 初始化DXUT 使用基于DXUT的程序窗口 使用DXUT设备 使用DXUT主循环 处理DXUT的错误 DXUT高级设备选择 DXUT高级功能See also: DXUT参考.DXUT概观本主题提供对DXUT概观的高级介绍。 概观 特点 局限性 启动一个新工程 DirectX April 2005 SDK中DXUT的改进 自DirectX Summer 2003 SDK以来DXUT的变化概观DXUT框架的设计是为了帮助开发者在创建窗口、设备,处理窗口消息和设备事件时,更有效率(消耗较少的时间)。这是使用该框架的应用程序的主函数:INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT ) / 设置回调函数,这些函数允许DXUT通知应用程序更换设备,用户输入和窗口消息。 / 回调函数是可选的,因此你要做的仅是设置你感兴趣的事件的回调函数。 DXUTSetCallbackDeviceCreated( OnCreateDevice ); DXUTSetCallbackDeviceReset( OnResetDevice ); DXUTSetCallbackDeviceLost( OnLostDevice ); DXUTSetCallbackDeviceDestroyed( OnDestroyDevice ); DXUTSetCallbackFrameRender( OnFrameRender ); DXUTSetCallbackFrameMove( OnFrameMove ); / 初始化DXUT并创建想要的Win32窗口和应用程序的Direct3D设备。调用这些/ 可选函数中的每一个,此外它们允许你设置几个选项来控制框架的行为。 DXUTInit( TRUE, TRUE, TRUE ); DXUTCreateWindow( LBasicHLSL ); DXUTCreateDevice( D3DADAPTER_DEFAULT, TRUE, 640, 480 ); / 通过DXUT来处理消息循环并分派渲染调用。当在空闲时间和处理窗口消息的/ 时间间隔时,框架将调用OnFrameMove和OnFrameRender回调函数。 DXUTMainLoop(); return DXUTGetExitCode();在例子代码中,框架做了大部分的工作。它创建窗口、设备,处理主消息循环,当应用程序事件触发时,提供相应的回调函数,例如:在设备重置或渲染每帧时。DXUT框架是组件化的,应用程序可以使用框架的全部功能或部分功能。这个设计指南的其他部分详细的包括了这些步骤,并着重于应用程序可选择的控制或可替代的步骤。更详细的语法和函数的使用,回调函数,结构,列举和常量等信息可以在DXUT参考中找到。特点为了帮助你创建一个应用程序,框架提供下列服务: 简单的窗口和设备的创建。 设备事件 (created, reset, lost, destroyed) 和窗口事件 (messages, keyboard, mouse)的通知。 窗口模式与全屏模式之间的转换, 硬件设备和软件设备之间的转换。 精确的计时器。 命令行支持和自动化测试。 使用对话框或API的设备选择。 一套纹理化的GUI控件,包括一个可使用输入法编辑器的编辑框。 各种扩展类,例如简单的摄像机类型。局限性为了便于使用,框架只支持绑定一个设备的窗口。需要同时使用多个设备,或显示多个Direct3D窗口的高级程序,是本框架不支持的,大部分类型的应用程序将能够使用本框架来实现。启动一个新工程最简单的方法,启动一个使用新的Visual Studio .NET中的DXUT开发的项目:1. 启动例子浏览器(SampleBrowser.exe),在下面位置找到DirectX SDK:(SDK root)SamplesSampleBrowser2. 在例子浏览器里,选择一个已有的Direct3D 例子项目,将从这开始。 3. 点击 “安装项目”(Install Project)链接,然后拷贝Visual Studio .NET项目文件到一个新的本地目录。 4. 你可以给项目重命名,这时浏览器将根据提供的新工程名,去更改相应的文件和源代码。DirectX April 2005 SDK中DXUT的改进基于用户的反溃, DXUT框架在DirectX April 2005 SDK中进行了改进更新。下面是主要的差异和改进的列表。 Callback functions now pass a void* pUserContext from the DXUTSetCallback* function to the callback. This allows the callback functions to receive context from the application such as a class pointer. The frameworks GUI is now separate and optional from the core framework. The creation and interfacing of CDXUTDialogResourceManager is now the responsibility of the application if it wishes to use the frameworks GUI. The framework now allows applications to reject device changes via the LPDXUTCALLBACKMODIFYDEVICESETTINGS function which returns a bool. Returning false from this callback will notify the framework to keep using the current device instead of changing to the new device. For example, by default on a multiple monitor configuration dragging the window between monitors will cause the framework to change devices. However if the application can not use the other device, it must be able to reject this change and continue to use the current device. This callback can now be set separate of the CreateDevice function by using DXUTSetCallbackDeviceChanging. Passing 0 as the width and height to the DXUTCreateDevice function now creates a backbuffer of the same size as the client window. The DXUTGetExitCode function now returns 11 if the last device was a D3DDEVTYPE_REF device type.自DirectX Summer 2003 SDK以来DXUT的变化The new framework is significantly redesigned from DXUT that shipped in the DirectX Summer 2003 SDK Update. The following is a list of major differences and improvements. Flat API design. The new framework is a set of global functions that more clearly define how the application interacts with the framework. Clearer naming. The device, frame, and message events have been renamed to be more easily understood. Modular. An application can use only parts of the framework if desired. An application can use the framework to create its own window or its own device, or it can use its own main loop. Better device selection. The application can fully customize the presentation parameters or behavior flags before creating the device. The new framework also has a more advanced algorithm for finding valid device settings. Toggling between hal and reference devices (see Device Types). Built-in toggling support is available, and toggling can be bound to a keystroke for simplified debugging. Better error handling. Error handling and macros can be used by the application to display error message boxes immediately if an API is called incorrectly. Better multiple-monitor support. If this feature is enabled, the new framework will automatically change devices if the window is moved to a different monitor. GUI controls. A set of textured GUI controls features an IME-enabled edit box for use in samples, prototypes, and professional games. No dialog dependency onGDI. Unlike the previous framework, the new framework does not require anyGDI dialog resources in the application. Late binding with DirectX. Late binding verifies that the required DirectX version is installed on the system. Unicode support. The new framework supports Unicode. Windows NT-based operating systems natively support Unicode, which means that ANSI calls need to be converted to Unicode. With this and better international support, Unicode is the better choice because it will result in better performance on these operating systems. For Windows 98 and Windows Millennium Edition (Windows Me) systems, consider using the Microsoft Layer for Unicode (MSLU). Documentation. The framework library functions in the Dxut.h header are documented; see DXUT Reference.初始化DXUT使用DXUT的第一步是初始化。可以简单的用DXUTInit 函数:HRESULT DXUTInit (BOOL bParseCommandLine = TRUE,BOOL bHandleDefaultHotkeys = TRUE,BOOL bShowMsgBoxOnError = TRUE);你将在应用程序的 WinMain 函数开始后不远的地方调用DXUTInit。如果DXUTInit没有在应用程序中调用,它将使用默认的参数在框架中自动调用。如果第一个参数bParseCommandLine为TRUE,框架将对命令行参数做出响应。例如,运行BasicHLSL Sample执行下列命令行参数:BasicHLSL.exe -windowed -width:600 -height:600DXUT框架将尝试执行这些窗口设定,对于命令行支持参数的全部列表,请查看DXUTInit函数部分的帮助。第二个参数bHandleDefaultHotkeys通知DXUT框架对一些预先执行的击键做出响应,例如:ALT+ENTER。再说一次,全部的列表请查看DXUTInit函数部分的帮助。如果这个参数为FALSE,程序将不做响应。最后一个参数bShowMsgBoxOnError,当框架发现一个错误时,显示一个消息框。设置它为FALSE则运行自动测试或完全由用户经验控制的专业程序。使用基于DXUT的程序窗口你的程序可以只使用一个新的DXUT函数,来处理大部分窗口管理的任务。 创建窗口 使用你自己的窗口创建窗口创建一个Direct3D应用程序窗口包括下列步骤:1. 定义一个响应窗口的消息。2. 创建。3. 使用。4. 使用。这些步骤如果没做正确将会引起bugs。虽然它对于一个Direct3D程序员来说,这可能很没劲,但却是每个程序所必需的。DXUT框架使用DXUTCreateWindow函数来简单化这个过程:HRESULT DXUTCreateWindow( const WCHAR *strWindowTitle = LDirect3D Window, HINSTANCE hInstance = NULL, HICON hIcon = NULL, HMENU hMenu = NULL, INT x = CW_USEDEFAULT, INT y = CW_USEDEFAULT);所有参数都是可选的: strWindowTitle是窗口标题,也显示在任务栏,它表示工程名称。 hInstance是应用程序实例的句柄。大部分程序的默认值为NULL。 hIcon是应用程序的图标。如果为NULL,则应用程序的可执行文件里包含的第一个图标将被使用,所以NULL值也能很好的工作。 hMenu 处理菜单,如果想的话可以设置它,大部分游戏无论无何不能使用标准菜单,但作为替代,可以用自己定制的游戏类界面来创建它们。 最后2个参数描述窗口位置。如果应用程序运行在全屏模式,则忽视这2个参数。最简单的调用方法,程序可以像下面这样调用DXUTCreateWindow:DXUTCreateWindow( LMy New Game );只用一个参数来调用这个函数,strWindowTitle将促使DXUT框架去创建窗口,并自动处理重要的窗口消息。如果需要重新取得窗口的句柄,可以调用DXUTGetHWND。如果想让程序响应窗口消息,可以用DXUTSetCallbackMsgProc 去设置回调函数:void DXUTSetCallbackMsgProc( LPDXUTCALLBACKMSGPROC pCallbackMsgProc, void* pUserContext = NULL );PCallbackMsgProc参数是一个LPDXUTCALLBACKMSGPROC类型的回调函数,下面是定义:LRESULT CALLBACK FUNCTION MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL* pbNoFurtherProcessing, void* pUserContext ) return 0;在这个回调函数里,程序不需要去响应任何消息,因为所有重要的消息将被DXUT框架处理。为了阻止DXUT框架处理消息,应用程序可以设置*pbNoFurtherProcessing为TRUE。(查看LPDXUTCALLBACKMSGPROC),然而,当使用这个设置时要小心,因为它可能会阻止DXUT框架的正确行为。使用自己的窗口如果你想让程序去创建自己的窗口,并且和框架一起使用,而不是让DXUT处理窗口的操作,那么你可以使用DXUTSetWindow函数:HRESULT DXUTSetWindow( HWND hWndFocus, HWND hWndDeviceFullScreen, HWND hWndDeviceWindowed, BOOL bHandleMessages = TRUE);这个函数带有3个窗口句柄,它们是完全相同的,除非程序在窗口模式和全屏模式中使用不同的窗口。当应用程序因按ALT+TAB、鼠标点击、或其他用户输入,而转到后台时,将提供焦点窗口的句柄通知给Direct3D。应用程序应该经常传递焦点窗口的句柄给DXUTSetWindow函数,不管它创建多少个Direct3D设备。除了用一个窗口初始化框架之外,应用程序需要用窗口消息通知框架,窗口接收有序的消息给正确的框架行为处理。如果框架创建了窗口,窗口消息是自动处理的。否则,应用程序可以使用DXUTStaticWndProc函数,从内部的窗口WindowProc回调函数传递窗口消息给框架,下面是定义:LRESULT CALLBACK DXUTStaticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);如果你不想让应用程序使用DXUTStaticWndProc,你可以交替复制在函数中的功能,尽管它是不被推荐的。使用DXUT设备使用最新版的DXUT创建DirectX设备。它可以代替你用应用程序直接创建设备,而框架的其他功能仍然可用。 创建设备 选择最佳设备设定 更改可用的设备设定 软件顶点处理 Fallback to Software Vertex Processing 使用你自己的设备创建设备下面是用标准的Direct3D方法创建设备,CreateDevice:HRESULT CreateDevice( UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags, D3DPRESENT_PARAMETERS *pPresentationParameters, IDirect3DDevice9 *ppReturnedDeviceInterface);这个方法需要正确的adapter(适配器),设备类型(hal or reference),窗口句柄,行为标记(软件/硬件顶点处理和其他设备标记),和一个表达参数(一个D3DPRESENT_PARAMETERS结构的参数)。此外,D3DPRESENT_PARAMETERS结构有众多成员,它们是:特定的后备缓存区设置,采样器设备,swap效果,窗口模式,深度模版缓存区设置,刷新速度等等。给所有这些参数选择有效的设定就是个挑战,那么DXUT框架的DXUTCreateDevice函数简化了这一过程:HRESULT DXUTCreateDevice( UINT AdapterOrdinal = D3DADAPTER_DEFAULT, BOOL bWindowed = TRUE, INT nSuggestedWidth = 640, INT nSuggestedHeight = 480, LPDXUTCALLBACKISDEVICEACCEPTABLE pCallbackIsDeviceAcceptable = NULL, LPDXUTCALLBACKMODIFYDEVICESETTINGS pCallbackModifyDeviceSettings = NULL);大多数基本用法是很简单的,使用默认的参数调用函数:DXUTCreateDevice();对于这个简单的调用,框架创建设备的默认设定,它可以工作在大部分情况下。下面是设备创建的默认设定:Direct3D创建标记描述DXUTCreateDevice的默认值AdapterFormat parameter of CheckDeviceFormat适配器表面格式Desktop display mode, or D3DFMT_X8R8G8B8 if the desktop display mode is less than 32 bits.Adapter parameter of IDirect3D9:CreateDevice显示适配器的序号D3DADAPTER_DEFAULTD3DPRESENT_PARAMETERS. BackBufferCount后备缓冲区数量2, indicating triple buffering.D3DPRESENT_PARAMETERS. BackBufferFormat缓冲区格式Desktop display mode, or D3DFMT_X8R8G8B8 if the desktop display mode is less than 32 bits.D3DPRESENT_PARAMETERS. AutoDepthStencilFormat设备将创建表面的深度缓冲区格式D3DFMT_D16 if the backbuffer format is 16 bits or less, or D3DFMT_D32 otherwise.The DeviceType parameter of IDirect3D9:CreateDevice设备的列举类型D3DDEVTYPE_HAL if available, otherwise D3DDEVTYPE_REF or failure code if neither is available.D3DPRESENT_PARAMETERS. MultiSampleQuality品质级别MultiSampleQuality = 0, indicating multisampling is disabled.D3DPRESENT_PARAMETERS. FlagsPresentation parameters flags.D3DPRESENTFLAG_DISCARD_DEPTHSTENCILD3DPRESENT_PARAMETERS. PresentationIntervalPresentation interval.D3DPRESENT_INTERVAL_IMMEDIATE for windowed mode, or D3DPRESENT_INTERVAL_DEFAULT for full-screen mode.D3DPRESENT_PARAMETERS. FullScreen_RefreshRateInHz显示器的刷新速度0, indicating windowed mode.D3DPRESENT_PARAMETERS. BackBufferWidth and .BackBufferHeight显示模式640 x 480 pixels for windowed mode, or the desktop resolution for full-screen mode.D3DPRESENT_PARAMETERS. AutoDepthStencilFormat设备将创建表面的模版缓冲区格式D3DFMT_D16 if the backbuffer format is 16 bits or less, or D3DFMT_D32 otherwise.D3DPRESENT_PARAMETERS. SwapEffect交换效果.D3DSWAPEFFECT_DISCARDBehaviorFlags parameter of IDirect3D9:CreateDevice顶点处理标记D3DCREATE_HARDWARE_VERTEXPROCESSING if supported, otherwise D3DCREATE_SOFTWARE_VERTEXPROCESSING.D3DPRESENT_PARAMETERS. Windowed窗口或全屏模式true, indicating windowed mode.hFocusWindow parameter of CreateDevice处理创建的窗口 (查看使用基于DXUT的程序窗口).hWndFocus parameter of DXUTSetWindowD3DPRESENT_PARAMETERS. hDeviceWindow设备窗口的处理hWndDeviceFullScreen or hWndDeviceWindowed parameters of DXUTSetWindowD3DPRESENT_PARAMETERS. EnableAutoDepthStencil深度/模版缓冲区的创建标记true.比使用一个设备创建很多默认设定更好的方法是,应用程序能够通过传递给CreateDevice函数的参数来使设备应用更多的控制。例如,你可能通过SuggestedWidth和nSuggestedHeight参数改变窗口的尺寸:DXUTCreateDevice( D3DADAPTER_DEFAULT, false, 1024, 768, NULL, NULL, NULL);为了取得更多的控制,应用程序可以使用2个可选的回调函数: LPDXUTCALLBACKISDEVICEACCEPTABLE和LPDXUTCALLBACKMODIFYDEVICESETTINGS.选择最佳设备设定你可以在程序里使用IsDeviceAcceptable回调函数来帮助框架选择佳的设备设定,请看下列代码:bool CALLBACK IsDeviceAcceptable(D3DCAPS9* pCaps,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,bool bWindowed,void* pUserContext ) / TODO: 可接受的设定返回true,否则返回false return true;这个回调函数的原型是LPDXUTCALLBACKISDEVICEACCEPTABLE。框架为下列5个设定中每个唯一有效的组合,一次性的调用这个函数:D3DDEVTYPE DeviceType;UINT AdapterOrdinal;D3DFORMAT AdapterFormat;D3DFORMAT BackBufferFormat;bool Windowed;注意:适配器序号和设备类型不直接传递给回调函数,而是分别的传递,D3DCAPS9结构中的设备类型(DeviceType)和设备序号(AdapterOrdinal)成员。在这个回调函数里,应用程序可以拒绝它不支持的或接受任何组合。举个例子,程序可以使用下列代码拒绝16-bit格式的后备缓冲区,并且让所有设备不支持像素着色器ps_2_0以下的版本:bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed ) if( pCaps-PixelShaderVersion CheckDeviceFormat( pDeviceSettings-AdapterOrdinal, pDeviceSettings-DeviceType, pDeviceSettings-AdapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) ) if( SUCCEEDED( pD3D-CheckDepthStencilMatch( pDeviceSettings-AdapterOrdinal, pDeviceSettings-DeviceType, pDeviceSettings-AdapterFormat, pDeviceSettings-pp.BackBufferFormat, D3DFMT_D24S8 ) ) ) pDeviceSettings-pp.AutoDepthStencilFormat = D3DFMT_D24S8; return true;作为替代, 回调函数也可以使用框架的CD3DEnumeration 对象去检查是否支持D3DFMT_D24S8格式:bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps ) CD3DEnumeration *pEnum = DXUTGetEnumeration(); CD3DEnumDeviceSettingsCombo *pCombo; pCombo = pEnum-GetDeviceSettingsCombo( pDeviceSettings ); if( pCombo-depthStencilFormatList.Contains( D3DFMT_D24S8 ) ) pDeviceSettings-pp.AutoDepthStencilFormat = D3DFMT_D24S8; return true;应用程序更改设备设定后,框架用新的设定创建设备。这个回调函数返回bool值。如果应用程序返回TRUE,框架将创建标准设备。如果返回FALSE,如果有设备存在的话,框架不更改设备,保持当前的设备。这样就允许应用程序拒绝框架的请求(更改应用程序所不支持的设备)。例如,在一个多显示器的结构里,默认在显示器间拖曳窗口将导致框架更改设备,然而如果应用程序不能使用另一个设备,它必须能够拒绝更改,并继续使用当前的设备。软件顶点处理如果我在硬件上创建一个Direct3D设备,它支持硬件像素处理,但不支持硬件顶点处理,那么你需要设置行为标记。在IsDeviceAcceptable回调函数里,为了确保正确的回调给软件顶点处理,当IsDeviceAcceptable回调函数里不能拒绝基于顶点着色器版本的设备时,你要采取防备措施;并确保行为标记在ModifyDeviceSettings回调函数里被正确的调用。这里有一个例子:bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps ) / 如果设备不支持硬件的T&L 或硬件的顶点着色器版本1.1,那么转换到SWVP(软件顶点处理). if( (pCaps-DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) = 0 | pCaps-VertexShaderVersion BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; else / 支持 pDeviceSettings-BehaviorFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; return true; 使用你自己的设备你可以不必依赖框架创建Direct3D设备,替代的方法是,用程序自己创建设备,并且传递它给框架使用。类似的方法是应用程序可以覆盖框架的window creation设定。用所有想要的设定简单的创建一个设备,然后调用DXUTSetDevice函数使框架能够在设备上进行渲染。注意如果应用程序创建了独立于框架的设备,在主循环执行完毕之后清除资源时,程序必须释放设备接口。使用DXUT主循环在窗口和设备创建后,程序需要使用主循环(调用一个渲染循环或消息循环)来响应窗口消息。更新并渲染场景,处理设备事件。程序可以自己实现主循环,也使用DXUT实现。回调函数的注册允许DXUT去处理设备、框架和事件消息。进入主消息循环要使用框架的主循环,简单的调用DXUTMainLoop,唯一的参数设置为NULL。尽管用框架去处理消息循环相当容易,对于一些高级程序,定制主循环是更好的设计。使用DXUTMainLoop函数定制的主循环是可能的,但需要在程序中写更多的代码,下面是例子代码:INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, INT ) DXUTSetCallbackDeviceCreated( OnCreateDevice ); DXUTSetCallbackDeviceReset( OnResetDevice ); DXUTSetCallbackDeviceLost( OnLostDevice ); DXUTSetCallbackDeviceDestroyed( OnDestroyDevice ); DXUTSetCallbackFrameRender( OnFrameRender ); DXUTSetCallbackFrameMove( OnFrameMove ); DXUTInit( TRUE, TRUE, TRUE ); DXUTCreateWindow( LBasicHLSL ); DXUTCreateDevice( D3DADAPTER_DEFAULT, TRUE, 640, 480 ); / - / 定制主循环 HWND hWnd = DXUTGetHWND(); BOOL bGotMsg; MSG msg; msg.message = WM_NULL; PeekMessage( &msg, NULL, 0U, 0U

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论