• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            DXUT框架剖析(1)

            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(0555), 1.0f0) );

                
            // 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( 
            truetrue ); // Parse the command line and show msgboxes
                DXUTSetHotkeyHandling( truetruetrue );  // handle the default hotkeys
                DXUTSetCursorSettings( truetrue ); // Show the cursor and clip it when in full screen
                DXUTCreateWindow( L"AppFrame Sample" );
                DXUTCreateDevice( 
            true640480 );

                
            // Start the render loop
                DXUTMainLoop();

                
            // TODO: Perform any application-level cleanup here

                
            return DXUTGetExitCode();
            }

            運行效果圖:




            下載示例工程


            posted on 2008-05-15 11:23 lovedday 閱讀(3739) 評論(2)  編輯 收藏 引用

            評論

            # re: DXUT框架剖析(1) 2012-10-14 17:28 小馬甲

            博主理解的不錯 距離樓主還差的有點遠  回復  更多評論   

            # re: DXUT框架剖析(1) 2012-10-19 15:30 long275

            感謝樓主的講解  回復  更多評論   

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            亚洲国产精品久久久久婷婷软件| 日韩精品久久久久久久电影蜜臀| 久久免费视频6| 人人狠狠综合久久亚洲| 午夜精品久久久久久久| 99热成人精品免费久久| 免费久久人人爽人人爽av| 久久国产精品-久久精品| 婷婷久久五月天| 久久精品草草草| 思思久久精品在热线热| 国产成人精品久久| 久久99精品久久久久子伦| 亚洲精品第一综合99久久| 99久久免费国产精品| 久久久久人妻精品一区二区三区| 婷婷综合久久中文字幕| 久久久久久亚洲精品成人| 亚洲精品综合久久| 精品久久久久国产免费| 久久免费高清视频| 久久精品无码专区免费东京热| 久久久久国产成人精品亚洲午夜| 久久精品国产亚洲AV无码偷窥| 狠狠色丁香婷婷久久综合| 精品久久国产一区二区三区香蕉| 国产精品久久免费| 99久久人妻无码精品系列蜜桃 | 久久天堂AV综合合色蜜桃网| 久久99热这里只有精品66| 久久99久久成人免费播放| 亚洲精品国产成人99久久| 久久精品人人做人人爽97| 亚洲精品无码久久久久sm| 狠狠色婷婷久久综合频道日韩| 久久乐国产精品亚洲综合| 精品综合久久久久久88小说| 91亚洲国产成人久久精品网址| 国产精品久久久久久久| 国产精品美女久久久久久2018| 久久国产精品无码HDAV|