遊戲開發編程基礎第二章
三角形網格是構建物體模型的基本單元
通常網格中的三角形元素:
多邊形(polygons),圖元(primitives),網格幾何元(mesh geometry)
描述三角形單元時,需要指定改三角形單元3個頂點的位置
描述物體時,需要指定構成該物體的三角形單元列表
頂點結構定義好之後,就需要用靈活頂點格式(Flexible Vertex Format,FVF)標記的組合來描述頂點的組織圖
例如:
#define FVF_COLOR (D3DFVF_XYZ|D3DFVF_DIFFUSE)//位置屬性,漫反射顏色
#define FVF_NORMAL_TEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1)//位置,法線,紋理
定義靈活頂點格式時必須遵循一個約定:靈活頂點格式標記的指定順序必須與頂點結構中相應類型的資料定義的順序保持一致
三角形單元是3D物體的基本組成部分。構建一個物體,需要建立一個描述物體形狀的輪廓形狀和輪廓的三角形的單元列表
三角形單元列表包含了我們所希望繪製的每個獨立三角形的資料
三角形各頂點的指定順序非常重要,我們稱其為繞序(winding order)
為瞭解決頂點重合,引入索引的概念
我們建立一個頂點列表(vertex list)和一個索引列表(index list)
頂點列表包含了全部獨立頂點,索引列表包含了指向頂點列表的索引,這些索引規定了構建三角形單元,各頂點應按何種方式來組織
攝像機指定了情境對觀察者的可見部分,即將依據哪部分3d情境來建立2D映像
在全局座標系中,攝像機有一定的位置和方向,定義了可見的空間體積(在3D圖形學中也可稱為視域體或視截體)
位於視域體之外的物體時不可見的,在進一步處理時將應將其丟棄,丟棄這類資料運算過程稱為裁剪
投影視窗時一個2D地區,位於視域體中的3D幾何體通過投影映射到該地區中,便建立了3D情境的2D表示
很重要的一點是,矩形投影視窗在X和Y方向座標的最小值是min(-1,-1),最大值max(1,1)
Direct3D將檢視平面定義為平面z = 1
要想用Direct3D來完成座標變換,我們所必須做的是提供描述座標變換的變換矩陣
應用一個變換矩陣的方法是使用IDirect3DDevice9->SetTransfrom方法,
改方法有兩個參數:1,描述變換類型,2 描述變換矩陣
假定讓一個立方體的中心位於全局座標系中的點(-3,2,6)上,讓一個球體的中心位於點(5,0,-2)上:
立方體:
D3DXMATRIX cubeWorldMatrix;
D3DXMatrixTranslation(&cubeWorldMatrix,-3.0f,2.0f,6.0f);
Device->SetTransfrom(D3DTS_WORLD,&cubeWorldMatrix);
drawCube();
球體:
D3DXMATRIX sphereWorldMatrix;
D3DXMatrixTranslation(&sphereWorldMatrix,5.0f,0.0f,-2.0f)
Device->SetTransfrom(D3DTS_WORLD,&sphereWorldMatrix);
drawSphere();
為了簡化運算,我們將攝像機變換至全局座標系的原點,並將其旋轉,使攝像機的光軸與全局座標系z軸正方向一致,
同時,世界空間中所有幾何體都隨著攝像機一同進行變換,以保證攝像機的視場恒定。這種變換稱為取景變換,我們稱變換後的幾何體位
於觀察座標系中。
取景變換矩陣(觀察矩陣)可由如下D3DX函數得到:
D3DXMATRIX *D3DMatrixLookAtLH(
D3DXMATRIX* pOut,
CONST D3DXVECTOR3* pEye,//攝像機在全局座標系中的位置
CONST D3DXVECTOR3* pAt,//攝像機在全局座標系中的被觀察點
CONST D3DXVECTOR3* pUp//全局座標系中表示”向上“方向的向量
);
例:假定攝像機位於(5,3,-10),其觀察點為全局座標系的原點(0,0,0)
D3DXVECTOR3 position(5.0f,3.0f,-10.0f);
D3DXVECTOR3 targetPoint(0.0f,0.0f,0.0f);
D3DXVECTOR3 worolUp(0.0f,1.0f,0.0f);
D3DXMATRIX V;
D3DMatrixLookAtLH(&V,&position,&targetPoint,&worldUp);
// 取景變換需要用IDirect3DDevice9::SetTransform方法來設定,其中對應於變換類型的參數需指定為D3DTS_VIEW:
Device->SetTransform(D3DTS_VIEW,&V);
為了實現背面消隱,Direct3D需要區分哪些多邊形是正面,哪些是背面朝向。預設狀態下,Direct3D認為頂點排列順序為順時針(觀察座標
系中)的三角形單元時正面朝向的,頂點排列順序為逆時針(觀察座標系中)的三角形單元時背面朝向的
通過修改繪製狀態(render state)D3DRS_CULLMODE來達到目的
Device->SetRenderState(D3DRS_CULLMODE,
Value//D3DCULL_NONE 禁用背面消隱,//D3DCULL_CW只對順時針繞序的三角形單元進行消隱//D3DCULL_CCW預設
值,只對逆時針繞序的三角形單元進行消隱
);
投影變換定義了視域體,並負責將視域體中的幾何體投影到投影視窗中。投影矩陣比較複雜,我們將使用D3DX函數:
//其功能是依據視域體的描述資訊建立一個投影矩陣
D3DXMATRIX* D3DXMatrixPerspectiveFovLH(
D3DXMATRIX& pOut,//指向D3DXMATRIX 結構的操作結果矩陣。
FLOAT fovY,//觀察時y 軸方向的角度(弧度),就是觀察範圍夾角
FLOAT Aspect,//縱橫比
FLOAT zn,//近裁剪面位置Z值。
FLOAT zf//遠裁剪面位置Z值
);
投影矩陣應用要用方法:IDirect3DDevice::SetTransform來實現,其中對應變換類型的參數需指定為D3DTS_PROJECTION
例:
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj,PI*0.5f,(float)width/(float)height,1.0f,1000.0f);
Device->SetTransform(D3DTS_PROJECTION,&proj);
視口變換的任務是將頂點座標從投影視窗轉換到螢幕的一個矩形地區中,該矩形地區稱為視口
Direct3D中,視口用結構D3DVIEWPORT9來表示
typedef struct D3DVIEWPORT9{
DWORD X;
DWORD Y;
DWORD Width;
DWORD Height;
DWORD MinZ;//指定深度緩衝中的最小深度值
DWORD MaxZ;//指定深度緩衝中的最大深度值
}D3DVIEWPORT9;
該結構前4個資料成員定義了視口矩形相對於其父視窗的位置及大小。
Direct3D將深度緩衝的深度範圍設在[0,1]區間內,所以除非想要追求某種特效,MinZ和MaxZ應限制在指定區間內
例:
D3DVIEWPORT9 vp = {0,0,640,480,0,1};
Device->SetViewport(&vp);