顯示列表(Display List)是一組暫存起來的OpenGL命令序列,可以被反覆執行。顯示列表會被儲存在server端,因此可以提高效率。
1、顯示列表的設計
顯示列表可以被視作是指令緩衝,而不是一個資料結構, 它不可以被修改;
顯示列表會對指令先做最佳化再儲存,這種最佳化是隨具體的OpengGL實現而定的,但一般來說肯定不會比“立即模式”更慢,可能被最佳化的地方有:1)變換矩陣計算;2)映像的光柵化,可能先轉化成適合硬體的格式;3)光照相關的屬性設定,這些屬性會涉及到一些矩陣計算,可能被預先執行,只緩衝結果;4)多邊形點畫模式;
顯示列表還是有一些額外的開銷的,因此顯示列表不能太小,否則效率上的收益會低於這種開銷;
顯示列表執行的時候,還是依賴於內容相關的,所以要注意上下文狀態的影響;
2、API
要使用顯示列表,先建立名字:GLuint glGenLists(GLsizei range);再把顯示表的指令序列放置在glNewList(GLuint list, GLenum mode)和glEndList(void)之間,就建立好了一個顯示列表;glIsList(GLuint
list)可以判斷一個名字是不是顯示列表; glDeleteLists(GLuint list, GLsizei range)刪除顯示列表。要調用的時候,glCallList(GLUint name)。
顯示列表是被儲存在server端的,所以如果顯示列表中間引用到用戶端變數,變數的值會被緩衝,之後變數的變化不會影響到顯示列表。
並不是所有的Opengl指令可以被儲存在顯示列表中,那些和client狀態有關的指令不可以,那些做狀態查詢的指令不可以(這些指令一般需要一個引用變數做傳出參數),這些指令如果出現的顯示列表的定義體中,會被立即執行。具體那些指令不可以,請參考手冊。
顯示列表可以嵌套調用,也即顯示列表1的實現主體可以調用現實列表2,這個特性允許我們設計出“可修改”顯示列表。比如我們可以動態地重新定義顯示列表2,這樣列表1的行為就會發生變化。
還可以一次調用多個顯示類表,glListBase(GLuint base)設定一個base值,glCallLists(GLsizei n, GLenum type, const GLvoid *lists)執行數組list裡面的n個顯示列表,list裡面的元素會加上base值得到顯示列表的名字。例如,把字型儲存為顯示列表,這項技術就很有用了。
顯示列表如果包含改變opengl state的代碼,在執行完成後,這個改變不會自動回復。有時候我們希望顯示列表執行完之後能夠把狀態變數恢複到執行之前,注意顯示列表不能使用glGet*這樣的狀態查詢函數的,推薦的方式是在顯示列表的起始處使用glPushAttrib()、glPushMatrix(),在末尾處使用glPopAttrib()、glPopMatrix()。
反過來,也可以使用顯示列表來進行多組狀態的管理,每個顯示列表的職責就是設定一組狀態。