深入淺出Direct3D 蔡軍生 版權所有

 /***********************************
 *作者:蔡軍生
 *出處:http://blog.csdn.net/caimouse/
 ************************************/
 
 深入淺出Direct3D
深入淺出Direct3D 蔡軍生 版權所有
·第 1 章 3D基礎知識
·1.1 什麼是3D?
·1.2 3D相關概念
·1.3 DirectX介紹
·1.4 Direct3D中3D基元
·1.5 Direct3D的表面和頂點法向矢量
·第 2 章 Direct3D系統架構
·2.1 Direct3D在系統中的位置
·2.2 Direct3D各個組件位置
·2.3 渲染
·第 3 章 Direct3D程序
 
·附錄A 1. Direct3D對象 
·附錄A 2. Direct3D的設備
·附錄A 3. Direct3D的資源
·附錄A 4. Direct3D的着色
·附錄A 5. Direct3D顯示場境
·附錄A 6. Direct3D基元渲染
·附錄A 7. Direct3D表面緩衝區翻轉
·附錄A 8. Direct3D中的3D座標變換
·附錄A 9. 矩陣


 什麼是3D
3D是three-dimensional的縮寫,就是三維圖形。在計算機裏顯示3D圖形,就是說在平面裏顯示三維圖形。不像現實世界裏,真實的三維空間,有真實的距離空間。計算機裏只是看起來很像真實世界,因此在計算機顯示的3D圖形,就是讓人眼看上就像真的一樣。人眼有一個特性就是近大遠小,就會形成立體感。
計算機屏幕是平面二維的,我們之所以能欣賞到真如實物般的三維圖像,是因爲顯示在計算機屏幕上時色彩灰度的不同而使人眼產生視覺上的錯覺,而將二維的計算機屏幕感知爲三維圖像。基於色彩學的有關知識,三維物體邊緣的凸出部分一般顯高亮度色,而凹下去的部分由於受光線的遮擋而顯暗色。這一認識被廣泛應用於網頁或其他應用中對按鈕、3D線條的繪製。比如要繪製的3D文字,即在原始位置顯示高亮度顏色,而在左下或右上等位置用低亮度顏色勾勒出其輪廓,這樣在視覺上便會產生3D文字的效果。具體實現時,可用完全一樣的字體在不同的位置分別繪製兩個不同顏色的2D文字,只要使兩個文字的座標合適,就完全可以在視覺上產生出不同效果的3D文字。

 相關概念
大家學習立體幾何時,都要用到座標系,才能把幾何體定位和計算。在計算機裏要顯示3D的圖像,就是顯示幾何體,就是把那些數字化的座標轉換成幾何圖像顯示。因此座標系必須要學習的,否則那一大堆座標數據就沒有辦法顯示,或者顯示出來是亂七八糟的。
在Direct3D裏也要用到座標系,它的座標系是左手座標系。目前常見的有兩種座標系,如下圖所示:
 原圖丟失了
 
  圖1.1:左手座標系,右手座標系

  左手座標系就是x軸的正方向指向右,y軸正方向批向上,z軸的正方向指向裏面。當伸出左手,讓四個手指指着x軸的正方向,大母指指向z軸的正方向,牚心指向y軸的正方向。符合這樣規則的座標系,就叫做左手座標系。
右手座標系就是x軸的正方向指向右,y軸正方向批向上,z軸的正方向指向外面。當伸出右手,讓四個手指指着x軸的正方向,大母指指向z軸的正方向,牚心指向y軸的正方向。符合這樣規則的座標系,就叫做右手座標系。
當然還有很多其它座標系,就不一一介紹了。
  如果想從文件中讀取不是左手座標系的幾何模型時,就要作相應的轉換。比如從右手座標系轉換到左手座標系,就是進行三角形頂點順序改變和翻轉。
  3D繪圖就是在二維的計算機屏幕上創建三維幻覺。爲了做到這一點,使用了數學變換進行建模和處理圖像。爲了熟悉3D算法和概念,作爲使用Direct3D創建和處理3D世界和對象的準備。理解3D算法是怎麼實現的將有助於你領悟使用Direct3D。
