Linux下的OpenGL編程

來源:互聯網
上載者:User

OpenGL是一個工業標準的三維電腦圖形軟體介面,它由SGI公司發布並廣泛應用於Unix、OS/2、Windows/NT等多種平台,當然也包括Linux。在Windows/NT平台上,一般的開發工具如VC、BC、Fortran Powerstation等都支援直接的OpenGL應用的開發;在商用Unix平台上,Motif同樣很好的支援OpenGL(畢竟OpenGL最初是工作站上的東西);那麼在Linux上呢?
   本文不著力於OpenGL編程的方法和技巧,而是把重點放在如何在Linux平台上開發OpenGL程式。介紹支援OpenGL的幾個工具包,並輔以詳細的執行個體來闡述。

1.Linux下OpenGL編程環境簡介

  OpenGL不是自由軟體,它的著作權、商標(OpenGL這個名字)都歸SGI公司所有。但在Linux下有OpenGL的取代產品:Mesa。Mesa提供和OpenGL幾乎完全一致的介面,對利用OpenGLAPI編程的人來說,幾乎感覺不到任何差異。Mesa是遵循GPL協議(部分遵循LGPL協議)的自由軟體,而且,正是由於Mesa的自由性,它在對新硬體的支援度等方面都超過了OpenGL。Mesa可以從www.mesa3d.org取得。得到Mesa後,依照說明即可產生編寫程式所需要的動態、靜態串連庫和標頭檔。
   瞭解OpenGL的讀者都知道,OpenGL本身只提供三維圖形介面,不具備繪製視窗、接受響應、處理訊息等功能。這些功能必須由第三方的開發環境提供,如上面提及的VC等等。有人會想,既然在Motif下可以開發OpenGL程式,那麼,使用Linux下的Le tif也應該可以。是的,的確可以,但不幸的是,Linux下的Le tif是一個很不成熟的產品,而且也不具有可移植性,所以應用Le tif開發的人很少。下面我們簡單介紹幾個常用的工具包。
   在Linux下開發OpenGL程式,最常用的工具是GLUT(TheOpenGLUtility Toolkit)。它可以建立一個或多個OpenGL視窗,響應、處理使用者的互動操作、簡單的彈出式菜單以及一些內建的繪圖和字型處理功能。GLUT和OpenGL一樣,可以移植於多種平台。由於它良好的表現,現在它已經成為Mesa發布的標準套件之一。
   另一個很好的開發套件是FLTK(Fast Light Tool Kit),這是一個用C 編寫的圖形介面開發工具。和GTK 、KDE不同,它只關注於圖形介面的設計,而盡量不牽涉其他的實際應用。這個特點使得它比其他許多開發工具簡練和高效。而且,它同樣也是一個具有良好移植性的開發工具。事實上,它現在正引來越來越多人的興趣,許多商業軟體(尤其是致力於開發嵌入式案頭系統的軟體)都選用了它作為圖形介面的開發工具。關於它的詳細情況參見作者的另一篇文章《FLTK---一個優秀的圖形介面開發套件》。在FLTK裡有一個組件:Fl_Gl_Window是專門的OpenGL視窗,利用它開發OpenGL程式相當方便。
   最後要提的是GTK和KDE,它們是目前在Linux下用的最多的開發工具。GTK本身並不直接支援OpenGL(新的版本是否支援,尚不太清楚),但有人開發了支援OpenGL的Widget,叫做GLAREA,需要的讀者可以到網上去尋找或者與本文作者聯絡。KDE提供了對OpenGL的支援,但它的缺陷之一是KDE只運行於Linux系統,不具有可移植性。在這裡,我將主要向大家介紹前面兩個工具包。

2. 用GLUT開發OpenGL程式

2.1 如何獲得
  GLUT可以從Mesa中獲得,讀者也可以直接到它的首頁去下載它:                      http://reality.sgi.com/employees/mjk_asd/glut3/glut3.html。按照說明安裝後在OpenGL的標頭檔GL目錄下將會有GLUT的標頭檔glut.h,同時安裝的還有庫檔案libglut.a或libglut.so。有了它們以後,就可以用GLUT來編程了。

2.2 一個簡單的例子
下面,我們先看一個簡單的例子。這個例子畫一個立體的球。
/* light.c
此程式利用GLUT繪製一個OpenGL視窗,並顯示一個加以光照的球。
*/
/* 由於標頭檔glut.h中已經包含了標頭檔gl.h和glu.h,所以只需要include 此檔案*/
# include < GL /glut.h >
# include < stdlib.h >

