原 文:lesson 12: display lists
譯 者:marhoo
這次我將教你如何使用顯示列表,顯示列表將加快程式的速度,而且可以減少**的長度。
當你在製作遊戲裡的小行星場景時,每一層上至少需要兩個行星,你可以用opengl中的多邊形來構造每乙個行星。聰明點的做法是做乙個迴圈,每個迴圈畫出行星的乙個面,最終你用幾十條語句畫出了乙個行星。每次把行星畫到螢幕上都是很困難的。當你面臨更複雜的物體時你就會明白了。
那麼,解決的辦法是什麼呢?用現實列表,你只需要一次性建立物體,你可以貼圖,用顏色,想怎麼弄就怎麼弄。給現實列表乙個名字,比如給小行星的顯示列表命名為「asteroid」。現在,任何時候我想在螢幕上畫出行星,我只需要呼叫glcalllist(asteroid)。之前做好的小行星就會立刻顯示在螢幕上了。因為小行星已經在顯示列表裡建造好了,opengl不會再計算如何構造它。它已經在記憶體中建造好了。這將大大降低cpu的使用,讓你的程式跑的更快。
那麼,開始學習咯。我稱這個demo為q-bert顯示列表。最終這個demo將在螢幕上畫出15個立方體。每個立方體都由乙個盒子和乙個頂構成,頂部是乙個單獨的顯示列表,盒子沒有頂。
這一課是建立在第六課的基礎上的,我將重寫大部分的**,這樣容易看懂。下面的這些**在所有的課程中差不多都用到了。
#include // header file for windows
#include // header file for standard input/output
#include // header file for the opengl32 library
#include // header file for the glu32 library
#include // header file for the glaux library
bool keys[256]; // array used for the keyboard routine
bool active=true; // window active flag set to true by default
bool fullscreen=true; // fullscreen flag set to fullscreen mode by default
下面設定變數。首先是儲存紋理的變數,然後兩個新的變數用於顯示列表。這些變數是指向記憶體中顯示列表的指標。命名為box和top。
然後用兩個變數xloop,yloop表示螢幕上立方體的位置,兩個變數xrot,yrot表示立方體的旋轉。
gluint texture[1]; // storage for one texture
gluint box; // storage for the display list
gluint top; // storage for the second display list
gluint xloop; // loop for x axis
gluint yloop; // loop for y axis
glfloat xrot; // rotates cube on the x axis
glfloat yrot; // rotates cube on the y axis
接下來建立兩個顏色陣列。
static glfloat boxcol[5][3]= // array for box colors
,,,,
};static glfloat topcol[5][3]= // array for top colors
,,,,
};lresult callback wndproc(hwnd, uint, wparam, lparam); // declaration for wndproc
現在正式開始建立顯示列表。你可能注意到了,所有創造盒子的**都在第乙個顯示列表裡,所有創造頂部的**都在另乙個列表裡。我會努力解釋這些細節。
glvoid buildlists() // build box display list
if (textureimage[0]=loadbmp("data/cube.bmp")) // load the bitmap
改變視窗大小的**和第六課是一樣的。
初始化的**只有一點改變,加入了一行buildlist()。請注意**的順序,先讀入紋理,然後建立顯示列表,這樣當我們建立顯示列表的時候就可以將紋理貼到立方體上了。
接下來的三行使燈光有效。light0一般來說是在顯示卡中預先定義過的,如果light0不工作,把下面那行注釋掉好了。
最後一行的gl_color_material使我們可以用顏色來貼紋理。如果沒有這行**,紋理將始終保持原來的顏色,glcolor3f(r,g,b)就沒有用了。總之這行**是很有用的。
glenable(gl_light0); // quick and dirty lighting (assumes light0 is set up)
glenable(gl_lighting); // enable lighting
glenable(gl_color_material); // enable material coloring
最後,設定投影校正,返回ture。
glhint(gl_perspective_correction_hint, gl_nicest); // nice perspective correction
return true; // initialization went ok
現在來看繪畫的**。對數學我從來都是很頭大的,沒有sin,沒有cos,但仍然看起來很奇怪(相信讀者不會覺得頭大)。首先,按慣例,清除螢幕和深度緩衝。
然後**紋理到立方體上(我知道**這個詞不太專業,但是……)。可以將這行放在顯示列表裡,但放在外邊,就可以在任何時候修改它。
int drawglscene(glvoid) // here's where we do all the drawing
}return true; // jump back
}下面的**是鍵盤控制的一些東西。
swapbuffers(hdc); // swap buffers (double buffering)
if (keys[vk_left]) // left arrow being pressed?
if (keys[vk_right]) // right arrow being pressed?
if (keys[vk_up]) // up arrow being pressed?
if (keys[vk_down]) // down arrow being pressed?
與以前的指南一樣,我們要確認視窗頂部標題的正確。
if (keys[vk_f1]) // is f1 being pressed?}}
}}
OpenGL 顯示列表
相關主題 頂點緩衝區物件 vbo 顯示列表是一組被儲存或編譯的用來以後執行的opengl命令的集合。當乙個顯示列表被建立以後,所有的頂點資料和畫素資料被複製到位於伺服器端的顯示列表記憶體中。這個過程只進行一次。當顯示列表準備好 被編譯完成 後,你可以重複使用它而不需要在每幀中重複地傳輸這些資料。顯示...
OpenGL顯示列表
opengl的顯示列表 一 簡介 所謂顯示列表就是一組預選儲存起來的留待以後呼叫的函式語句。呼叫此顯示列表時就按次序執行其中函式。以前所有的函式呼叫可以稱之為立即方式 immediate mode 現在我們將介紹顯示列表方式 display list 顯示列表可以優化程式執行效能。它被設計成命令的快...
OpenGL採用顯示列表顯示文字完整範例
2011 05 23 16 01 07 分類 預設分類 標籤 opengl 舉報 字型大小大中小訂閱 一 顯示英文 opengl並沒有直接提供顯示文字的功能,並且,opengl也沒有自帶專門的字型檔。因此,要顯示文字,就必須依賴作業系統所提供的功能了。各種流行的圖形作業系統,例如 windows系統...