3D繪圖比2D繪圖要複雜的多,這是因爲程序需要理解的三維圖形在二維平面顯示的原理,比顯示在屏幕上的要多得多。創建三維圖形通常使用商業三維建模軟件,比如3DS,或3D MAX等等。
可以使用3D繪圖算法實時處理各種類似這樣的模型,使你的世界中的模型更具有真實感。這種具有真實感的模型由物體、攝像機和光源組成。
3D世界中包含的3D物體有各種屬性,可以通過處理這些屬性來改變物體。
  一個物體的形狀由表面定義,而表面可以被定義成平面或二次曲面。如果已經看過一些輪廓模型,就會知道用於實體物體的基本表面。每個物體都有紋理,定義了表面的粗糙度和光滑度。每個對象都有漫反射和鏡面反射,反射屬性決定了射到物體上的光線反射的程度。漫反射代表對象明暗程度。一個新的乾淨的球要比又舊又髒求具有更高的漫反射。鏡面反射代表了物體看起來的亮度,水晶瓶比木塊有更高的鏡面反射。物體的位置,在3D空間中由三個座標軸定義:x,y,z座標。物體方位性,即三維空間的某個方向。對方位進行轉動處理的效果是物體旋轉。
把小的、或最基本的物體組成大物體,這個處理被稱爲組合。組合簡化了複雜的大物體的移動。比如說一個自行車,它由兩個旋轉的車輪。當車輪旋轉的時候,整個車向前移動。車輪旋轉和移動的相對靜態座標系統。組合能使向前移動座標系統,同時保持把車輪約束在上面;無需明確的向前移動車輪。組合對一些複雜的移動物體,比如說轎車、飛機、動物等等是非常有用的。
爲了能看見物體,定義了攝像機代表用戶對3D世界的關聯。攝像機有一個位置和一個方向,它們定義了觀察者在3D世界的什麼地方看和看到的物體是什麼樣。在3D世界裏移動攝像機和改變它的方向使看到物體不同部份。
雖然有了物體和攝像機,但是還是什麼都看不見,除非把一些光線打到物體表面上。可以創建不同風格的光線,通過改變光線照亮的程度來改變物體在場景中的外觀。不同光線類型和效果佔用CPU和其它資源是不一樣的。
環境光對場景中所有的物體都提供了固定不變的照明,所有其它的光線光的強度和方向上都是不同的。
  點光源是從一個點發出的光,反射的角度取決於光點和物體位置之間的角度。就會在物體表面出反射現象。
  平行光同點光源類似,但它是從一個平面發射出來的光,經過反射後入射角和反反射角是一樣大小。這是的平行光計算量少的原因,但損失了一些真實感。
  聚光源正如它的的名字一樣,隨着接近物體,光線強度產生變化。
  方向光最經常用於模擬太陽光和其它無窮遠的光源。這種光源被看作來自無窮遠,一次它的強度不隨着接近物體而變化。在唯一的方向上,亮度是固定的。
  可以確定亮度或強度,來影響物體被照亮的程度。聚光源和其它的光源有一個確定光線從哪裏發出的方向。
  某些光源的強度受距離的影響。但對環境光來說不是這樣的,它沒有位置,不是有方向的光遠。通常與場景有無限遠的距離。
  可以創建不同的有色光。這比白色光要複雜的多,因爲它改變了所照到的每一個物體的顏色。
  3D繪圖有兩種重要的裁剪概念:視區(View Volumes)和可視表面(Visible Surface)。視區用於減少被渲染的對象的數量。越靠近攝像機,物體就越大,細節也越多。當遠離攝像機的時候,物體就變小了,細節也少。當物體非常遠的時候,它可以從視野中消失,而沒有丟失可被察覺的真實感。實際上,物體總是在一個適當的距離上被不被察覺地模擬得更簡單。
