1. 程式人生 > >Direct3D基礎——預備知識:多重取樣、畫素格式、記憶體池、交換鏈和頁面置換、深度快取、頂點運算、裝置效能

Direct3D基礎——預備知識:多重取樣、畫素格式、記憶體池、交換鏈和頁面置換、深度快取、頂點運算、裝置效能

多重取樣

用畫素矩陣表示影象的時候往往會出現塊狀效應,多重取樣便是一項用於平滑塊狀影象的技術。

圖片來自:DirectX9.03D遊戲開發程式設計基礎

左邊那條是一條鋸齒線,右邊是一條經過取樣的反走樣線,看上去要平滑的多。

D3DMULTISAMPLE_TYPE列舉型別包含了一系列列舉常量值,用於表示對錶面進行多重取樣的級別:

1、D3DMULTISAMPLE_NONE:禁止多重取樣

2、D3DMLTISAMPLE_1_SAMPLE    -----    D3DMLTISAMPLE_16_SAMPLE指定了從1~16級的多重取樣

另外還有一個與特定多重取樣型別相關的質量水平,該水平值用DWORD型別描述。

注意:多重取樣技術會顯著的降低應用程式執行速度,如果希望使用到多重取樣技術,請務使用:IDirect3D9::CheckDeviceMultiSampleType方法來檢測本地的圖形裝置是否支援所使用的多重取樣型別,並驗證由該型別的多重取樣得到的影象質量水平是否理想。

畫素格式

建立表面或者紋理時,常常需要指定這些Direct3D資源的畫素格式。畫素格式可以用D3DFORMAT列舉型別的列舉常量來定義。下面是一些常用格式:

1、D3DFMT_R8G8B8:每個畫素由24位組成。自最左端起,8位分配給紅色,8位分配給綠色,8位分配給藍色。

2、D3DFMT_X8R8G8B8:每個畫素由於32位組成。自最左端起,8位未使用,8位紅色,8位綠色,8位藍色。

3、D3DFMT_A8R8G8B8每個畫素山32位組成。自最左端起,8位分配給Alpha值,8位分配給紅色,8位分配給綠色,8位分配給藍色。

4、D3DFMT_A16B16G16R16F每個畫素由64位組成,是一種浮點數型別的畫素格式。自最左端起,16位分配給Alpha,16位分配給藍色,8位分配給綠色,8位分配給紅色。

5、D3DFMT_A32B32G32R32F每個畫素由128位組成,也是一種浮點數型別的畫素格式。自最左端起,32位分配給Alpha,32位分配給藍色,32位分配給綠色,32位分配給紅色。

注意;前面3種格式比較常用,並且為大多數的硬體裝置所支援,浮點數的畫素格式或者其他的可用格式還沒有廣泛的額支援,使用之前應該驗證硬體裝置是否支援。

 記憶體池

表面和其他Direct3D資源可以放入許多型別的記憶體池中。記憶體池的型別可以使用D3DPOOL列舉型別來表示,可用的記憶體池包括:

·D3DPOOL_DEFAULT 預設值.該型別的記憶體池指示 Direct3D將資源放入最適合該資源型別及其使用方式的儲存區中.該儲存區可能是視訊記憶體(video memory)、AGP儲存區或系統儲存區.注意,呼叫函式IDirect3DDevice9::Reset之前,必須對預設記憶體池中的資源銷燬(destroy)
或釋放(release).上述函式呼叫之後,還必須對記憶體池中的資源重新初始化.
·D3DPOOL_MANAGE放入該託管記憶體池中的資源將交由Direct3D管理(即,這些資源將根據需要被裝置自動轉移到視訊記憶體或AGP儲存區中).此外,這些資源將在系統儲存區中保留一個備份.這樣,必要時Direct3D會將這些資源自動更新到視訊記憶體中.·D3DPOOL_SYSTEMMEM指定將資源放入系統儲存區中.
·D3DPOOL_SCRATCH指定將資源放入系統儲存區中.不同於前述型別D3DPOOL_SYSTEMMEM,這些資源不受圖形裝置的制約.所以,裝置無法訪問該型別記憶體池中的資源.但這些資源之間可互相複製.

交換鏈和頁面置換

Direct3D維護著一個表面集合,該集合通常由兩三個表面組成,這個表面集合被稱為交換鏈。該集合用介面IDirect3DSwapChain9來表示,具體的實現細節我們可以不關心,它由Direct3D負責管理,目前我們不需要對其進行操作,只對其用途瞭解就可以。

交換鏈和頁面置換技術只要用於生成更加平滑的影象,下圖展示了由兩個平面組成的交換鏈:

圖片摘自:DirectX9.03D遊戲開發程式設計基礎—P43

