一、OpenGL的組成
- 圖元函數(primitive function)指定要生成屏幕圖像的圖元。包括兩種類型:可以在二維、三維或者四維空間進行定義的幾何圖元,如多邊形;離散實體;位圖。
- 屬性函數(attribute function)負責控制圖元的外觀。這類函數定義了顏色、線型、材質屬性、光照以及紋理。
- 觀察函數(viewing function)指定攝像機的屬性。OpenGL提供一個虛擬攝像機,我們可相對於由圖元函數定義的對象設置該攝像機的位置和朝向。我們也可以控制攝像機的鏡頭參數,以便制造出廣角或長焦效果。
- 查詢函數(query function)允許我們決定某一特定系統的性能以及OpenGL狀態變量的取值。
- 控制函數(control function)允許我們啟用或禁用各種OpenGL特性,如消隱、紋理映射和光照等。
- 輸入與窗口函數不屬於OpenGL核心庫,但是由於它們在交互式程序中的重要地位,這類函數已被包含在GLUT庫中。這些函數使我們能夠對屏幕中的窗口進行控制並使用鼠標和鍵盤。
二、庫組織結構
下圖是Linux平台下實現的庫組織結構
對於Windows 或 Macintosh平台,也有一張類似的組織結構圖。
應用程序既可以使用OpenGL、GLU以及GLX庫中的函數,也可以直接使用X庫或X工具集中的函數。
另外還有一種折衷的方法是借助GLUT庫,這樣可以使同一個程序能夠在不同的平台下重新編譯和運行。
三、GLUT
void glutInit(int * argc, char ** argv); //初始化GLUT,應在其他GLUT函數和OpenGL函數之前進行調用。 //glutInit()接收來自main函數的參數,程序可以具體實現相關的方式來使用這些參數
所有的GLUT函數都是以glut為前綴。
函數glutCreateWindow()將一個窗口以默認尺寸(300*300像素)顯示在屏幕的默認位置上(屏幕左上角)。該函數的參數使我們可為窗口創建一個標題。
int glutCreatewindow(char * title) //在屏幕上創建一個窗口,該窗口的標題由參數title給出。 //在多窗口情況下,該函數返回一個標識所創建窗口的整數。
下圖是帶有GLUT的庫組織結構:
四、事件循環和回調函數
void glutDisplayFunc(void (*func)(void)) //函數func()在每次需要對窗口重繪時被調用。 void glutMainLoop() //使程序進入無限事件處理循環。該函數的調用應作為main函數最后一條語句出現
提示:GLUT回調函數的形式是固定的。所以,若要在不同的函數之間進行值傳播,可能需要借助全局變量。
五、矩形的繪制
void glVertex<234><sifd>(type xcoordinate,type ycoordiante,...) void glVertex<234><sifd>(type * coordinates) //指定頂點在二維、三維或思維空間中的位置坐標,坐標值的類型可以是short(s)、int(i)、float(f)或double(d)。 //如果函數名的末尾出現了v,則type為一個指向指定類型的坐標數組的指針。
void glBegin(GLenum mode) //指定mode類型對象的起始點。mode可取GL_POINTS、GL_LINES或GL_POLYGON void glEnd() //指定頂點列表的終止點
提示:在頂點列表的末尾不要忘記包含glEnd()。
void glClear(GLbitfield mask) //清空mask指示的所有緩存的位。 //其中mask可由定義在gl.h中的常量通過邏輯或運算構成。GL_COLOR_BUFFER_BIT指顏色緩存
void glFlush() //強制執行之前緩存的所有OpenGL命令
六、示例程序
1 #include <GL/glut.h> 2 void display() //定義了所要繪制的圖形實體 3 { 4 glClear(GL_COLOR_BUFFER_BIT); 5 glBegin(GL_POLYGON); 6 glVertex2f(-0.5, -0.5); 7 glVertex2f(-0.5, 0.5); 8 glVertex2f(0.5, 0.5); 9 glVertex2f(0.5, -0.5); 10 glEnd(); 11 glFlush(); 12 } 13 14 int main(int argc, char ** argv) //OpenGL的初始化 15 { 16 glutInit(&argc, argv); 17 glutCreateWindow("simple"); 18 glutDisplayFunc(display); 19 glutMainLoop(); 20 }