標籤:opengl 使用者互動 顯示列表
菜單
GLUT提供了重要的組件--菜單。通常這些菜單都被實現為彈出式菜單。往往在滑鼠的某一鍵被按下時才會出現。定義菜單的三個步驟:
1、確定菜單中有哪些選項,即菜單的每行將顯示哪些字串。
2、菜單的每一行關聯一種特定操作。
3、每個菜單與滑鼠按鍵建立關聯。
菜單通常在主函數或主函數調用的初始化函數中被建立。GLUT允許建立串聯功能表,方法是一個功能表項目指向一個子功能表。頂級菜單由如下函數建立:
int glutCreateMenu(void (*f)(int value))
建立一個使用回呼函數f的頂級菜單,f由功能表項目傳入一個整數值value。該函數將為所建立菜單返回一個唯一標示符。
所建立的菜單將稱為當前菜單。
void glutSetMenu(int id) //將當前菜單設為標示符為id的菜單
void glutAddMenuEntry(char* name,int value) //為當前項增加一個名稱為那麼的功能表項目, value將被返回給菜單回呼函數
void glutAttachMenu(int button) //為當前菜單依附到一個指定的滑鼠按鍵上 (GLUT_RIGHT_BOTTON、GLUT_MIDDLE_BOTTON、GLUT_LEFT_BOTTON)
void glutAddSubMenu(char* name,int menu)
假如我們想用滑鼠右鍵彈出一個有兩個功能表項目的菜單:一個可清屏,一個結束程式。則可以在main或者init假如如下代碼:
int id=glutCreateMenu(mymenu);glutAddMenuEntry("Clear Screen",1);glutAddMenuEntry("Exit",2);glutAttachMenu(GLUT_LEFT_BUTTON);
mymenu函數定義如下:
void mymenu(int value) {if (value==1){glClear(GL_COLOR_BUFFER_BIT);glFlush();}if (value==2){exit(0);} }
NULL回呼函數
將NULL作為回呼函數,則可登出原來的回呼函數。
子視窗與多視窗
int glutCreateWindow(char* name) //建立一個最上層視窗name,並為其返回一個標示符
int glutDestoryWindow(int id) //銷毀標示符為id的最上層視窗
當一個視窗被建立後,它就成了當前視窗。圖元都將繪製在當前視窗中。
void glutSetWindow(int id) //將當前視窗設定為標示符為id的視窗。
int glutCreateSubWindow(int parent,int x,int y,int width,int height) //為parent創 建一個子視窗
當子視窗被建立時,它就成為當前視窗。
void glutPostWindowRedisplay(int winid) //通知標示符為winid的視窗重新顯示
顯示列表
OpenGL中的標準繪圖模式稱為立即模式。只要各種圖元被定義,就立即傳入到OpenGL流水線。當螢幕需要重繪時,我們必須重建這些圖元,然後再次將這些圖元傳入流水線。因此重新顯示的過程可能相當耗時。
保留模式下,圖元集合及其他資訊可作為對象儲存在伺服器中,這樣避免了代價較高的傳輸和重建的問題。OpenGL通過顯示列表來實現這些對象的定義。使用顯示列表的4個步驟:
1、開啟顯示列表
2、為其命名
3、添加命令
4、關閉顯示列表
void glNewList(GLuint name,GLenum mode) //建立一個新的顯示列表,mode的值(GL_COMPILE、 GL_COMPILE_AND_EXECUTE)
void glEndList() //結束顯示列表的定義
GL_COMPILE:將顯示列表放在伺服器中,但其內容不被顯示
GL_COMPILE_AND_EXECUTE:顯示列表建立時就被顯示。
void glCallList(GLuint name) //執行顯示列表name
void glDeleteLists(GLuint first,GLsizei number) //刪除由first開始的number個顯示列表。
多個顯示列表
void glCallLists(GLSizes num,GLenum type,GLvoid * lists)
//依據儲存類型為type的數組lists中的整數值執行num個顯示列表。當前位移量被疊加到lists中的每個認證上,這樣就得到了所要執行的顯示列表的ID
void glListBase(GLuint offset) //設定glCallLists()使用的位移量,預設為0
GLuint glGenLists(GLsizei n) //返回可用於新顯示列表的n個連續整數標示符中的第一個。
顯示列表與文本
若能為每一個字元使用一個顯示列表,則文本就能高效的得到繪製。若決定用GLUT的10磅大小的羅馬位元影像字型。我們需要256個顯示列表。
首先擷取256個連續可用的ID:
base=glGenLists(256);
接著為每個字型使用一個顯示列表:
for(i=0;i<256;i++)
{
glNewList(base+i,GL_COMPILE);
glutBitMapCharacter(GLUT_BITMAP_TIMES_ROMAN_10,i);
glEndList();
}
然後設定基數列表
glListBase(base);
如想繪製一個字串
char* text;
glCallLists((GLint)strlen(text),GL_UNSIGNED_BYTE,text);
顯示列表和對象
顯示列表為使用者提供了一種比立即模式更符合物件導向的思想的程式構建方式。顯示列表使得新顏色可以與幾何實體綁定在一起。顯示類表還可以在顯示列表中執行其他的顯示列表。例如,如要建立一個人物,我們可以把,臉,眼睛,鼻子,嘴巴分開繪製。
glNewList(FACE,GL_COMPILE);
glCallList(EYE);
glCallList(EAR);
glCallList(MOUTH);
glCallList(NOSE);
glEndList();
OpenGL學習(二)使用者與互動