在攝像機後面的物體能夠很好的被裁剪;在2D應用程序中,超過屏幕四個邊的對象被裁剪。在裁剪中使用兩種投影。一種是平行(正交)投影,另一種是透視投影。透視投影使用沒影點。正如它的名字所示,距離觀察者遠的物體就變小了。
可視表面檢測是通過避免計算渲染不可見物體而加速渲染算法的一種方法。它需要計算出哪一個對象的表面在視區中沒有被裁剪以及哪些面遠離攝像機。
  實時地渲染3D場景需要處理大量的計算,因此就要找到一些好的方法來減少計算量,優化程序性能,但隨着技術的發展,越來越不那麼重視優化,並且顯示的場境非常的真實性。
隨着對3D圖形編程的概述,可以考慮使用Direct3D開始製作應用程序了。Direct3D使無須直接地寫驅動程序,就能夠訪問許多顯卡的3D硬件加速功能,讓很多3D算法可以在顯卡中直接運行,極大地加速3D程序性能。

 DirectX介紹
DirectX介紹     蔡軍生

微軟發佈"具有多項令人興奮功能"的DirectX 9.0!DirectX獲得更好的圖像顯示質量,使多人遊戲具可伸縮性,以及更棒的音頻效果。DirectX 9.0至少在以下幾個方面表現出色:
1、 強化了針對DirectDraw和Direct3D的接口,簡化了應用擴展,提升性能
2、 改善了圖形創作工具,更易於做出最佳的3-D角色和環境
3、 點光源式光影和像素式光影使圖象更逼真
4、 強化了DirectSound和DirectMusic,簡化了其應用擴展
5、 DLS2音頻合成功能提高了樂器音頻的真實感
6、 DirectInput的設備影射功能令對設備的支持更簡單;
7、 DirectPlay使多人遊戲的性能和可擴展性得到了提高;
8、 DirectPlay提供了IP聲音通訊;
9、 DirectShow的應用編程接口提供了音頻/視頻的實時合成和即時編輯;
10、DirectShow支持Windows媒體音頻和視頻(WMA和WMV)的讀寫;
11、Microsoft TV技術可以支持數字電視節目

DirectX是一種圖形應用程序接口(API),它的意思不難理解,Direct是直接的意思,X是很多東西,加在一起就是一組具有加束訪問硬件的東西。微軟定義它爲"硬件設備無關性,提高非常多媒體能力"。DirectX主要由以下幾個部分組成:
1、DirectDraw(2D繪圖)
2、Direct3D(3D繪圖)(注意:DirectDraw和Direct3D已經合併)
3、DirectSound(聲音相關)
4、DirectMusic(MIDI相關)
5、DirectInput(輸入相關)
6、DirectPlay(網絡相關)
7、DirectSetup(Setup相關)
8、DirectShow(動畫播放)
9、DirectX Media Objects(媒體數據流對象)
微軟在94年推出了WinG和WAVEMix。WinG擁有較高速的圖形處理能力,WAVEMix可以同時播放八聲道的聲音。其後又推出了能使得影像高速化的WinToon,但是這些產品的實用性不大。一直到Window95的問世,微軟開發了DirectX 1.0,並且根據硬件製造廠商和遊戲廠商合作共同更新升級DirectX的標準。
隨着DirectX版本的升級,功能越來越強大,DirectX已經成爲遊戲的工業標準。

 
 /***********************************
 *作者:蔡軍生
 *出處:http://blog.csdn.net/caimouse/
 ************************************/
 
 附錄A 1. Direct3D對象
