在D3D中, 頂點被存儲在一個名為Vertex Buffer的資料結構中, 他是一段連續的記憶體, 頂點被一個挨一個的存儲在這個buffer中. 但問題是這個Vertex Buffer隻存儲了頂點, 并沒有指明這些頂點要如何組成幾何原型. 是以在D3D中, 我們指明 Primitive Topology 來告訴D3D如何”看待”這一串頂點資料.
在渲染管線一文中我們知道這部分處理是在INPUT ASSEMBLER階段進行的, DirectX的API名稱定義的非正常範, 我們用來設定原型拓撲的方法便是以”IA”開頭的 IASetPrimitiveTopology .
void ID3D11DeviceContext::IASetPrimitiveTopology(
D3D11_PRIMITIVE_TOPOLOGY Topology);
D3D提供了一個枚舉 D3D11_PRIMITIVE_TOPOLOGY 用來表示拓撲方式(MSDN文檔). 所有後來的draw call都将遵循這種格式, 直到再次調用IASetPrimitiveTopology改變拓撲方式.
typedef enum D3D11_PRIMITIVE_TOPOLOGY
{
D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED = ,
D3D11_PRIMITIVE_TOPOLOGY_POINTLIST = ,
D3D11_PRIMITIVE_TOPOLOGY_LINELIST = ,
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP = ,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST = ,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = ,
D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = ,
D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = ,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = ,
D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ = ,
D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = ,
D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = ,
//...
D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = ,
} D3D11_PRIMITIVE_TOPOLOGY;
下圖展示了幾種典型的拓撲方式, 更多細節請參考文檔和相關書籍.
- (a) point list
- (b) line strip
- (c) line list
- (d) trangle strip
實際上我們使用更多的是 Triangle List , 他不像Triangle Strip那樣彼此相連, 雖然這樣在表示連續的圖形時會浪費頂點, 但是好在我們可以使用索引緩存最大程度上減少這種浪費. 更重要的是由于不需要連續, 相較于Triangle Strip要更加靈活.