/* 初始化材料屬性、光源屬性、光照模型,開啟深度緩衝區 */
void init ( void )
{
GLfloat mat_ ecular [ ] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_shinine [ ] = { 50.0 };
GLfloat light_position [ ] = { 1.0, 1.0, 1.0, 0.0 };

glClearColor ( 0.0, 0.0, 0.0, 0.0 );
glShadeModel ( GL_SMOOTH );

glMaterialfv ( GL_FRONT, GL_ ECULAR, mat_ ecular);
glMaterialfv ( GL_FRONT, GL_SHININE , mat_shinine );
glLightfv ( GL_LIGHT0, GL_POSITION, light_position);

glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_DEPTH_TEST);
}
/*調用GLUT函數,繪製一個球*/
void di lay ( void )
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glutSolid here (1.0, 40, 50);
glFlush ();
}
/* 定義GLUT的reshape函數,w、h分別是當前視窗的寬和高*/
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ( );
if (w <= h)
glOrtho (-1.5, 1.5, -1.5 * ( GLfloat ) h / ( GLfloat ) w,
1.5 * ( GLfloat ) h / ( GLfloat ) w, -10.0, 10.0 );
else
glOrtho (-1.5 * ( GLfloat ) w / ( GLfloat ) h,
1.5 * ( GLfloat ) w / ( GLfloat ) h, -1.5, 1.5, -10.0, 10.0);
glMatrixMode ( GL_MODELVIEW );
glLoadIdentity ( ) ;
}

/* 定義對鍵盤的響應函數 */
void keyboard ( u igned char key, int x, int y)
{
/*按Esc鍵退出*/
switch (key) {
case 27:
exit ( 0 );
break;
}
}

int main(int argc, char** argv)
{
/*GLUT環境初始化*/
glutInit (&am argc, argv);
/* 顯示模式初始化 */
glutInitDi layMode (GLUT_SINGLE |GLUT_RGB |GLUT_DEPTH);
/* 定義視窗大小 */
glutInitWindowSize (300, 300);
/* 定義視窗位置 */
glutInitWindowPosition (100, 100);
/* 顯示視窗,視窗標題為執行函數名 */
glutCreateWindow ( argv [ 0 ] );
/* 調用OpenGL初始化函數 */
init ( );
/* 註冊OpenGL繪圖函數 */
glutDi layFunc ( di lay );
/* 註冊視窗大小改變時的響應函數 */
glutReshapeFunc ( reshape );
/* 註冊鍵盤響應函數 */
glutKeyboardFunc ( keyboard );
/* 進入GLUT訊息迴圈,開始執行程式 */
glutMainLoop( );
return 0;
}
   從上面的例子中我們可以看出,GLUT採用一種函數註冊的機制來實現OpenGL繪圖。它的一般流程正如我們上面的注釋所寫,先是初始化函數,定義視窗,然後執行OpenGL初始化程式,這主要是一些需要全域設定的環境變數。接下來是註冊相應事件的函數,包括完成實際繪圖工作的繪製程式、改變OpenGL視窗大小時的響應函數、鍵盤事件的響應函數和滑鼠時間的響應函數。最後調用glutMainLoop()函數,執行在glutReshapeFunc和glutDi layFunc中註冊的函數,進入訊息迴圈。當使用者通過鍵盤和滑鼠進行互動操作時,它即調用相應的函數。
  我們編譯上面的名為light.c的源檔案。假定標頭檔(目錄GL)放在目錄/usr/local/include下,庫檔案(動態庫 libGL.so.*、libGLU.so.*和libglut.so.*)在目錄/usr/local/lib目錄下,並已經運行了ldconfig,則編譯命令為:
   gcc -I/usr/local/include -L/usr/local/lib -L/usr/X11R6/lib -lglut -lGLU -lGL
   -lX11 -lXext -lXmu -lXi -lm light.c -o light
   其中的-lX11 -lXert -lXi -lm 是繪製視窗需要的X的庫,它們預設在 /usr/X11R6/lib目錄下。下面的圖一即是運行light的結果,當按下ESC鍵時,程式會退出。調整視窗大小時,圖形自動重繪。注意在上面 reshape函數中,比較w和h的值給出的取景變換,這是一個常用的技巧。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.