• <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>

            實時陰影繪制技術研究

            C++博客 首頁 新隨筆 聯系 聚合 管理
              48 Posts :: 20 Stories :: 57 Comments :: 0 Trackbacks
            讓人很不爽的前兩天裝的directX9(decemeber)版和我看的這本《Direct3D游戲編程入門教程》有版本沖突。書里邊使用了 direct3D自己帶的框架,而這個框架和我裝的這個directX9是不一樣的,聽說這個版本包含了許多directX10的東西,可能是這個原因吧。
            我反復想是用新的框架還是裝回較早的版本,看了directX自帶的tutorail和文檔是英文的,不利于我速成。要是用原來的版本呢,可能換回來還需要一些代價。想來想去最后還是把原來那個卸了,裝回原來的版本。先速成再說。
            好,下面進入第5章的第一個例子-Basic。
             
            • CD3DApplication類

            這個是d3d通用框架中的應用程序基類,在WinMain()里邊聲明一個CD3DApplication對象,然后調用其Run()方法程序就跑起來了。簡單代碼如下:

            INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
            {
                CMyD3DApplication d3dApp;

                InitCommonControls();
                if( FAILED( d3dApp.Create( hInst ) ) )
                    return 0;

                return d3dApp.Run();
            }

            我們再來看一下CMyD3DApplication的聲明

            class CMyD3DApplication : public CD3DApplication
            {
             LPDIRECT3DVERTEXBUFFER9 m_pVB;  //vertice buffer的指針 
                DWORD m_dwSizeofVertices;    //頂點數

            protected:
                HRESULT OneTimeSceneInit();
                HRESULT InitDeviceObjects();
                HRESULT RestoreDeviceObjects();
                HRESULT InvalidateDeviceObjects();
                HRESULT DeleteDeviceObjects();
                HRESULT FinalCleanup();
                HRESULT Render();
                HRESULT FrameMove();
                HRESULT ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
              D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat );

            public:
                CMyD3DApplication();
            };

            也很簡單,兩個成員變量的含義已經注釋出來。需要說明一下的就是該程序使用vertex buffer來處理頂點,也就是直接把頂點復制到顯卡可以直接訪問到的驅動程序緩沖中,這樣就不必每次復制頂點,提高了效率。下面介紹一下該類的方法的調用:

            1. 程序啟動的執行順序是:ConfirmDevice()->OneTimeSceneInit()->InitDeviceObject()->RestoreDeviceObjects().
            2. 程序運行期間會執行一個循環:FrameMove()->Render()
            3. 如果運行期間改變窗口大小,框架會調用:InvalidateDeviceObjects()->RestoreDeviceObjects();
            4. 如果通過F2或者菜單來更改設備(HAL或REF),調用:InvalidateDeviceObjects()-> DeleteDeviceObjects()->InitDeviceObjects()->RestoreDeviceObjects();
            5. 程序退出時執行:InvalidateDeviceObjects()->DeleteDeviceObjects()->FinalCleanUp().

            下面說一下具體函數的含義:

            1. ConfirmDevice():最先被執行,用來檢查顯卡能力,如果顯卡不支持,框架會切換到使用參考光柵器,或切換為頂點軟件處理。具體參數見教材。
            2. OneTimeSceneInit():一次性永久初始化,初始化與設備無關的東西,與FinalCleanUp()搭配,初始化的數據可以在FinalCleanUp()中銷毀。
            3. InitDeviceObjects():初始化與設備相關的對象,如果通過F2使設備發生改變,那么就需要重新執行該初始化。與DeleteDeviceObjects()搭配。
            4. InvalidateDeviceObjects():對于窗口的大小改變做出響應。
            5. RestoreDeviceObjects():和InvalidateDeviceObjects()搭配,可以在窗口大小改變時重新設置投影矩陣和渲染狀態等等。除了在程序開始時以為,都會和InvalidateDeviceObjects()成對調用。
            6. DeleteDeviceObjects():在設備改變時對設備資源進行銷毀。
            7. Render():作為3D渲染的入口點在每一幀時被調用,可以設置render state,clear buffer,渲染場景。
            8. FrameMove():容納所有動畫的代碼。
            9. FinalCleanUp():銷毀幾何數據和文件對象等等非設備資源。

            OK,了解了執行過程,下面看一下重要步驟。

            在Basic例子程,程序較為簡單,繪制了一個無須任何坐標變換和投影的四邊形,并用 m_d3dEnumeration.AppUsesDepthBuffer = FALSE;設置了不使用深度緩存。這里邊重要的方法就是RestoreDeviceObjects()中創建頂點緩沖區:

            m_pd3dDevice->CreateVertexBuffer( m_dwSizeofVertices, D3DUSAGE_WRITEONLY, FVF,D3DPOOL_MANAGED,&m_pVB, NULL )

            這里m_dwSizeofVertices是頂點數,m_pVB是緩沖區指針,比較好理解。FVF表示每個頂點的表示形式,定義成const DWORD FVF = (D3DFVF_XYZRHW | D3DFVF_DIFFUSE);表示每個頂點由(x,y,z,rhw,diffuse)構成,direct3D的頂點表示還有specular, normal,紋理等信息,分別對應不同的變量組合。

            D3DPOOL_MANAGED是指定了D3D的資源管理器,負責對于紋理和幾何數據實施統一管理。D3D的資源管理器分成五種:

            1. D3DPOOL_DEFAULT:資源存儲在AGP或顯存中,在頂點緩沖或索引緩沖經常更新的情況下使用,避免內存到顯存的拷貝“過慢”。對于永遠不變的紋理,用默認池就是一種好的選擇。
            2. D3DPOOL_MANAGED:托管池,資源存儲在AGP或者顯存中,并在系統內存中有一份拷貝。只有內存發生變化才需要拷貝到顯存,如果性能不是最重要的,托管池永遠是一種最安全的選擇。
            3. D3DPOOL_SYSTEMMEN:系統池,存儲在系統內存中,設備丟失后(在全屏和窗口模式切換時或者改變分辨率)資源不需要重建。
            4. D3DPOOL_SCRATCH:臨時池,資源存儲在系統內存中,且設備丟失時無法重建,連同CreateOffScreenPlainSurface()一起使用,用于創建圖像表面。
            5. D3DPOOL_FORCE_DWORD:

            創建頂點緩沖器之后,是Lock()頂點緩沖器,然后執行memcpy()拷貝頂點,之后UnLock().這里Lock()包含四個參數, offsetToLock是鎖定頂點緩沖區從哪個偏移開始,SizeToLock是鎖定的大小,ppbData是返回指向內存緩沖區的指針,最后一個是指定如何使用頂點緩沖器.

            最后看一下Render()方法:

            HRESULT CMyD3DApplication::Render()
            {
                // Begin the scene
                if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
                {
              // In DX8: m_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
              // Passing an FVF to IDirect3DDevice9::SetFVF specifies a legacy FVF with stream 0.
                 m_pd3dDevice->SetFVF(FVF ); // new in DX9
              // DX8: only three parameters. In DX9 the third parameter is new
              m_pd3dDevice->SetStreamSource( 0, m_pVB, 0, sizeof(VERTEX) );
                 m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );

                  // End the scene.
                  m_pd3dDevice->EndScene();
                }

                return S_OK;
            }

            Render()方法中首先使用m_pd3dDevice初始化一個場景 BeginScene(),使場景處于處理過程中,這樣后邊的繪制才會奏效,否則都會返回D3DERR_SCENE_NOT_IN_SCENE的錯誤。結束繪制以后再調用EndScene()清除標識場景處于處理過程的標志,刷新緩存數據以及確認渲染表面完好。

            SetFVF()只有一個參數,就是頂點的結構,該方法僅用于固定流水線,對于使用shader的情況要調用SetVertexShader().

            SetStreamSource()設置了數據流,DrawPrimitive()把數據渲染出來。

            over!

            原文地址:http://blog.sina.com.cn/u/40d00f170100012z

            posted on 2005-12-23 00:24 苦行僧 閱讀(1323) 評論(0)  編輯 收藏 引用 所屬分類: directX
            亚洲国产综合久久天堂 | 久久久久亚洲AV成人网| 久久亚洲天堂| 9191精品国产免费久久| 久久精品中文騷妇女内射| 久久AV高潮AV无码AV| 久久国产精品无| 国产精品久久久久a影院| 久久精品成人欧美大片| 久久无码一区二区三区少妇| 91精品久久久久久无码| 国产精品欧美久久久久无广告| 亚洲国产精品久久久久婷婷软件 | 国产毛片久久久久久国产毛片| 99久久精品免费看国产一区二区三区| 欧美午夜A∨大片久久| 中文字幕精品久久久久人妻| 久久久久久久久66精品片| 久久久久久久久波多野高潮| 97精品依人久久久大香线蕉97| 性高湖久久久久久久久| a高清免费毛片久久| 精品无码久久久久久国产| 久久久久亚洲AV无码去区首| 一本久久精品一区二区| 青草国产精品久久久久久| 久久精品视频一| 伊人久久综合无码成人网| 国产69精品久久久久9999APGF | 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 国内精品久久久久久99蜜桃| 久久99国产精品尤物| 国产精品成人久久久久久久| 综合久久精品色| 久久久中文字幕| 婷婷国产天堂久久综合五月| 国产一级持黄大片99久久| 亚洲国产成人久久综合野外| 久久精品国产亚洲av日韩| 日韩十八禁一区二区久久| 久久成人影院精品777|