DirectX9 0 入門手冊 5

2021-04-01 19:46:00 字數 4847 閱讀 2084

第一次寫這種文章,再加上自己也是菜鳥,雖然有部分內容是參考一些書籍及自己翻譯一些英文文章所寫出來的,但我相信文章裡面肯定也還有很多

bug,如果你發現了請告訴我,或者你有什麼想法也可以和我交流,我誠心和志同道合的人成為朋友,我的qq是

61010818

,我的郵箱

[email protected]

第一次寫這種文章,再加上自己也是菜鳥,雖然有部分內容是參考一些書籍及自己翻譯一些英文文章所寫出來的,但我相信文章裡面肯定也還有很多

bug,如果你發現了請告訴我,或者你有什麼想法也可以和我交流,我誠心和志同道合的人成為朋友,我的qq是

61010818

,我的郵箱

[email protected]

(慘了,開始自己最不願意接觸的數學部分了。啊?你也討厭數學?哈哈,那我就偷個懶,太深的數學知識我就不翻老書作複習了,只說一些基本的很簡單的吧。不過有空還是要看一些數學方面的書,特別是線性代數和立體幾何方面的。)

·向量(也叫向量,英文叫vector)

向量就是包含大小(長度)和方向的乙個量。向量有2維的,也有3維甚至4維的。在dx的所有結構體中,有乙個結構體是用來表示3維向量的,它就是d3dvector,這個結構體很簡單,只有三個成員:x、y、z。一般來說,如果不涉及到向量運算的話,用這個結構體來定義乙個向量就可以了。我們可以它來表示方向以及頂點在3d世界中的位置等。如果你要對那些向量進行一些運算的話,使用d3dvector就很不方便了,因為在d3dvector這個結構體中沒有過載任何的運算子,如果想要做乙個加法運算,就得分別對結構體中的每乙個成員進行運算了。嘿嘿,不用怕,在dx裡面有個叫d3dx的東東(包含d3dx.h標頭檔案),它裡面定義了很多方便我們進行數學計算的函式和結構。其中就有d3dxvector2,d3dxvector3,d3dxvector4這三個結構體。看它們的名字就應該知道它們的作用了吧。對於2維和4維的結構體這裡就不講了,其實它們也很簡單,和d3dxvector3差不多。不過要說明一點的是d3dxvector3是從d3dvector派生過來的,說明它和d3dvector一樣,有x、y、z這三個成員,除此之外,d3dxvector3還過載了小部分算術運算子,這樣我們就可以像對待整型那樣對d3dxvector3的物件進行加減乘除以及判斷是否相等的運算了。同時,由於d3dxvector3是從d3dvector派生過來的,所以兩者的物件可以互相賦值,在這兩種型別中隨便轉換。

還是簡單說一下向量的數**算吧。向量的加減法很簡單,就是分別把兩個向量的各個分量作加減運算。向量的乘除法也很簡單,它只能對乙個數值進行乘除法,運算的結果就是向量中的各個分量分別對那個數值進行乘除法後得出的結果。向量的模就是向量的長度,就是各個分量的平方的和的開方。向量的標準化就是使得向量的模為1,這對在3d世界中實現光照是很有用的。對於向量的運算,還有兩個「乘法」,那就是點乘和叉乘了。點乘的結果就是兩個向量的模相乘,然後再與這兩個向量的夾角的余弦值相乘。或者說是兩個向量的各個分量分別相乘的結果的和。很明顯,點乘的結果就是乙個數,這個數對我們分析這兩個向量的特點很有幫助。如果點乘的結果為0,那麼這兩個向量互相垂直;如果結果大於0,那麼這兩個向量的夾角小於90度;如果結果小於0,那麼這兩個向量的夾角大於90度。對於叉乘,它的運算公式令人頭暈,我就不說了,大家看下面的公式自己領悟吧……

//v3 = v1 x v2

v3.x = v1.y*v2.z – v1.z*v2.y

v3.y = v1.z*v2.x – v1.x*v2.z

v3.z = v1.x*v2.y – v1.y*v2.x

是不是很難記啊,如果暫時記不了就算了。其實我們主要還是要知道叉乘的意義。和點乘的結果不一樣,叉乘的結果是乙個新的向量,這個新的向量與原來兩個向量都垂直,至於它的方向嘛,不知大家是否還記得左手定則。來,伸出你的左手,

按照第乙個向量(v1)指向第二個向量(v2)彎曲你的手掌,這時你的拇指所指向的方向就是新向量(v3)的方向了。通過叉乘,我們很容易就得到某個平面(由兩個向量決定的)的法線了。

終於寫完了上面的文字,描述數學問題可真是費勁,自己又不願意畫圖,辛苦大家了。如果你覺得上面的文字很枯燥,那也沒關係。因為上面的不是重點,下面介紹的函式才是希望大家要記住的。

d3dx中有很多很有用的函式,它們可以幫助我們實現上面所講的所有運算。不過下面我只說和d3dxvector3有關的函式:

計算點乘:float d3dxvec3dot(

const d3dxvector3* pv1,

const d3dxvector3* pv2)

計算叉乘:d3dxvector3* d3dxvec3cross(

d3dxvector3* pout,

const d3dxvector3* pv1,

const d3dxvector3* pv2)

計算模:float d3dxvec3length(

const d3dxvector3* pv)

標準化向量:d3dxvector3* d3dxvec3normalize(

d3dxvector3* pout,

const d3dxvector3 pv)

