最簡單的情形,多邊形網格不過是一個多邊形列表;三角網格就是全部由三角形組成的多邊形網格。多邊形和三角網格在圖形學和建模中廣泛使用,用來模擬復雜物體的表面,如建筑、車輛、人體,當然還有茶壺等。圖14.1給出一些例子:

當然,任意多邊形網格都能轉換成三角網格,三角網格以其簡單性而吸引人,相對于一般多邊形網格,許多操作對三角網格更容易。
表示網格
三角網格為一個三角形列表,所以最直接的表示方法是用三角形數組:
Listing 14.1: A trivial representation of a triangle mesh
struct Triangle {
Vector3 p[3];
};
struct TriangleMesh {
int triCount;
Triangle *triList;
};
對于某些應用程序,這種表示方法已經足夠。然而,術語"網格"隱含的相鄰三角形的連通性卻未在這種簡單表示中有任何體現。實際應用中出現的三角網格,每個三角形都和其他三角形共享邊。于是,三角網格需要存儲三類信息:
(1)頂點。每個三角形都有三個頂點,各頂點都有可能和其他三角形共享。
(2)邊。連接兩個頂點的邊,每個三角形有三條邊。
(3)面。每個三角形對應一個面,我們可以用頂點或邊列表表示面。
索引三角網格
在索引三角網格中,我們維護了兩個列表:頂點表與三角形表。
每個頂點包含一個3D位置,也可能有如紋理映射坐標、表面法向量、光照值等附加數據。
每個三角形由頂點列表的三個索引組成。通常,頂點列出的順序是非常重要的,因為我們必須考慮面的"正面"和"反面"。從前面看時,我們將用順時針方向列出頂點。另外一些信息也存在這一級中,如預先計算的表面法向量,表面屬性(紋理映射)等。
程序清單14.2給出了一段高度簡化的代碼:
Listing 14.2: Indexed triangle mesh
// struct Vertex is the information we store at the vertex level
struct Vertex
{
// 3D position of the vertex
Vector3 p;
// Other information could include texture mapping coordinates,
// a surface normal, lighting values, etc.
}
// struct Triangle is the information we store at the triangle level
struct Triangle
{
// Indices into the vertex list
int vertex[3];
// Other information could include a normal, material information, etc.
}
// struct TriangleMesh stores an indexed triangle mesh
struct TriangleMesh
{
// The vertices
int vertexCount;
Vertex *vertexList;
// The triangles
int triangleCount;
Triangle *triangleList;
};
實踐中,三角網格類會有一系列方法,用于存取和維護頂點、三角形列表。當然,存儲多邊形網格,還需要定義一個多邊形類,用來表達有任意多頂點的面。為簡化和提高效率,我們可以對每個多邊形的最大定點數做出限制。
注意到,索引三角形列表中的鄰接信息是隱含的。例如:邊信息沒有直接存儲,但我們還是可以通過搜索三角形表找出公共邊。和前面"三角形數組"方式相比,這種方式確實能節省不少空間。原因是信息存于頂點級別,它的整數索引比之三角形數組里存儲的頂點重復率要小得多。
高級技術
簡單索引三角網格對于基本應用已經足夠了,但為了更加高效地實現某些操作還可以進行一些改進。主要的問題是鄰接信息沒有顯式表達,所以必須從三角形列表中搜索。另一種表達方法可以在常數時間內取得這種信息。
方法是維護一個邊列表,每個邊由兩個端點定義,同時維護一個共享該邊的三角形列表。這樣,三角形可視為三條邊而非三個點的列表,也就是說它是邊列表而不是點列表的索引。該思想的一個擴展稱作"winged
edge"模型,對每一頂點,存儲使用該點的邊的索引。
針對渲染的特殊表達
大多數圖形卡并不直接支持索引三角網,渲染三角形時,一般是將三個頂點同時提交。這樣,共享頂點會多次提交,三角形用到一次就提交一次。因為內存和圖形硬件間的數據傳輸是瓶頸,所以許多API和硬件支持特殊的三角網格式以減少傳輸量?;舅枷胧桥判螯c和面,使得現存中已有的三角形不需要再次傳輸。
從最高靈活性到最低靈活性,我們討論三種方案:頂點緩存,三角帶,三角扇。
頂點緩存
與其說頂點緩存是一種特殊的存儲格式,不如說是API和硬件之間的一種存儲策略,用以發揮連續三角形頂點一致性的特點。通常,高級代碼不需要了解頂點緩存是如何實現和執行的。
和其他緩存機制類似,頂點緩存基于最近使用的數據將來仍被使用的原則。圖形處理器緩存一小部分(如,16個)最近使用的頂點,當API要發送頂點時,首先探測緩存內是否已存在。當然,這要求API了解圖形卡緩存的大小和替換機制。若緩存內沒有該頂點,則發生脫靶,API發送頂點并更新緩存;若緩存內有該頂點,就命中,API通知圖形卡"使用緩存內位置x的頂點"。
頂點緩存其實是一種底層的優化手段,任何三角網都可用高級代碼實現正確渲染而不用考慮緩存。但進行頂點順序的調整,使共享頂點的三角形集中發送有助于提高效率。這種調整只需要進行一次,并且可以離線進行,它只會對性能有幫助,不會使沒有緩存的系統性能降低。善用緩存,可能使發送到顯卡的頂點數降低到平均每三角形少于一個。