上圖展示了擁有兩個表面的交換鏈:前臺快取和後臺快取,位於前臺快取的表面對應於在顯示器中顯示的影象。顯示器並不是立即的顯示出由前臺快取所表示的影象。例如:當顯示器的重新整理頻率是60HZ的時候,顯示一幀影象 需要1/60秒,應用程式的幀頻通常與顯示器的重新整理頻率是不同的(例如:應用程式繪製一幀影象的速度可能會快魚顯示器顯示一幀的速度),但是隻能是把前臺快取的內容顯示完畢之後,再能將前臺快取的內容更新為下一幀。但是通常我們在顯示器顯示前臺快取所表示的影象的時候,並不想停止對於影象的繪製,所以我們將下一個繪製的影象繪製在離屏表面,也就是我們的後臺快取。這樣一來,當顯示器將前臺快取內容顯示完畢之後,我們將其置換到交換鏈的末端,並將交換鏈中的下一個後臺快取提升為前臺快取,這個過程稱之為提交,下圖展示了提交前後的交換鏈。

上圖繪製功能的程式結構:

(1)在後臺快取繪製完成,提交到前臺快取

(2)將前臺快取表示的影象進行顯示

(3)顯示完成之後,將前臺快取置到交換鏈的末尾,

(4)再次回到步驟(1)重新開始在執行一遍

深度快取

深度快取是一個表面,一個只含有特定畫素的深度資訊而不含有影象資料的表面。深度快取為最終繪製的影象中的每一個畫素都保留了一個深度項。所以,當所繪製的影象的解析度為640×480的時候,深度快取中將有640×480個深度項。

例子(影象為DirectX9.03D遊戲開發程式設計基礎—P44):

上圖展示了一個簡單的場景,其中前面的物體部分遮擋住了位於其後面的物體。Direct3D為了判定某一物體的那些畫素位於另一個物體之前,使用了一項叫做:深度快取的技術

深度快取用於計算每一個畫素的深度值進行深度探測。深度探測的基本內容是讓處於同一位置的不同畫素進行競爭,以選出該位置到底應該寫入哪一個畫素。

舉例攝影機最近的畫素會被寫入到深度快取的位置,這是一種合理的做法,因為舉例攝影機近的畫素一定會將位於其後方的畫素進行遮擋。

深度快取的格式決定了深度快取的精度,即:24位的深度快取會比16位的深度快取精確的多,雖然Direct3D提供了32位的深度快取格式,但是通常24位的深度快取格式已經能夠讓應用程式獲得比較滿意的效果。

·D3DFMT_D32指定32位深度快取。
·D3DFMT_D24S8指定24位深度快取,其中8位保留供模板快取(stencil buffer)使用。
·D3DFMT_D24X8僅指定24位深度快取。
·D3DFMT_X4S4指定24位深度快取,其中4位保留供模板快取使用。
·D3DFMT_D16僅指定l6位深度快取。

頂點運算

頂點是3D幾何學中的基本元素,在Direct3D中,有兩種不同的頂點運算方式:軟體頂點運算方式和硬體頂點運算方式,無論採用何種配置的硬體,軟體頂點運算方式都會被支援,但是硬體頂點運算只有得到圖形卡的支援方可使用。

實際開發中,我們應該首先考慮硬體頂點運算方式,因為如果使用硬體專有的加速功能,程式的執行速度會比軟體的執行速度快很多,而且在硬體頂點運算方式中,可以不佔用CPU資源,也就意味著CPU可以解放出來進行其他計算。

注意:圖形卡支援硬體頂點運算功能,另一種等價的說法就是:圖形卡支援變換和光照的硬體計算。

裝置效能

Direct3D所提供的每一項效能都對應於D3DCAP9中的一個數據成員或者某一位,現在我們的思路是:首先以某一個具體的硬體為基礎,初始化一個D3DCAPS9型別的例項,然後在應用程式中通過檢查該D3DCAPS9例項中對應的資料成員或者某一位來判斷該裝置是否支援某一特性。

下面有一個例子:

假定我們希望檢查某一個硬體裝置是否可以進行硬體頂點計算,也就是判斷該裝置是否支援變換和光照的硬體計算。查閱D3DCAPS9的SDK文件,可以發現:資料成員D3DCAPS9:DevCaps的 D3DDEVCAPS_HWTRANSFORMANDLIGHT位可以用來表示裝置是否支援變換和光照的硬體的計算,假定caps為D3DCAPS9型別的一個例項並且已經初始化,測試程式碼如下:

bool supportsHardwareVertexProcessing;
//如果這些位是開啟的狀態,就表示硬體裝置支援他
if(caps. DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT){
    //該位表示邏輯真,也就是表示硬體裝置支援變換和光照的硬體計算
    supportsHardwareVertexProcessing =true;
}
else{
    supportsHardwareVertexProcessing =false;
}