OpenGL 顯示列表

2021-08-04 11:29:10 字數 3376 閱讀 3256

相關主題:頂點緩衝區物件(vbo)

顯示列表是一組被儲存或編譯的用來以後執行的opengl命令的集合。當乙個顯示列表被建立以後,所有的頂點資料和畫素資料被複製到位於伺服器端的顯示列表記憶體中。這個過程只進行一次。當顯示列表準備好(被編譯完成)後,你可以重複使用它而不需要在每幀中重複地傳輸這些資料。顯示列表是最快的一種繪製靜態資料的方式,因為頂點資料和opengl命令被緩衝在伺服器端的顯示列表中,這樣減少了從客戶端到伺服器段的資料傳輸。這意味著減少了執行實際的資料傳輸的cpu週期。

顯示列表另乙個重要的功能是顯示列表可以被多個客戶端所共享,因為它是伺服器端的狀態。

為了最佳的效能,將矩陣變換,光照,材質計算盡可能地放在顯示列表中,這樣opengl將只會在顯示列表建立時執行一次這些高昂開銷的計算,並將最終的結果儲存在顯示列表中。

然而,顯示列表有乙個缺點。當乙個顯示列表被編譯後,它不能被改變。如果你需要頻繁地改變資料或需要動態的資料,使用頂點陣列或頂點緩衝區物件。頂點緩衝區物件可以同時處理靜態和動態的資料。

注意並不是所有的opengl命令都可以儲存在顯示列表中。由於顯示列表是伺服器端的狀態,所有與客戶端狀態相關的命令不能被放置在顯示列表中。例如:glflush(),glfinish(),glrendermode(),glenableclientstate(),glvertexpointer()等這些函式不能放在顯示列表中。並且有返回值的opengl命令也不能放在顯示列表中,因為這些返回值需要被返回到客戶端,而不是顯示列表中,例如:glisenabled(),geget*(),glreadpixels(),glfeedbackbuffer()等。如果這些命令儲存在顯示列表中,它們將會被立即執行。

實現 使用顯示列表非常簡單。首先是使用glgenlists()函式建立乙個或多個顯示列表物件,它的引數是需要建立的顯示列表的數目,它返回連續的顯示列表塊中的第乙個元素的索引。例如,glgenlists()函式如果返回1並且你建立的顯示列表的數目為3的話,那麼索引1,2,3是可用的。如果opengl建立顯示列表失敗,它將會返回0。如果你不再使用顯示列表,可以使用gldeletelists()刪除它們。

第二步,你需要在glnewlist()和glendlist()塊之間儲存opengl命令到顯示列表中來優先渲染。這個過程叫做編譯。glnewlist()需要兩個引數,第乙個引數是glgenlists()函式返回的索引值,第二個引數是指定模式:是只編譯還是編譯並執行,gl_complile,gl_complile_and_execute。

到現在為止,準備工作已經做好了。只需要在每幀中使用glcalllist()函式或glcalllists()函式來執行顯示列表就可以了。

看一下下面這個簡單的顯示列表的例子:

[cpp]view plain

copy

// 建立乙個顯示列表物件

gluint index = glgenlists(1);  

// 編譯顯示列表, 儲存乙個三角形

glnewlist(index, gl_compile);  

glbegin(gl_********s);  

glvertex3fv(v0);  

glvertex3fv(v1);  

glvertex3fv(v2);  

glend();  

glendlist();  

...  

// 繪製顯示列表

glcalllist(index);  

...  

// 如果不再需要這個顯示列表,刪除它

gldeletelists(index, 1);  

注意只有在glnewlists()和glendlists()之間的opengl命令才會被記錄到顯示列表中一次,並在每次呼叫glcalllist()時快取一次。

為了使用glcalllists()執行多個顯示列表,你需要做乙個額外的工作。你需要使用乙個陣列來存放那些需要被渲染的顯示列表的索引。換句話說,你可以選擇渲染所有顯示列表中的部分顯示列表。glcalllists()需要3個引數:需要繪製的顯示列表的個數,索引陣列的資料型別,指向索引陣列的指標。

注意你可以不需要指定顯示列表的準確索引到陣列中,你可以指定它們的偏移量,然後使用gllistbase()設定基準的顯示列表的位置。當glcalllists()被呼叫時,實際的索引值會通過將基準的位置與偏移量想加得到。下面的例子顯示了如何使用glcalllists()以及一些說明:

[cpp]view plain

copy

gluint index = glgenlists(10);  

// 建立10個顯示列表

glubyte lists[10];              // 最多允許渲染10個顯示列表

glnewlist(index, gl_compile);   // 編譯第乙個顯示列表

...  

glendlist();  

...// 編譯中間的顯示列表

glnewlist(index+9, gl_compile); // 編譯最後乙個顯示列表

...  

glendlist();  

...  

// 只繪製部分顯示列表 (第1個,第3個,第5個,第7個,第9個)

lists[0]=0; lists[1]=2; lists[2]=4; lists[3]=6; lists[4]=8;  

gllistbase(index);              // 設定基準的位置

glcalllists(5, gl_unsigned_byte, lists);  

opengl為了方便起見提供了gllistbase()函式指定當glcalllists()函式執行時新增到顯示列表索引的基準。

在上面的例子中,只有5個顯示列表會被渲染:第1個,第3個,第5個,第7個,第9個。因此實際的偏移是index+0,index+2,index+4,index+6,index+8,這些偏移會被儲存在索引陣列中方便後面的渲染。如果glgenlists()函式的返回值是3,那麼背渲染的顯示列表的實際的索引是:3+0,3+2,3+4,3+6,和3+8。

glcalllists()顯示使用字型中相對應的ascii值做偏移的文字時非常有用。

例子

這個例子使用了顯示列表繪製了乙個茶壺(6320個多邊形)。最開始它使用頂點陣列,gldrwaelements(0來渲染茶壺,但是所有的gldrawelements()呼叫都是放置在顯示列表中。你可以看到使用顯示列表和頂點陣列在效能上的差異。

注意不能放置所有與客戶端狀態相關的opengl命令在顯示列表中,glenableclientstate(),glvertexpointer(),和glnormalpointer()不應該被仿製在顯示列表中。

OpenGL 顯示列表

原 文 lesson 12 display lists 譯 者 marhoo 這次我將教你如何使用顯示列表,顯示列表將加快程式的速度,而且可以減少 的長度。當你在製作遊戲裡的小行星場景時,每一層上至少需要兩個行星,你可以用opengl中的多邊形來構造每乙個行星。聰明點的做法是做乙個迴圈,每個迴圈畫出...

OpenGL顯示列表

opengl的顯示列表 一 簡介 所謂顯示列表就是一組預選儲存起來的留待以後呼叫的函式語句。呼叫此顯示列表時就按次序執行其中函式。以前所有的函式呼叫可以稱之為立即方式 immediate mode 現在我們將介紹顯示列表方式 display list 顯示列表可以優化程式執行效能。它被設計成命令的快...

OpenGL採用顯示列表顯示文字完整範例

2011 05 23 16 01 07 分類 預設分類 標籤 opengl 舉報 字型大小大中小訂閱 一 顯示英文 opengl並沒有直接提供顯示文字的功能,並且,opengl也沒有自帶專門的字型檔。因此,要顯示文字,就必須依賴作業系統所提供的功能了。各種流行的圖形作業系統,例如 windows系統...