對於d3dxvector3的加減乘除運算,上面已經講了,用+ - * / 就行了。

·矩陣與矩陣運算

什麼是矩陣?這個概念還真不好解釋,不過學過線性代數的人肯定都知道矩陣長什麼樣,那我在這裡就不解釋了。在d3d中,定義矩陣的結構體是d3dmatrix:

typedef

struct _d3dmatrix ;

float m[4][4];

};} d3dmatrix;

看這個結構的樣子,你就應該很清楚怎麼使用它來定義乙個矩陣了吧。在這裡我順便說一下c++中union的特性吧。像上面定義的結構體所示,在union裡面有兩個部分,乙個是結構體,另乙個是二維陣列,它有16個元素。在union中,所有的成員都是共用乙個記憶體塊的,這是什麼意思呢?繼續看上面的**,結構體中的成員_11和成員m陣列的第乙個元素是共用乙個記憶體空間,即它們的值是一樣的,你對_11賦值的同時也對m[0][0]進行了賦值,_11和m[0][0]的值是一樣的。這樣有什麼好處呢?比如你定義了乙個矩陣變數d3dmatrix mat;你想訪問矩陣中第三行第四列的元素,可以這樣做:mat._34;另外也可以這樣:mat.m[2][3](陣列是從位置0開始儲存的哦)。看起來使用後者比較麻煩,不過當你把中括號裡面的數換成i和j,使用mat.m[i][j]來訪問矩陣中的元素,你就應該知道它的好處了吧。

實際上直接使用d3dmatrix的情況不多,因為在d3dx中有個更好的結構體,那就是d3dxmatrix。和d3dxvector3相似,d3dxmatrix是從d3dmatrix繼承過來的,它過載了很多運算子,使得矩陣的運算很簡單。矩陣的運算方法我不打算多說了,下面只介紹和矩陣性質有關的三個函式。

產生乙個單位矩陣:d3dxmatrix *d3dxmatrixidentity(

d3dxmatrix *pout);//返回結果

求轉置矩陣:d3dxmatrix *d3dxmatrixtranspose(

d3dxmatrix *pout,//返回的結果

const d3dxmatrix *pm );//目標矩陣

求逆矩陣:d3dxmatrix *d3dxmatrixinverse(

d3dxmatrix *pout,//返回的結果

float *pdeterminant,//設為0

const d3dxmatrix *pm );//目標矩陣

至於什麼是單位矩陣,什麼是轉置矩陣,什麼是逆矩陣我就不說了,可以看一下線性代數的書,一看就明白了。簡單的加減乘除法可以使用d3dxmatrix結構體裡面過載的運算子。兩個矩陣相乘也可以用函式來實現,這將在接下來的矩陣變換中講到。

·矩陣變換

矩陣的基本變換有三種:平移,旋轉和縮放。

平移:

d3dxmatrix *d3dxmatrixtranslation(

d3dxmatrix* pout,//返回的結果

float x, //x軸上的平移量

float y, //y軸上的平移量

float z) //z軸上的平移量

;繞x軸旋**

d3dxmatrix *d3dxmatrixrotationx(

d3dxmatrix* pout, //返回的結果

float angle //旋轉的弧度

);繞y軸旋**

d3dxmatrix *d3dxmatrixrotationy(

d3dxmatrix* pout, //返回的結果

float angle //旋轉的弧度

);繞z軸旋**

d3dxmatrix *d3dxmatrixrotationz(

d3dxmatrix* pout, //返回的結果

float angle //旋轉的弧度

);繞指定軸旋**

d3dxmatrix *d3dxmatrixrotationaxis(  

d3dxmatrix *pout,

//返回的結果

const d3dxvector3 *pv,

//指定軸的向量

float angle

//旋轉的弧度

);縮放:

d3dxmatrix *d3dxmatrixscaling(

d3dxmatrix* pout, //返回的結果

float sx, //x軸上縮放的量

float sy, //y軸上縮放的量

float sz //z軸上縮放的量

);好了,這章就寫這麼一些東西。如果你覺得好像沒學到什麼的話,可能是因為不知道上面的知識有什麼用吧。下一章我將介紹世界空間、檢視空間(也叫攝像機空間)以及投影,這三者對應的是世界矩陣、檢視矩陣和投影矩陣。搞清楚這三個空間的作用後,我們就可以利用這章的知識使我們的3d世界動起來了。

DirectX9 0 入門手冊 5

第一次寫這種文章,再加上自己也是菜鳥,雖然有部分內容是參考一些書籍及自己翻譯一些英文文章所寫出來的,但我相信文章裡面肯定也還有很多 bug,如果你發現了請告訴我,或者你有什麼想法也可以和我交流,我誠心和志同道合的人成為朋友,我的qq是 61010818 我的郵箱 fowenler 126.com 慘...

DirectX9 0 入門手冊 1

這一章我先不寫有關dx的東西,我先從最基本的視窗建立講起,然後再慢慢講解使用dx的一些內容.我寫這個指南的主要目的是為了學習。我希望自己可以通過寫這個指南更快地學會 directx 下面正式開始吧,先講視窗類,建立視窗,銷毀視窗,視窗訊息處理函式.視窗類 wndclass struct wndcla...

vs2008配置Directx 9 0開發環境

1 軟體安裝 vs2008簡體中文版 msdn2008 microsoft directx sdk june 2010 2 dx目錄配置 開啟vs2008 工具 選項 專案和解決方案 vc 目錄 1 引用檔案 c program files x86 microsoft directx sdk jun...