一旦我們描述幾何學上的3d場景和設定了虛擬照相機,我們要把這個場景轉換成2d圖象顯示在顯示器上。這一系列必須完成的操作就叫做渲染管線。圖2.7展示了乙個簡化的渲染管線,隨後將詳細解釋圖中的每一部分。
渲染管線中的許多級都是從乙個座標系到另乙個座標的幾何變換。這些變換都通過矩陣變換來實現。direct3d為我們進行變換計算並且如果顯示卡支援硬體變換的話那就更有利了。使用direct3d進行矩陣變換,我們唯一要做的事就是提供從乙個系統變換到另乙個系統的變換矩陣就可以了。我們使用idirect3ddevice9::settranform方法提供變換矩陣。它輸入乙個表示變換型別的引數和乙個變換矩陣。如圖2.7所示,為了進行乙個從自身座標系到世界座標系的變換,我們可以這樣寫:
device->settransform(d3dts_world, &worldmatrix);
自身座標系又叫做建模空間,這是我們定義物體的三角形列的座標系。自身座標系簡化了建模的過程。在物體自己的座標系中建模比在世界座標系中直接建模更容易。例如,在自身座標系中建模不像在世界座標系中要考慮本物體相對於其他物體的位置、大小、方向關係。圖 2.8所示是乙個在自身區域性座標系中定義的茶壺。
一旦我們構造了各種模型,它們都在自己的自身座標系中,但是我們需要把它們都放到同乙個世界座標系中。物體從自身座標系到世界座標系中的變換叫做世界變換。世界變換通常是用平移、旋轉、縮放操作來設定模型在世界座標系中的位置、大小、方向。世界變換就是通過各物體在世界座標系中的位置、大小和方向等相互之間的關係來建立所有物體。圖2.9所示是相對於世界座標系描述的幾個3d物體。
世界變換由乙個矩陣表示,並且在direct3d中呼叫idirect3ddevice9::settransform方法設定它,記住將轉換型別設為d3dts_world。例如我們要在世界座標系中放置乙個立方體定位在(-3,2,6)和乙個球體定位在(5,0,-2),我們可以這樣寫程式:
//建立立方體的世界矩陣(乙個平移矩陣)
d3dxmatrix cubeworldmatrix;
d3dxmatrixtranslation(&cubeworldmatrix, -3.0f, 2.0f, 6.0f);
//建立球體的世界矩陣(乙個平移矩陣)
d3dxmatrix sphereworldmatrix;
d3dxmatrixtranslation(&sphereworldmatrix, 5.0f, 0.0f, -2.0f);
// 變換立方體,然後繪製它
device->settransform(d3dts_world, &cubeworldmatrix);
drawcube(); // draw the cube
// 因為球體使用乙個不同的世界變換,我們必須更改世界矩陣為球體的,
// 如果不更改,球體將繪製在上乙個世界矩陣的位置上(立方體的世界矩陣)
device->settransform(d3dts_world, &sphereworldmatrix);
drawsphere(); // 繪製球體
這是個非常簡單的例項,沒有用到矩陣的旋轉和縮放。但是一般很多物體都需要進行這些變換,不過這個例子也還是展示了世界變換是怎樣進行的。
世界座標系中的幾何圖與照相機是相對於世界座標系而定義的,如圖2.10所示。然而在世界座標系中當照相機是任意放置和定向時,投影和其它一些操作會變得困難或低效。為了使事情變得更簡單,我們將照相機平移變換到世界座標系的原點並把它的方向旋轉至朝向z軸的正方向,當然,世界座標系中的所有物體都將隨著照相機的變換而做相同的變換。這個變換就叫做檢視座標系變換(view space transformation)。
檢視座標的變換矩陣可以通過如下的d3dx函式計算得到:
d3dxmatrix *d3dxmatrixlookatlh(
d3dxmatrix* pout, // 指向返回的檢視矩陣
const d3dxvector3* peye, // 照相機在世界座標系的位置
const d3dxvector3* pat, // 照相機在世界座標系的目標點
const d3dxvector3* pup // 世界座標系的上方向(0, 1, 0)
);peye引數指定照相機在世界座標系中的位置,pat引數指定照相機所觀察的世界座標系中的乙個目標點,pup引數指定3d世界中的上方向,通常設y軸正方向為上方向,即取值為(0,1,0)。
例如:假設我們要把照相機放在點(5,3,-10),並且目標點為世界座標系的中點(0,0,0),我們可以這樣獲得檢視座標系變換矩陣:
d3dxvector3 position(5.0f, 3.0f, –10.0f);
d3dxvector3 targetpoint(0.0f, 0.0f, 0.0f);
d3dxvector3 worldup(0.0f, 1.0f, 0.0f);
d3dxmatrix v;
d3dxmatrixlookatlh(&v, &position, &targetpoint, &worldup);
檢視座標系變換也是通過idirect3ddevice9::settransform來實現的,只是要將變換型別設為d3dts_view,如下所示:
device->settransform(d3dts_view, &v);
乙個多邊形有兩個表面,我們將乙個標為正面,乙個為背面。通常,後表面總是不可見的,這是因為場景中大多數物體是密封的。例如盒子、圓柱體、箱子、角色等,並且我們也不能把照相機放入物體的內部。因此照相機永不可能看到多邊形的背面。這是很重要的,如果我們能看背面,那麼背面揀選就不可能工作。
圖2.11表示了乙個物體在檢視座標系中的正面。乙個多邊形的邊都是面向照相機叫正面多邊形,而乙個多邊形的邊都背對照相機叫背面多邊形。
由圖2.11可知,正面多邊形擋住了在它後面的背面多邊形,direct3d將通過消除(即刪除多餘的處理過程)背面多邊形來提高效率,這種方法就叫背面揀選。圖2.12展示了背面揀選之後的多邊形,從照相機的觀察點來看,仍將繪製相同的場景到後備表面,那些被遮住的部分無論如何都永遠不會被看見的。
當然,為了完成這項工作,direct3d需要知道哪個多邊形是正面,哪個是背面。direct3d中預設頂點以順時針方向(在觀察座標系中)形成的三角形為正面,以逆時針方向形成的三角形為背面。
如果我們不想使用預設繪製狀態,我們可以通過改變d3drs_cullmode來改變渲染狀態:
device->setrenderstate(d3drs_cullmode, value);
value可以是如下乙個值:
d3dcull_none——完全不使用背面消除
d3dcull_cw——消除順時針方向環繞的三角形
d3dcull_ccw——消除逆時針方向環繞的三角形,這是預設值。
詳解流水線併發模型
我之前翻譯了一系列的關於併發模型的教程文章,有對其中的流水線模型表示不是很理解。實際上當時進行翻譯的時候自己也是一知半解,不過現在可以作進一步的介紹。典型的流水線模式如下如 可以這樣理解,例如 乙個任務分成三個步驟完成,將這三個步驟分成了三個 worker 讓不是很理解的是下面這張圖中非阻塞式io ...
流水線排程
n個作業要在由2臺機器m1和m2組成的流水線上完成加工。每個作業加工的順序都是先在m1上加工,然後在m2上加工。m1和m2加工作業i所需的時間分別為a i 和b i 你可以安排每個作業的執行順序,使得從第乙個作業在機器m1上開始加工,到最後乙個作業在機器m2上加工完成所需的時間最少。求這個最少的時間...
流水線冒險
流水線冒險 回顧一下常用五階段流水線 f 取指 d 解碼 e 執行 m 訪存 w 寫回 注意 對暫存器檔案的寫只有在時鐘上公升的時候才會更新!資料冒險的原因 對暫存器檔案的讀寫是在不同階段進行的 1.用暫停來避免資料冒險 暫停時,處理器會停止流水線中一條或多條指令,直到冒險條件不再滿足。在本該正常處...