附錄A 1. Direct3D對象 (蔡軍生 版權所有)
在Direct3D應用程序裏,最先創建的對象是Direct3D對象,最後刪除的對象也是Direct3D對象。那麼Direct3D對象是用來作什麼的呢?是怎麼樣創建的呢?
由於Direct3D對象是用COM實現,所以要用到Direct3D對象,就要先初始化COM庫,然後創建Direct3D的COM對象。如果在C++時創建Direct3D對象如下:
LPDIRECT3D9 g_pD3D = NULL;
if( NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
return E_FAIL;
D3D_SDK_VERSION參數是用來確定用那個版本SDK頭文件來編譯。創建Direct3D對象後,就可以通過來枚舉設備和檢查設備的兼容性。就可以進一步去創建顯示設備對象,對特定的設備選擇合適的顯示模式,特別硬件加速的編程。
 


 附錄A 2. Direct3D的設備
·附錄A 2. Direct3D的設備 (蔡軍生 版權所有)
  在Direct3D應用程序裏,Direct3D的設備是非常重要的。因爲Direct3D的設備提供矩陣變換,三維圖像渲染和三維圖像光柵化顯示。這些操作都需要大最運算,目前大部份集中在顯卡中處理。Direct3D的設備就是硬件顯卡的一種抽象,當然它是高於硬件的,因爲它不但可以直接使用硬件功能,還可以用軟件來模擬顯卡不存在的功能。
  要使用Direct3D的設備,就要根據不同類型,選擇合適的設備來創建。顯卡在應用程序裏不是獨佔的,就會造成設備丟失。因此,應用程序要處理這種情況,當發現丟失之後,就要去嘗試恢復設備,如果設備不能恢復就要當作錯誤處理。
  在使用設備之前,還要檢查設備是否支持應用程序要求支持的功能,如果不支持就要退出程序。如果不退出,整個系統就有可能出錯。同時檢測硬件支持什麼樣的頂點處理,是否支持硬件,或軟件,或軟件硬件混合,或只能其中一種等等。根據不同的處理,程序作相應的優化。還要把頂點的數據合適地傳送給相應的設備,否則就處理不了。
  在Direct3D的設備裏有兩大類,一類是HAL設備(HAL Device),一類是基準設備(Reference Device)。HAL設備主要用於速度要求高,實時處理快的程序裏,因爲它是用硬件加速的。而基準設備是全部用軟件實現,所有數據都用CPU來處理,主要用於測試和研究領域,正確性和精確性是最主要的目的,不考慮其速度。所以在遊戲裏用到的設備,應都是HAL設備。 

 附錄A 3. Direct3D的資源
·附錄A 3. Direct3D的資源 (蔡軍生 版權所有)
在Direct3D裏的資源,有很多種,但主要有紋理和緩衝區。應用程序要創建,加載,拷貝和使用這些資源。資源的接口都是繼承於COM接口IDirect3DResource9,其中紋理和緩衝區日的接口都是繼承上面的接口。這些的資源的接口如下圖所示:


資源有很多事情要做,比如瞭解資源屬性,操作資源,進行資源訪問時同步,同步就要用到鎖等,還有資源關係,應用程序怎麼樣管理和分配資源。很事情都要處理,處理資源的好壞關係程序的性能,比如什麼樣的紋理放到顯卡內存裏,什麼樣的頂點數據放到系統內存裏。
 
 附錄A 4. Direct3D的着色
·附錄A 4. Direct3D的着色 (蔡軍生 版權所有)
現在來介紹一下Direct3D裏的3D多邊形着色。在Direct3D裏有什麼樣的着色模式呢?怎麼樣設置着色模式呢?在Direct3D裏有兩種着色模式,分別是平面着色和Gouraud着色。兩種着色區分就是在多邊形裏每點着色的區別。平面着色就是用多邊形第一個頂點的顏色作來整個多邊形裏每個點的顏色;而Gouraud着色就是根據每個頂點的顏色,法線和光線來計算出多邊形裏每個點的顏色,這個就內部進行插值運算着色。比如頂點1的紅色成分爲0.8,頂點2的紅色成分爲0.4,用Gouraud着色計算出來頂點1和頂點2中間的紅色成分就是0.6。平面着色的優點,就是着色速度快。而Gouraud着色的優點,就是平面比較光滑,看起來比較真實。
下圖就兩種不同着色的茶壺比較:

兩種着色模式還有很多不同點,平面着色模式讓兩個平面連接的棱看起更尖,而Gouraud着色看起來棱就會變成平滑。但在光線着色裏,平面着色不大好,因爲整個平面都統一的顏色,看起來不真實,但Gouraud着色剛好相反,看起來比較真實,更加接近現實中光線照着的物體。不過Gouraud着色也會因爲進行插值運算,會丟掉一些實物的細節。像下圖進行Gouraud着色,就丟掉中間聚光燈。

在Direct3D裏的缺省着色模式是Gouraud着色,可以調用函數IDirect3DDevice9::SetRenderState來設置參數D3DRS_SHADEMODE來選擇不同的着色模式。下面的代碼就是怎麼樣設置着色模式。
// 設置爲平面着色模式。
// pDev是指向IDirect3DDevice9的指針。
hr = pDev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
if(FAILED(hr))
{
// 這裏處理出錯程況。
}

// 設置Gouraud着色模式。缺省是這種模式。
hr = pDev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
if(FAILED(hr))
{
//這裏處理出錯程況。
}
 
 附錄A 5. Direct3D顯示場境
·附錄A 5. Direct3D顯示場境 (蔡軍生 版權所有)
在Direct3D裏怎麼顯示場境呢?或者說怎麼樣顯示一幀的畫面?帶着這個問題,我們來看看Direct3D顯示過程。由於任何的動畫,都是基於電影的播放原理。就是由於人眼具有圖像視覺延遲性,當看到一幀圖畫時,並不能立即就從大腦裏消失。如果一秒鐘內至少保持24幀圖畫播放,就會看到的圖畫是連續的動畫。因此,Direct3D裏只要有顯示一幀圖畫的能力就行了。
Direct3D裏用函數IDirect3DDevice9::Present來顯示一幀動畫。要顯示這一幀動畫,有很多工作要做,先要計算好圖像位置、着色、貼圖、背景等等,然後把數據放到後備緩衝區(back buffer)裏,接着用上面的函數來把後備緩衝區換成前面緩衝區(front buffer),就可以顯示一幀動畫出來。Direct3D裏每個顯示設備都有一個後備緩衝區切換列表(swap chain),它用來保存後備緩衝區,當然可以添加很多後備緩衝區到裏面,關鍵看程序需要和顯存大小或者系統內存大小。Direct3D就是通過不斷從後備緩衝區切換列表裏取得後備緩衝區,顯示到前面緩衝區裏,就可以讓顯卡顯示動畫在顯示器上。把已經顯示的前面緩衝區,又放回到後備緩衝區切換列表裏,讓應用程序可以不斷地拷貝顯示數據到後備緩衝區切換列表的後備緩衝區裏面。
 

 附錄A 8. Direct3D中的3D座標變換
·附錄A 8. Direct3D中的3D座標變換(蔡軍生 版權所有)
在遊戲裏有很多物體,就拿CS來說,常常看到裏面有很多木箱,這些木箱位置是怎麼樣放上去的呢?因爲這些木箱都相同的,同樣大小,同樣紋理,但擺的位置不一樣,要表示這種不一樣的位置,就要用到3D座標空間,而用座標來表示兩個木箱相對位置。

座標變換是3D遊戲裏最基本知識,時時都要用到變換。比如從模型的座標空間轉換到世界座標空間,因爲很多模型創建時的座標空間都是相對創建時的座標空間。比如創建一個正方體,就是用來表示一個木箱,它的座標空間就是左手座標,但它的中心頂點是左手座標系的原點,要把這個木箱放到不同位置上,就要進行平移。要不同方向對着用戶,就要旋轉。這些平移和旋轉,都是怎麼樣計算的呢?其實學習過立體幾何都知道,使用矩陣來變換。矩陣就是一個3D變換的最好工具。矩陣可以保存變換的值,並還有可以通矩陣相乘得到各種變換。下面主要介紹矩陣,以及怎麼樣生成world、view、projection等變換的矩陣。

矩陣
world變換-從模型空間變換到world空間
view變換-從world空間變換到view空間
projection變換-從view空間變換到projection空間

 
·附錄A 9. 矩陣(蔡軍生 版權所有)

Direct3D使用矩陣這個工具來實現3D變換。其實矩陣是用來計算線性代數最方便工具,因爲座標變換都是線性方程組組成,肯定要用到矩陣這個工具來計算,纔是最佳的方法。在3D裏,最常用的是4行4列的矩陣,因爲它纔可以更加方便地計算三維座標的平移,旋轉和縮放等。如果用3行的矩陣,要表示平移是有困難的。
後面接討論下面內容:
3D變換
平移和縮放
旋轉
矩陣組合

 

 

發佈了2 篇原創文章 · 獲贊 13 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章