有些新手不知道什麼是D3DFVF ,這裏做個簡單介紹,和一些應用。但關於D3DFVF 最官方的資料還是看SDK(但它是英文的)。
D3DFVF_XYZ——頂點的三維座標,表示有位置,而且會又Direct3D進行矩陣變換;
D3DFVF_XYZRHW——即平時所說rhw,它說明頂點有位置,而且經過了矩陣變換,不用在由Direct3D對它進行變換,通常用於做UI(用戶界面);
D3DFVF_DIFFUSE——表示頂點格式中有漫反射顏色;
D3DFVF_NORMAL——表示頂點有法線向量;
D3DFVF_TEX^——表示頂點有紋理座標,^可以是1至8,表示有多少套紋理座標;
以上是最常用的D3DFVF了,如果還要更詳細,請看SDK(一半以上的夠用了)。
還有一些應用方法:
1、在創建VB時,pd3dDevice->CreateVertexBuffer(3*sizeof(Vertex),D3DUSAGE_WRITEONLE,FVF,D3DPOOL_MANAGED,&先前聲明的VB,NULL);
在此之前還要先定義FVF:
#define FVF (D3DFVF_XYZ|D3DFVF_DIFFUSE)//這裏隨自己需要
還要定義自己的頂點結構,這個FVF,頂點結構可以這樣:
2、我們很多時候要用到ID3DXMesh,但它的頂點用矩陣變換還不夠,不能滿足骨骼動畫的需求,所以只能用Vertex Shader和ID3DXMesh::LockVertexBuffer()了,這裏重點說LockVertexBuffer()。
首先,我們不知道Mesh的格式,如果冒然用LockVertexBuffer()會出錯,所以先統一Mesh的頂點格式:
重新定義結構Vertex:
之後就可以Lock了:
學習D3D9的時候遇到靈活頂點格式(FVF)中D3DFVF_XYZRHW和D3DFVF_XYZ之間差異而引起的問題。
參看了同是C++博客的一篇博文,其分析如下:
在頂點結構體中沒有RHW時,Direct3D將執行視、投影、世界等變換以及進行光線計算,之後你才能在窗口中得到你所繪製的物體。當頂點結構體中有RHW時,就像上面那段英文所述,告知Direct3D使用的頂點已經在屏幕座標系中了,不再執行視圖、投影、世界等變換和光線計算,因爲D3DFVF_XYZRHW標誌告訴它頂點已經經過了這些處理,並直接將頂點進行光柵操作,任何用SetTransform進行的轉換都對其無效。不過這時的原點就在客戶區的左上角了,其中x向右爲正,y向下爲正,而z的意義已經變爲z-buffer的象素深度。
值得注意的是D3DFVF_XYZRHW和D3DFVF_XYZ、D3DFVF_NORMAL不能共存,因爲後兩個標誌與前一個矛盾。在使用這種頂點時,系統需要頂點的位置已經經過變換了,也就是說x、y必須在屏幕座標系中,z必須是z-buffer中的象素深度,取值範圍:0.0-1.0,離觀察者最近的地方爲0.0,觀察範圍內最遠可見的地方爲1.0。
結合我自己的試驗,有一些發現,記錄下來以備忘。
D3DFVF_XYZ默認的用戶區中心座標是(0,0),而D3DFVF_XYZRHW是左上角爲(0,0),用D3DFVF_XYZ默認的爲非光照的,而D3DFVF_XYZRHW是高洛德光照。
當使用D3DFVF_XYZ時,要設置渲染狀態:
而且要設置觀察矩陣和投影矩陣,例如:
否則沒有渲染結果。
D3DFVF_XYZRHW的格式是(x,y,z,1/w),RHW是指W的倒數。
使用這個格式的頂點是不通過頂點變換的,也就是直接對應窗口設備座標系,這個座標系下Z的範圍是[0,1],(x,y,z)的形式是仿射座標,(x,y,z,w)的形式是齊次座標,詳細的可以去看數學參考書。在這裏由於已經是設備座標系了,所以一般情況下w只用1.0。但如果是自己做的三維空間變換得到的座標,那麼w就很重要,因爲它要用於紋理的透視矯正。
D3DFVF_XYZ - 頂點格式包括未變換的頂點位置。這個標記不能和D3DFVF_XYZRHW一起使用。 [注意] 使用D3DFVF_XYZRHW時,RHW分量應設置爲>=1.0f,只有這樣才表明該頂點爲變換後的。 一定要了解DirectX SDK裏DX90SDK/Samples/C++/Direct3D/Tutorials/Tut02_Vertices下的例子,瞭解到D3DFVF_XYZ D3DFVF_XYZRHW的區別。 主要是rhw的值的設置上需要特別注意一下。 |
原帖地址:http://hi.baidu.com/shixueguili/blog/item/e9097f4ab292b82909f7ef09.html。