zhigu 发表于 2007-6-1 22:41:00

DXUT进阶(翻译)

DXUT进阶<br/>&nbsp;<br/>概要<br/>这个指南涵盖了更多DXUT的高级应用.&nbsp;这个指南里的大部分功能是可选的,&nbsp;为了以最小的代价来增强你的应用程序.&nbsp;DXUT提供了一个简单的基于GUI系统的精灵和一个设备设置对话框.&nbsp;另外,&nbsp;它还提供了一些摄像机类.<br/>这个指南的结果是一个具有完善功能的GUI&nbsp;用于更改设备和场景的设置.&nbsp;它将有按钮,&nbsp;滑块,&nbsp;和文本来示范这些功能.<br/>导航<br/>&amp;#8226; DXUT摄像机&nbsp;<br/>&amp;#8226; DXUT对话框&nbsp;<br/>&amp;#8226; 资源管理程序初始化&nbsp;<br/>&amp;#8226; 3D设置对话框&nbsp;<br/>&amp;#8226; 文本渲染<br/>DXUT&nbsp;摄像机<br/>DXUT中的CModelViewerCamera&nbsp;类可以简单的的管理视图变换和透视变换,&nbsp;就像GUI&nbsp;的功能一样.<br/>&nbsp;&nbsp;&nbsp;&nbsp;CModelViewerCamera&nbsp;g_Camera;&nbsp;&nbsp;//&nbsp;A&nbsp;model&nbsp;viewing&nbsp;camera<br/>摄像机类提供的第一个功能是创建视图和透视矩阵.&nbsp;有了这个摄像机,没有必要担心这些矩阵.&nbsp;反而,&nbsp;你可以指定你在哪,&nbsp;你看着什么,还有窗口的大小.&nbsp;然后,&nbsp;把这些参数传递给摄像机对象,&nbsp;它会在后台创建这些矩阵.<br/>这里我们设置摄像机的一部分视图参数.&nbsp;我们指定我们在哪,和我们看着什么.<br/>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Initialize&nbsp;the&nbsp;camera<br/>&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3&nbsp;Eye(&nbsp;0.0f,&nbsp;0.0f,&nbsp;-800.0f&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;D3DXVECTOR3&nbsp;At(&nbsp;0.0f,&nbsp;0.0f,&nbsp;0.0f&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_Camera.SetViewParams(&nbsp;&amp;Eye,&nbsp;&amp;At&nbsp;);<br/>接下来,我们指定摄像机的投影参数.&nbsp;也就是说,&nbsp;我们需要提供观察角度,纵横比,&nbsp;和视图截锥的近、远裁剪面.&nbsp;这些信息跟之前的指南提供的一样,&nbsp;不同的是,&nbsp;你不必担心怎么去创建矩阵.<br/>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Setup&nbsp;the&nbsp;camera's&nbsp;projection&nbsp;parameters<br/>&nbsp;&nbsp;&nbsp;&nbsp;float&nbsp;fAspectRatio&nbsp;=&nbsp;pBackBufferSurfaceDesc-&gt;Width&nbsp;/&nbsp;(FLOAT)pBackBufferSurfaceDesc-&gt;Height;<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_Camera.SetProjParams(&nbsp;D3DX_PI/4,&nbsp;fAspectRatio,&nbsp;0.1f,&nbsp;5000.)0f&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_Camera.SetWindow(&nbsp;pBackBufferSurfaceDesc-&gt;Width,&nbsp;p00BackBufferSurfaceDesc-&gt;Height&nbsp;);<br/>另外,&nbsp;这个摄像机还封装了简单的鼠标反馈.&nbsp;在这里,&nbsp;我们指定三个鼠标按键给提供的鼠标操作:&nbsp;模型旋转,&nbsp;放缩,&nbsp;还有摄像机旋转.试着编译工程并用每个按键体会一下各个操作.<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_Camera.SetButtonMasks(&nbsp;MOUSE_LEFT_BUTTON,&nbsp;MOUSE_WHEEL,&nbsp;MOUSE_MIDDLE_BUTTON&nbsp;);<br/>在这个按钮组的基础上,&nbsp;摄像机会监听这些输入并产生相应效果.&nbsp;为了响应用户输入,&nbsp;需要加入一个监听到MsgProc回调函数(DXUT消息处理函数).<br/>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Pass&nbsp;all&nbsp;remaining&nbsp;windows&nbsp;messages&nbsp;to&nbsp;camera&nbsp;so&nbsp;it&nbsp;can&nbsp;respond&nbsp;to&nbsp;user&nbsp;input<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_Camera.HandleMessages(&nbsp;hWnd,&nbsp;uMsg,&nbsp;wParam,&nbsp;lParam&nbsp;);<br/>最后,在把所有数据都输入摄像机后,&nbsp;就是取出真正的变换矩阵的时候了.&nbsp;这里我们用相关函数获取投影矩阵和视图矩阵.&nbsp;摄像机对象会自己计算这些矩阵.<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_pProjectionVariable-&gt;SetMatrix(&nbsp;(float*)g_Camera.GetProjMatrix()&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_pViewVariable-&gt;SetMatrix(&nbsp;(float*)g_Camera.GetViewMatrix()&nbsp;);<br/>DXUT&nbsp;对话框<br/>用户交互可以用CDXUTDialog来实现,&nbsp;它在一个包含控件的对话框里接受用户输入,并且通过程序句柄传递它们.&nbsp;首先,&nbsp;对话框类要实例化,&nbsp;然后每个单独的控件才能加入.<br/>声明<br/>在这个指南里,&nbsp;有两个对话框会被加入,&nbsp;一个叫&nbsp;g_HUD跟D3D10示例共享相同的代码,&nbsp;另一个叫&nbsp;g_SampleUI&nbsp;用于显示函数细节给这个指南.&nbsp;第二个对话框用来控制模型的"胖瘦",就是设置一个变量传递给shaders.<br/>&nbsp;&nbsp;&nbsp;&nbsp;CDXUTDialog&nbsp;g_HUD;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;manages&nbsp;the&nbsp;3D&nbsp;UI<br/>&nbsp;&nbsp;&nbsp;&nbsp;CDXUTDialog&nbsp;g_SampleUI;&nbsp;//&nbsp;dialog&nbsp;for&nbsp;sample&nbsp;specific&nbsp;controls<br/>这些对话框被CDXUTDialogResourceManager控制着.这个管理程序会在对话框之间传递消息并处理共享资源.<br/>&nbsp;&nbsp;&nbsp;&nbsp;CDXUTDialogResourceManager&nbsp;g_DialogResourceManager;&nbsp;//&nbsp;manager&nbsp;for&nbsp;shared&nbsp;resources&nbsp;of&nbsp;dialogs<br/>最后,&nbsp;一些回调函数与GUI处理的实际消息相关联.&nbsp;这个函数用于处理控件间的交互.<br/>&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;CALLBACK&nbsp;OnGUIEvent(&nbsp;UINT&nbsp;nEvent,&nbsp;int&nbsp;nControlID,&nbsp;CDXUTControl*&nbsp;pControl,&nbsp;void*&nbsp;pUserContext&nbsp;);<br/>对话框初始化<br/>既然已经介绍了许多有用的东西,&nbsp;那么需要被初始化,&nbsp;这个指南将这些模块的真正初始化转移到一个单独的函数,&nbsp;叫&nbsp;InitApp().<br/>每个对话框的控件被初始化就是在这个函数里.&nbsp;每个对话框都需要调用它的初始化函数,&nbsp;并传递给资源管理者来指定把控件供给谁.&nbsp;同样,&nbsp;它们设置回调函数来处理GUI&nbsp;响应.&nbsp;既然这样,&nbsp;这个相关的回调函数是&nbsp;OnGUIEvent.<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_HUD.Init(&nbsp;&amp;g_DialogResourceManager&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_SampleUI.Init(&nbsp;&amp;g_DialogResourceManager&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_HUD.SetCallback(&nbsp;OnGUIEvent&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_SampleUI.SetCallback(&nbsp;OnGUIEvent&nbsp;);<br/>在它们被初始化后,&nbsp;每个都对话框可以加入它们想要使用的控件.&nbsp;对话框&nbsp;HUD加入了3个按钮用于基本功能:&nbsp;切换全屏,&nbsp;切换引用&nbsp;(软件)&nbsp;渲染器,&nbsp;和改变设备.<br/>要加入一个按钮,&nbsp;你要指定你想要使用的IDC&nbsp;标识符,&nbsp;一个用于显示的字符串,&nbsp;坐标,&nbsp;宽和高,&nbsp;还有可选的与它关联的热键.&nbsp;热键可以用键盘快速地开关这些按钮.<br/>注意指定的坐标与对话框的定位相关.<br/>&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;iY&nbsp;=&nbsp;10;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_HUD.AddButton(&nbsp;IDC_TOGGLEFULLSCREEN,&nbsp;L"Toggle&nbsp;full&nbsp;screen",&nbsp;35,&nbsp;iY,&nbsp;125,&nbsp;22&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_HUD.AddButton(&nbsp;IDC_TOGGLEREF,&nbsp;L"Toggle&nbsp;REF&nbsp;(F3)",&nbsp;35,&nbsp;iY&nbsp;+=&nbsp;24,&nbsp;125,&nbsp;22&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_HUD.AddButton(&nbsp;IDC_CHANGEDEVICE,&nbsp;L"Change&nbsp;device&nbsp;(F2)",&nbsp;35,&nbsp;iY&nbsp;+=&nbsp;24,&nbsp;125,&nbsp;22,&nbsp;VK_F2&nbsp;);<br/>同样对于sample&nbsp;UI,&nbsp;加入了这些控件,一个静态文本,一个滑块,&nbsp;还有一个复选按钮.<br/>传递给静态文本的参数是IDC&nbsp;标识符,字符串,坐标,&nbsp;和宽高.<br/>滑块的参数是IDC&nbsp;标识符,字符串,坐标,&nbsp;和宽高,&nbsp;还有滑块的最大最小值,&nbsp;最后是存储结果的变量.<br/>复选按钮包括IDC标识符,一个字符串标签,wf坐标,&nbsp;宽高,还有存储结果的布尔值.<br/>&nbsp;&nbsp;&nbsp;&nbsp;iY&nbsp;=&nbsp;10;<br/>&nbsp;&nbsp;&nbsp;&nbsp;WCHAR&nbsp;sz;<br/>&nbsp;&nbsp;&nbsp;&nbsp;iY&nbsp;+=&nbsp;24;<br/>&nbsp;&nbsp;&nbsp;&nbsp;StringCchPrintf(&nbsp;sz,&nbsp;100,&nbsp;L"Puffiness:&nbsp;%0.2f",&nbsp;g_fModelPuffiness&nbsp;);&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_SampleUI.AddStatic(&nbsp;IDC_PUFF_STATIC,&nbsp;sz,&nbsp;35,&nbsp;iY&nbsp;+=&nbsp;24,&nbsp;125,&nbsp;22&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_SampleUI.AddSlider(&nbsp;IDC_PUFF_SCALE,&nbsp;50,&nbsp;iY&nbsp;+=&nbsp;24,&nbsp;100,&nbsp;22,&nbsp;0,&nbsp;2000,&nbsp;(int)(g_fModelPuffiness*100.0f)&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;iY&nbsp;+=&nbsp;24;<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_SampleUI.AddCheckBox(&nbsp;IDC_TOGGLESPIN,&nbsp;L"Toggle&nbsp;Spinning",&nbsp;35,&nbsp;iY&nbsp;+=&nbsp;24,&nbsp;125,&nbsp;22,&nbsp;g_bSpinning&nbsp;);<br/>一旦初始化了,&nbsp;这个对话框要显示在屏幕上.&nbsp;这个由&nbsp;OnD3D10ResizedSwapChain&nbsp;调用来完成既然屏幕坐标每次改变这个交换链会重建&nbsp;(可能由于窗口大小的变化).<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_HUD.SetLocation(&nbsp;pBackBufferSurfaceDesc-&gt;Width-170,&nbsp;0&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_HUD.SetSize(&nbsp;170,&nbsp;170&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_SampleUI.SetLocation(&nbsp;pBackBufferSurfaceDesc-&gt;Width-170,&nbsp;pBackBufferSurfaceDesc-&gt;Height-300&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_SampleUI.SetSize(&nbsp;170,&nbsp;300&nbsp;);<br/>对话框的最后一步在哪需要鉴别它们自己是&nbsp;OnD3D10FrameRender&nbsp;函数.&nbsp;一个对话框如果你不绘制它并且用户看不到不太好吧?<br/>&nbsp;&nbsp;&nbsp;&nbsp;//<br/>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Render&nbsp;the&nbsp;UI<br/>&nbsp;&nbsp;&nbsp;&nbsp;//<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_HUD.OnRender(&nbsp;fElapsedTime&nbsp;);&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_SampleUI.OnRender(&nbsp;fElapsedTime&nbsp;);<br/>资源管理程序初始化<br/>资源管理程序在每次回调初始化和销毁时需要被初始化.&nbsp;这是因为在每次设备被重建的时候&nbsp;GUI需被重建,&nbsp;或者交换链被重建的时候.&nbsp;CDXUTDialogResourceManager&nbsp;类包含符合每个这样的回调的函数,&nbsp;具有一模一样的名字.&nbsp;因此,&nbsp;它仅仅是在合适的地方插入代码来调用它们.<br/>&nbsp;&nbsp;&nbsp;&nbsp;V_RETURN(&nbsp;g_DialogResourceManager.OnD3D10CreateDevice(&nbsp;pd3dDevice&nbsp;)&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;V_RETURN(&nbsp;g_DialogResourceManager.OnD3D10ResizedSwapChain(&nbsp;pd3dDevice,&nbsp;pBackBufferSurfaceDesc&nbsp;)&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_DialogResourceManager.OnD3D10ReleasingSwapChain();<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_DialogResourceManager.OnD3D10DestroyDevice();<br/>响应GUI事件<br/>当全部初始化完成后,&nbsp;我们最后可以开始写代码来处理GUI交互了.&nbsp;在我们初始化对话框的时候,我们设置这些对话框的回调函数做为OnGUIEvent.&nbsp;现在我们将要创建&nbsp;OnGUIEvent&nbsp;函数,&nbsp;它会监听并处理GUI&nbsp;相关事件(被框架调用的).<br/>这是一个简单的对每个IDC标识符包含一个case代码块的函数,它在对话框创建时被监听.&nbsp;在每个case块中会是处理代码,假设用户以某种方式控制.这里的处理控制的代码跟&nbsp;Win32&nbsp;代码很像.<br/>跟HUD&nbsp;相关的控制实际上调用DXUT内置的函数.&nbsp;有一个DXUT&nbsp;函数关系到切换全屏,&nbsp;绑定引用软件渲染器,&nbsp;并且更改设备设置(它会调用下面提到的3D设置对话框).<br/>SampleUI&nbsp;对话框包含自定义的代码操作跟滑块相关联的变量.&nbsp;它会收集数值,&nbsp;更新与它相关的文本,&nbsp;并把数值传递给滑块.<br/>&nbsp;&nbsp;&nbsp;&nbsp;void&nbsp;CALLBACK&nbsp;OnGUIEvent(&nbsp;UINT&nbsp;nEvent,&nbsp;int&nbsp;nControlID,&nbsp;CDXUTControl*&nbsp;pControl,&nbsp;void*&nbsp;pUserContext&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(&nbsp;nControlID&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;IDC_TOGGLEFULLSCREEN:&nbsp;DXUTToggleFullScreen();&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;IDC_TOGGLEREF:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DXUTToggleREF();&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;IDC_CHANGEDEVICE:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_D3DSettingsDlg.SetActive(&nbsp;!g_D3DSettingsDlg.IsActive()&nbsp;);&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;IDC_TOGGLESPIN:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_bSpinning&nbsp;=&nbsp;g_SampleUI.GetCheckBox(&nbsp;IDC_TOGGLESPIN&nbsp;)-&gt;GetChecked();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;IDC_PUFF_SCALE:&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_fModelPuffiness&nbsp;=&nbsp;(float)&nbsp;(g_SampleUI.GetSlider(&nbsp;IDC_PUFF_SCALE&nbsp;)-&gt;Getvalue()&nbsp;*&nbsp;0.01f);<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WCHAR&nbsp;sz;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringCchPrintf(&nbsp;sz,&nbsp;100,&nbsp;L"Puffiness:&nbsp;%0.2f",&nbsp;g_fModelPuffiness&nbsp;);&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_SampleUI.GetStatic(&nbsp;IDC_PUFF_STATIC&nbsp;)-&gt;SetText(&nbsp;sz&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_pPuffiness-&gt;SetFloat(&nbsp;g_fModelPuffiness&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>更新消息处理<br/>既然现在我们有对话框消息和用户交互,&nbsp;那就会有传递给应用程序的消息需要被解析,&nbsp;如果适用的话.那些代码会在DXUT提供的&nbsp;MsgProc&nbsp;回调函数中被处理.&nbsp;在之前的指南里,&nbsp;这段是空白因为没有消息需要被处理.&nbsp;但是现在,我们要确保发送给资源管理程序和对话框的消息被适当地发送.<br/>不需要专门的消息处理代码;&nbsp;我们只需要对每个对话框调用MsgProcs来确保消息被处理了.这通过调用每个单独的类的相应的&nbsp;MsgProc&nbsp;函数来完成.&nbsp;应该注意到这个函数提供了一个标记通报给框架,不需要更多的处理,&nbsp;因此,可以退出.<br/>&nbsp;&nbsp;&nbsp;&nbsp;LRESULT&nbsp;CALLBACK&nbsp;MsgProc(&nbsp;HWND&nbsp;hWnd,&nbsp;UINT&nbsp;uMsg,&nbsp;WPARAM&nbsp;wParam,&nbsp;LPARAM&nbsp;lParam,&nbsp;bool*&nbsp;pbNoFurtherProcessing,&nbsp;void*&nbsp;pUserContext&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Always&nbsp;allow&nbsp;dialog&nbsp;resource&nbsp;manager&nbsp;calls&nbsp;to&nbsp;handle&nbsp;global&nbsp;messages<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;so&nbsp;GUI&nbsp;state&nbsp;is&nbsp;updated&nbsp;correctly<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*pbNoFurtherProcessing&nbsp;=&nbsp;g_DialogResourceManager.MsgProc(&nbsp;hWnd,&nbsp;uMsg,&nbsp;wParam,&nbsp;lParam&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;*pbNoFurtherProcessing&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;g_D3DSettingsDlg.IsActive()&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_D3DSettingsDlg.MsgProc(&nbsp;hWnd,&nbsp;uMsg,&nbsp;wParam,&nbsp;lParam&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Give&nbsp;the&nbsp;dialogs&nbsp;a&nbsp;chance&nbsp;to&nbsp;handle&nbsp;the&nbsp;message&nbsp;first<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*pbNoFurtherProcessing&nbsp;=&nbsp;g_HUD.MsgProc(&nbsp;hWnd,&nbsp;uMsg,&nbsp;wParam,&nbsp;lParam&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;*pbNoFurtherProcessing&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*pbNoFurtherProcessing&nbsp;=&nbsp;g_SampleUI.MsgProc(&nbsp;hWnd,&nbsp;uMsg,&nbsp;wParam,&nbsp;lParam&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;*pbNoFurtherProcessing&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;uMsg&nbsp;==&nbsp;WM_CHAR&nbsp;&amp;&amp;&nbsp;wParam&nbsp;==&nbsp;'1'&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DXUTToggleFullScreen();<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>3D设置对话框<br/>有一个专门的内置对话框用来控制D3DDevice的设置.&nbsp;DXUT提供的这个对话框就是CD3DSettingsDlg.&nbsp;它的功能像一个自定义对话框,但是它会提供给用户所有的他们需要修改的设置选项.<br/>&nbsp;&nbsp;&nbsp;&nbsp;CD3DSettingsDlg&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_D3DSettingsDlg;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Device&nbsp;settings&nbsp;dialog<br/>初始化就像其它对话框一样,&nbsp;你可以调用初始化函数.&nbsp;然而,&nbsp;每次Direct3D&nbsp;改变它的交换链或者设备,这个对话框必须被更新.因此,&nbsp;它必须包含一个调用在OnD3D10CreateDevice&nbsp;和OnD3D10ResizedSwapChain里,&nbsp;相对应地命名,&nbsp;来反映这些改变.&nbsp;同样地,销毁对象的改变必须被通报,&nbsp;因而,&nbsp;需要在&nbsp;OnD3D10DestroyDevice里调用.<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_D3DSettingsDlg.Init(&nbsp;&amp;g_DialogResourceManager&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;V_RETURN(&nbsp;g_D3DSettingsDlg.OnD3D10CreateDevice(&nbsp;pd3dDevice&nbsp;)&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;V_RETURN(&nbsp;g_D3DSettingsDlg.OnD3D10ResizedSwapChain(&nbsp;pd3dDevice,&nbsp;pBackBufferSurfaceDesc&nbsp;)&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;g_D3DSettingsDlg.OnD3D10DestroyDevice();<br/>在渲染的这一边,&nbsp;因为对话框的出现可以被改变,它通过一个叫&nbsp;IsActive()的标记来转换.&nbsp;如果这个标记被设成false,&nbsp;那么这个面板将不会被渲染.这个面板的改变是受上面说过的HUD对话框处理的.&nbsp;标记The&nbsp;IDC_CHANGEDEVICE与HUD&nbsp;控件相关,&nbsp;就像上面提到的那样.<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(&nbsp;g_D3DSettingsDlg.IsActive()&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;g_D3DSettingsDlg.MsgProc(&nbsp;hWnd,&nbsp;uMsg,&nbsp;wParam,&nbsp;lParam&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>一旦这些初始步骤都完成了,&nbsp;你就可以在你的程序中加入这个对话框.&nbsp;试着编译这个指南并与更改设置的面板进行交互来观察它的效果.&nbsp;真正的D3DDevice&nbsp;或交换链的重构在DXUT内部完成.<br/>文本渲染<br/>一个程序不会有趣如果用户不知道干什么.&nbsp;所以就DXUT包含了一个工具类用于在屏幕上绘制2D&nbsp;文本,&nbsp;用来给用户反馈.&nbsp;这个类,&nbsp;CDXUTD3D10TextHelper,&nbsp;允许你在屏幕的任意位置绘制一行行的文本,&nbsp;并有简单的字符串输入.&nbsp;开始之前,&nbsp;我们要实例化这个类.&nbsp;既然文本渲染与大多数初始化过程独立,&nbsp;在这个指南里我们让大部分代码在RenderText10里.<br/>&nbsp;&nbsp;&nbsp;&nbsp;CDXUTD3D10TextHelper&nbsp;txtHelper(&nbsp;g_pFont,&nbsp;g_pSprite,&nbsp;15&nbsp;);<br/>初始化<br/>我们传入的第一个参数是我们要绘制的字体.&nbsp;字体的类型是D3DX提供的ID3DXFont.&nbsp;要初始化这个字体,&nbsp;你调用D3DX10CreateFont,&nbsp;并且你要传入设备,&nbsp;高度,&nbsp;宽度,&nbsp;重量,&nbsp;mip层次&nbsp;(一般取&nbsp;1),&nbsp;斜体,&nbsp;字符集,&nbsp;精度,&nbsp;质量,&nbsp;倾斜度和家族,&nbsp;字体名称,&nbsp;还有你的对象的指针.&nbsp;虽然它看起来像很多字符,&nbsp;只有开始的4个和最后的2个真正有意义.<br/>&nbsp;&nbsp;&nbsp;&nbsp;V_RETURN(&nbsp;D3DX10CreateFont(&nbsp;pd3dDevice,&nbsp;15,&nbsp;0,&nbsp;FW_BOLD,&nbsp;1,&nbsp;FALSE,&nbsp;DEFAULT_CHARSET,&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OUT_DEFAULT_PRECIS,&nbsp;DEFAULT_QUALITY,&nbsp;DEFAULT_PITCH&nbsp;|&nbsp;FF_DONTCARE,&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;L"Arial",&nbsp;&amp;g_pFont&nbsp;)&nbsp;);<br/>第2个参数需要我们初始化一个ID3DXSprite&nbsp;类.&nbsp;要做这个的话,&nbsp;我们可以调用&nbsp;D3DX10CreateSprite&nbsp;(notice&nbsp;the&nbsp;trend&nbsp;here?).&nbsp;这个函数只需要设备和对象的指针做为参数.<br/>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Initialize&nbsp;the&nbsp;sprite<br/>&nbsp;&nbsp;&nbsp;&nbsp;V_RETURN(&nbsp;D3DX10CreateSprite(&nbsp;pd3dDevice,&nbsp;&amp;g_pSprite&nbsp;)&nbsp;);<br/>当然,&nbsp;像其它对象一样,&nbsp;字体和精灵在我们完成时必须被销毁.&nbsp;这可以用常见的&nbsp;SAFE_RELEASE&nbsp;宏完成.<br/>&nbsp;&nbsp;&nbsp;&nbsp;SAFE_RELEASE(&nbsp;g_pFont&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;SAFE_RELEASE(&nbsp;g_pSprite&nbsp;);<br/>渲染<br/>在这个示例里包含的文本里有渲染的统计信息.&nbsp;另外,&nbsp;还有一个区域显示怎样用鼠标操作模型.<br/>渲染必须在OnD3D10FrameRender里调用,&nbsp;而且在这个指南里,&nbsp;它是在帧渲染调用里调用RenderText10来完成的.<br/>第一个区域一直在绘制,&nbsp;因此,&nbsp;它最先完成.&nbsp;第一个文本渲染调用是Begin().&nbsp;它通知引擎我要开始输出文本到屏幕.&nbsp;在那之后,&nbsp;我们设置好“指针”的位置,&nbsp;文本的颜色,&nbsp;我们就准备绘制了.<br/>输出一个字符串文本要调用DrawTextLine来完成.&nbsp;你传入字符串,&nbsp;它就会在当前位置输出.&nbsp;它在文本书写的同时增加指针,&nbsp;因此,&nbsp;如果q包含了一个\n,&nbsp;它会自动移动指针到下一行.<br/>&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Output&nbsp;statistics<br/>&nbsp;&nbsp;&nbsp;&nbsp;txtHelper.Begin();<br/>&nbsp;&nbsp;&nbsp;&nbsp;txtHelper.SetInsertionPos(&nbsp;2,&nbsp;0&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;txtHelper.SetForegroundColor(&nbsp;D3DXCOLOR(&nbsp;1.0f,&nbsp;1.0f,&nbsp;0.0f,&nbsp;1.0f&nbsp;)&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;txtHelper.DrawTextLine(&nbsp;DXUTGetFrameStats()&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;txtHelper.DrawTextLine(&nbsp;DXUTGetDeviceStats()&nbsp;);<br/>还有另一个方法来输出文本,&nbsp;就好似通常使用的printf.&nbsp;你用特殊的字符来格式化字符串,&nbsp;然后插入变量到字符串里.&nbsp;这通过DrawFormattedTextLine来实现.<br/>&nbsp;&nbsp;&nbsp;&nbsp;txtHelper.SetForegroundColor(&nbsp;D3DXCOLOR(&nbsp;1.0f,&nbsp;1.0f,&nbsp;1.0f,&nbsp;1.0f&nbsp;)&nbsp;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;txtHelper.DrawFormattedTextLine(&nbsp;L"fTime:&nbsp;%0.1f&nbsp;&nbsp;sin(fTime):&nbsp;%0.4f",&nbsp;fTime,&nbsp;sin(fTime)&nbsp;);<br/>既然帮助绘制用一种相似的方式,&nbsp;所以不需要涵盖那部分代码了.&nbsp;一定要注意你能在任何时候通过调用SetInsertionPos来重新设置指针的位置.<br/>最后,&nbsp;当你对文本输出满意后,&nbsp;调用&nbsp;End()&nbsp;来通知引擎你完成了. <p></p><p>Feedback?&nbsp;Please&nbsp;provide&nbsp;us&nbsp;with&nbsp;your&nbsp;comments&nbsp;on&nbsp;this&nbsp;topic.<br/>For&nbsp;more&nbsp;help,&nbsp;visit&nbsp;the&nbsp;DirectX&nbsp;Developer&nbsp;Center</p><p>&amp;copy;&nbsp;2005&nbsp;Microsoft&nbsp;Corporation.&nbsp;All&nbsp;rights&nbsp;reserved.<br/></p>
页: [1]
查看完整版本: DXUT进阶(翻译)