天天看點

Linux 3D 程式設計學習總結Linux下應用OGRE開發3DAndroid+Unity3D簡單的物體運動Linux下的OpenGL程式設計linux openGL "Hello world"

Linux下應用OGRE開發3D

linux下應用OGRE開發3D的資料網上很少,今天抽空整理一下。

大部分内容參考OGRE首頁http://www.ogre3d.org/。

首先根據首頁提示,我們可以利用已有資源建構一個工程,具體步驟如下:

第一步,準備工作,确定你是在linux環境下,進入終端,輸入一下指令:

編譯和配置

sudo apt-get install build-essential automake libtool

需要的依賴

sudo apt-get install libfreetype6-dev libfreeimage-dev libzzip-dev libxrandr-dev libxaw7-

dev freeglut3-dev

下面是可選項,一般還是裝上比較穩妥,不然後面出現問題不易查找

sudo apt-get install nvidia-cg-toolkit libois-dev libboost-thread-dev

sudo apt-get install doxygen graphviz libcppunit-dev

至此我們的準備工作已完成。接下來就要下載下傳工程源代碼,然後編譯。

第二步,下載下傳并編譯工程:

下載下傳工程源碼檔案:http://www.ogre3d.org/download/source/OGRE 1.7.4 Source for Linux / OSX

解壓檔案到/home目錄下:

tar xjf ogre_src_v1-7-4.tar.bz2

進入目錄:

cd ogre_src_v1-7-4

建立檔案build,這個檔案時用來存放編譯工程項目的,所有的編譯内容都将放在此目錄下:

mkdir build

進入此目錄:

cd build

由于此OGRE工程采用的CMake工具鍊進行編譯。是以使用CMake指令開始編譯:

cmake ..

編譯器會根據CMakeLists.txt産生一個新的CMakeFile檔案,接下來的編譯就和Make編譯一樣:

make -j2

如過此處顯示拒絕情況可以加sudo:sudo make -j2

最後一步:

sudo make install

所有的編譯工作已完成,下面就是執行工程,看看3D效果的,這裡還是要說明一下,如果你的電腦不支

持3D那就郁悶吧,因為這直接影響3D的渲染,結果當然是沒辦法看到執行的結果。如果支援3D渲染就繼

續一下操作吧!

cd build (這步已經執行了,隻是告訴一下是在這個目錄下)

cd bin

看到可執行檔案了吧!

./Samplexxxxxxx  這個檔案名記不全了,開頭那幾個字母的檔案就這一個,執行後會彈出一個界面,然

後選擇rendersystem,按住不放選中下來菜單,接下來就可以進入了,這裡你會看到所有你編譯的例子

,3D的,太棒了!如果願意,你可以修改源檔案參數,重新編譯。

========

Android+Unity3D簡單的物體運動

  我們來了解一下Translate的使用

  首先我們來看看場景的搭建:建一個立方體,加一個點光源。

  我們要實作的就是讓場景中的立方體延X軸嗖嗖的移動

  那麼我們在Project建立一個js腳本Creat->Javascript

  鍵入代碼

  function Update () 

{

        transform.Translate(Vector3(1,0,0));

}

  然後将js檔案拖到Hierarchy面闆的立方體上實作綁定。

  運作一下,我們可以看到,立方體嗖的一聲不見了。它一定是肚子餓了趕去吃飯了。

  好了,我們來修改代碼讓它慢一點。

  function Update () 

{

        transform.Translate(Vector3(1,0,0)*Time.deltaTime);

}

  運作一下,這會它老實了,慢慢的移動了。

  這是怎麼回事呢。接下來我們一步一步的分解代碼。

  首先Update()沒什麼好講的了,一直在用,相信大家都明白怎麼回事。

  接下來是

  transform:場景中的每一個對象都有一個transform,用來儲存和控制物體的位置,旋轉和縮放。

  Translate:是transform的函數,用來移動物體。它接受一個三維向量(Vector3)參數來移動。其

實它還有第二個參數,就是按照自身坐标軸移動還是按照世界坐标軸移動。這裡暫且不表。

  Vector3:表示3D的向量和點。3個參數分别代表了向量x,y,z。

  transform.Translate(Vector3(1,0,0));這句代碼的意思就是,讓被綁定的物體,也就是場景中的

立方體,向x軸的方向移動1個機關.

  Time.deltaTime:是一個時間增量,我想應該是這一幀的時間。像flash中的一秒30幀,每幀多少秒

之類的。在這個程式中它的值是0.016左右。原本移動一個機關,現在乘以0.016,那肯定慢了。也就是

說,它的作用其實就是減慢移動的速度。

  OK。

  本文工程源碼下載下傳:

  免費下載下傳位址在

  使用者名與密碼都是

  具體下載下傳目錄在 /pub/Android源碼集錦/2011年/11月/Android+Unity3D簡單的物體運動/

========

Linux下的OpenGL程式設計

    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幾乎完全一緻的接口,對利用OpenGL API程式設計的人來說,

幾乎感覺不到任何差異。Mesa是遵循GPL協定(部分遵循LGPL協定)的自由軟體,而且,正是由于Mesa的

自由性,它在對新硬體的支援度等方面都超過了OpenGL。Mesa可以從www.mesa3d.org取得。得到Mesa後

,依照說明即可生成編寫程式所需要的動态、靜态連接配接庫和頭檔案。 

   了解OpenGL的讀者都知道,OpenGL本身隻提供三維圖形接口,不具備繪制視窗、接受響應、處理消

息等功能。這些功能必須由第三方的開發環境提供,如上面提及的VC等等。有人會想,既然在Motif下可

以開發OpenGL程式,那麼,使用Linux下的Lesstif也應該可以。是的,的确可以,但不幸的是,Linux下

的Lesstif是一個很不成熟的産品,而且也不具有可移植性,是以應用Lesstif開發的人很少。下面我們

簡單介紹幾個常用的工具包。 

   在Linux下開發OpenGL程式,最常用的工具是GLUT(The OpenGL Utility 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 一個簡單的例子 

下面,我們先看一個簡單的例子。這個例子畫一個立體的球。 

# include < GL / glut.h > 

# include < stdlib.h > 

void init ( void ) 

GLfloat mat_specular [ ] = { 1.0, 1.0, 1.0, 1.0 }; 

GLfloat mat_shininess [ ] = { 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_SPECULAR, mat_specular); 

glMaterialfv ( GL_FRONT, GL_SHININESS, mat_shininess); 

glLightfv ( GL_LIGHT0, GL_POSITION, light_position); 

glEnable (GL_LIGHTING); 

glEnable (GL_LIGHT0); 

glEnable (GL_DEPTH_TEST); 

void display ( void ) 

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glutSolidSphere (1.0, 40, 50); 

glFlush (); 

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 ( unsigned char key, int x, int y) 

switch (key) { 

case 27: 

exit ( 0 ); 

break; 

int main(int argc, char** argv) 

glutInit (&argc, argv); 

glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); 

glutInitWindowSize (300, 300); 

glutInitWindowPosition (100, 100); 

glutCreateWindow ( argv [ 0 ] ); 

init ( ); 

glutDisplayFunc ( display ); 

glutReshapeFunc ( reshape ); 

glutKeyboardFunc ( keyboard ); 

glutMainLoop( ); 

return 0; 

   從上面的例子中我們可以看出,GLUT采用一種函數注冊的機制來實作OpenGL繪圖。它的一般流程正

如我們上面的注釋所寫,先是初始化函數,定義視窗,然後執行OpenGL初始化程式,這主要是一些需要

全局設定的環境變量。接下來是注冊相應事件的函數,包括完成實際繪圖工作的繪制程式、改變OpenGL

視窗大小時的響應函數、鍵盤事件的響應函數和滑鼠時間的響應函數。最後調用glutMainLoop()函數

,執行在glutReshapeFunc和glutDisplayFunc中注冊的函數,進入消息循環。當使用者通過鍵盤和滑鼠進

行互動操作時,它即調用相應的函數。 

   我們編譯上面的名為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的值給出的取景變換,這是一個常用的技巧。 

          圖一 

2.3 GLUT簡介 

   GLUT常用的函數主要包括以下幾類: 

   · 初始化函數。主要就是上面例子中的幾個函數。 

   · 消息循環函數。即glutMainLoop函數。 

   · 視窗管理函數。包括視窗的建立、修改、删除等。GLUT支援多個OpenGL視窗。 

   · Overlay管理函數。當使用者顯示卡支援Overlay方式時,可以用這些函數來建立、管理、删除GLUT

視窗的Overlay。 

   · 菜單管理函數。定制菜單以及定義菜單相應事件。 

   · 事件注冊函數。除了上面例子中提及的外,還有滑鼠、空間球(提供三維操作的裝備)、特殊

鍵(Ctrl、Shift、F系列鍵、方向鍵)等裝置的事件注冊函數。 

   · 字型繪制函數。用多種字型、字号供選擇。 

   · 簡單幾何體的繪制程式。包括球、立方體、錐體、圓環體、十二面體、八面體、四面體、二十

面體和茶壺。每種幾何體都有實體和虛線兩個選項。 

   · 取狀态函數。類似OpenGL的glGet系列函數,取得GLUT的各種狀态值。 

   · 顔色索引表函數。 

這些函數極大的友善了使用者的OpenGL程式設計。下面我們簡略介紹一下幾個常用的函數。 

   · glutPostRedisplay()。發送消息給函數glutMainLoop,請求重繪本視窗。利用此函數可以實

現動畫。例如在上面的例子中,我們添加一個全局變量:float move=0.0。并定義函數MoveSphere如下

: 

void MoveSphere ( void ) 

for(int i=0;i<100;i++){ 

if ( move<1.0) move+=0.1; 

else move=0.0; 

glutPostRedisplay ( ); 

同時修改函數display()為: 

void display ( void ) 

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glTranslatef ( move, 0.0, 0.0); 

glutSolidSphere (1.0, 40, 50); 

glFlush (); 

   這樣,當我們執行函數MoveSphere時,就會看到上面的球從中間向右移動一段距離,然後又回到中

心,繼續移動。 

   · glutIdleFunc()函數。這個函數注冊一個空閑程式一直在背景運作。我們将上面的

MoveSphere函數加以修改,去掉循環,然後在light.c程式的glutMainLoop()函數調用前添加一行代碼

:glutIdleFunc (MoveSphere);這樣我們不需要直接調用函數MoveSphere,程式一運作,它就被反複調

用直到我們退出程式為止,這和我們前一版本中它隻能循環特定的步數不一樣。 

   · glutTimerFunc()函數。和前面的glutIdleFunc()函數類似,但不同的是它注冊的函數每隔

特定的事件發生。時間的機關是毫秒。 

   · glutBitmapCharacter()函數。用位圖方式按指定的字型繪制一個字元串。 

   · glutSolidSphere()函數。這是繪制幾何體類函數中的一個。此函數繪制一個球體。 

2.4 一個更有代表性的例子 

   下面我們來看一個稍稍複雜的例子。我們繪制一個平面,使用者的左鍵點選被自動連接配接成一個多邊形

。當使用者點選右鍵,會彈出菜單供使用者選擇。使用者可以選擇清除、鑲嵌和退出。選擇清除将回到初始狀

态;選擇鑲嵌程式自動對多邊形進行三角剖分;選擇退出則終止程式。(見圖二、圖三和圖四) 

       圖二                圖三               圖四 

#include 

#include 

#include 

#include 

#define MAX_POINTS 256 

#define MAX_CONTOURS 32 

#define MAX_TRIANGLES 256 

typedef enum{ QUIT, TESSELATE, CLEAR } menu_entries; 

static mode_type mode; 

typedef enum{ DEFINE, TESSELATED } mode_type; 

static int menu; 

static GLsizei width, height;  

static GLuint contour_cnt;  

static GLuint triangle_cnt;  

static GLuint list_start;  

static struct { 

GLfloat p[MAX_POINTS][2]; 

GLuint point_cnt; 

} contours [ MAX_CONTOURS ] ; 

static struct { 

GLsizei no; 

GLfloat p [3] [2]; 

GLclampf color [3] [3]; 

} triangles [ MAX_TRIANGLES ]; 

void set_screen_wh ( GLsizei w, GLsizei h ) 

{ width = w; height = h; } 

void tesse ( void ) 

{ } 

void left_down ( int x1, int y1 ) 

GLfloat P[2]; 

GLuint point_cnt; 

P[0] = x1; P[1] = height - y1; 

point_cnt = contours [ contour_cnt ] . point_cnt; 

contours [ contour_cnt ] . p [ point_cnt ][ 0 ] = P [ 0 ]; 

contours [ contour_cnt ]. p [ point_cnt ] [ 1 ] = P [ 1 ]; 

glBegin ( GL_LINES ); 

if ( point_cnt ) { 

glVertex2fv ( contours[contour_cnt].p[point_cnt-1] ); 

glVertex2fv ( P ); 

else { 

glVertex2fv ( P ); 

glVertex2fv ( P ); 

glEnd(); 

glFinish(); 

contours[contour_cnt].point_cnt++; 

void middle_down( int x1, int y1 ) 

GLuint point_cnt; 

(void) x1; 

(void) y1; 

point_cnt = contours[contour_cnt].point_cnt; 

if ( point_cnt > 2 ) 

glBegin( GL_LINES ); 

glVertex2fv( contours[contour_cnt].p[0] ); 

glVertex2fv( contours[contour_cnt].p[point_cnt-1] ); 

contours[contour_cnt].p[point_cnt][0] = -1; 

glEnd(); 

glFinish(); 

contour_cnt++; 

contours[contour_cnt].point_cnt = 0; 

void mouse_clicked( int button, int state, int x, int y ) 

x -= x%10; 

y -= y%10; 

switch ( button ) { 

case GLUT_LEFT_BUTTON:  

if ( state == GLUT_DOWN ) { 

left_down( x, y ); 

break; 

case GLUT_MIDDLE_BUTTON:  

if ( state == GLUT_DOWN ) { 

middle_down( x, y ); 

break; 

void display( void ) 

GLuint i,j; 

GLuint point_cnt; 

glClear( GL_COLOR_BUFFER_BIT ); 

switch ( mode ) 

case DEFINE:  

glColor3f ( 0.6, 0.5, 0.5 ); 

glBegin ( GL_LINES ); 

for ( i = 0 ; i < width ; i += 10 ){ 

for ( j = 0 ; j < height ; j += 10 ) { 

glVertex2i ( 0, j ); 

glVertex2i ( width, j ); 

glVertex2i ( i, height ); 

glVertex2i ( i, 0 ); 

glColor3f( 1.0, 1.0, 0.0 ); 

for ( i = 0 ; i <= contour_cnt ; i++ ) { 

point_cnt = contours[i].point_cnt; 

glBegin( GL_LINES ); 

switch ( point_cnt ) { 

case 0: 

break; 

case 1: 

glVertex2fv ( contours[i].p[0] ); 

glVertex2fv ( contours[i].p[0] ); 

break; 

case 2: 

glVertex2fv( contours[i].p[0] ); 

glVertex2fv( contours[i].p[1] ); 

break; 

default: 

--point_cnt; 

for ( j = 0 ; j < point_cnt ; j++ ) { 

glVertex2fv ( contours [ i ]. p [ j ] ); 

glVertex2fv ( contours [ i ] .p [ j+1 ] ); 

if ( contours [ i ].p [ j+1 ] [ 0 ] == -1 ) 

glVertex2fv ( contours [ i ]. p [ 0 ] ); 

glVertex2fv ( contours [ i ] .p [ j ] ); 

break; 

glEnd(); 

glFinish(); 

break; 

case TESSELATED:  

glColor3f( 0.7, 0.7, 0.0 ); 

glCallList( list_start ); 

glLineWidth( 2.0 ); 

glCallList( list_start + 1 ); 

glLineWidth( 1.0 ); 

glFlush(); 

break; 

glColor3f( 1.0, 1.0, 0.0 ); 

void clear( void ) 

contour_cnt = 0; 

contours[0].point_cnt = 0; 

triangle_cnt = 0; 

mode = DEFINE; 

glDeleteLists( list_start, 2 ); 

list_start = 0; 

void quit( void ) 

exit( 0 ); 

void menu_selected( int entry ) 

switch ( entry ) { 

case CLEAR: 

clear ( ); 

break; 

case TESSELATE: 

tesse ( ); 

break; 

case QUIT: 

quit ( ); 

break; 

glutPostRedisplay(); 

void key_pressed( unsigned char key, int x, int y ) 

( void ) x; ( void ) y; 

switch ( key ) { 

case 'c': 

case 'C': 

clear(); 

break; 

case 't': 

case 'T': 

tesse(); 

break; 

case 'q': 

case 'Q': 

quit(); 

break; 

glutPostRedisplay(); 

void myinit( void ) 

glClearColor( 0.4, 0.4, 0.4, 0.0 ); 

glShadeModel( GL_FLAT ); 

glPolygonMode( GL_FRONT, GL_FILL ); 

menu = glutCreateMenu( menu_selected ); 

glutAddMenuEntry( "clear", CLEAR ); 

glutAddMenuEntry( "tesselate", TESSELATE ); 

glutAddMenuEntry( "quit", QUIT ); 

glutAttachMenu( GLUT_RIGHT_BUTTON ); 

glutMouseFunc( mouse_clicked ); 

glutKeyboardFunc( key_pressed ); 

contour_cnt = 0; 

mode = DEFINE; 

static void reshape( GLsizei w, GLsizei h ) 

glViewport( 0, 0, w, h ); 

glMatrixMode( GL_PROJECTION ); 

glLoadIdentity(); 

glOrtho( 0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0 ); 

glMatrixMode( GL_MODELVIEW ); 

glLoadIdentity(); 

set_screen_wh( w, h ); 

int main( int argc, char **argv ) 

glutInit ( & argc, argv ); 

glutInitDisplayMode ( GLUT_SINGLE | GLUT_RGB ); 

glutInitWindowSize ( 400, 400 ); 

glutCreateWindow( argv[0] ); 

myinit(); 

glutDisplayFunc( display ); 

glutReshapeFunc( reshape ); 

glutMainLoop(); 

return 0; 

3. 用FLTK開發OpenGL程式 

   從上面的例子我們不難看出,雖然GLUT為實作OpenGL程式設計提供了可能,但是作為應用程式,它是遠

遠不夠的。它隻提供了原始、簡陋的控制和操作方式,沒有一般應用程式所需要的按鈕、菜單條、輸入

框等控件。事實上,GLUT并不是用來單獨開發應用程式的,它是用作介于OpenGL函數接口和一般的圖形

界面開發接口之間的過渡層。在這一點上,它無疑是成功的。Mesa選擇它作為标準套件分發,大多數圖

形界面開發工具也保持與它的相容性。進而使得用GLUT開發的OpenGL程式有良好的可移植性。 

   和GLUT不同,FLTK本身是一個圖形界面開發工具,使用它完全可以開發實用的、商用的應用程式。

FLTK用C++編寫,使用面向對象的開發技術,它提供多種元件供使用者選用,每個元件有自己的屬性和事件

。在這裡,我們主要講述它的OpenGL視窗元件:Fl_Gl_Window,并充分使用C++的特性。 

   這一節裡,我們繪制一個可以自由旋轉、平移、放縮的小立方體。程式運作後如圖五所示。整個窗

口是一個由Fl_Window元件定義的一般視窗,中間是一個OpenGL視窗。我們使用了一些控制工具來調整小

立方體的屬性。上面的Zoom标尺調整它的大小,左邊和下邊各有一個平移标尺和一個旋轉标尺,調整小

立方體的位置和角度。這些标尺都是FLTK的标準元件,它們的作用是根據使用者的動作傳回特定的整數或

符點數。 

   Fl_Gl_Window最重要的是兩個虛函數:draw()、handle()和成員函數redraw()。函數draw(

)中定義繪制内容,建立視窗和視窗大小改變是這個函數被自動調用。函數handle()中定義對各種鍵

盤、滑鼠事件的響應。當有鍵盤、滑鼠事件響應時,這個函數被自動調用,如何有響應事件的函數被定

義,則會執行此函數。函數redraw()重繪視窗。在這個叫做CubeView的例子中,我們派生

Fl_Gl_Window,得到繪制我們這個小立方體的OpenGL視窗。 

// 檔案CubeView.cxx,派生Fl_Gl_Window,得到繪制小立方體的OpenGL視窗 

#include 

#include 

#include 

#include 

#include 

// 派生類CubeView的定義 

class CubeView : public Fl_Gl_Window { 

public: 

double size; // 定義小立方體的大小,供glScalef()函數使用 

// 構造函數,派生自Fl_Gl_Window,定義視窗大小和标題 

CubeView(int x,int y,int w,int h,const char *l=0); 

// 設定和取得垂直方向的旋轉角度,供元件标尺調用 

void v_angle(float angle){vAng=angle;}; 

float v_angle(){return vAng;}; 

// 設定和取得水準方向的旋轉角度,供元件标尺調用 

void h_angle(float angle){hAng=angle;}; 

float h_angle(){return hAng;}; 

// 設定水準和垂直方向的偏移量 

void panx(float x){xshift=x;}; 

void pany(float y){yshift=y;}; 

void draw(); 

private: 

void drawCube(); 

float vAng,hAng; 

float xshift,yshift; 

float boxv0[3];float boxv1[3]; 

float boxv2[3];float boxv3[3]; 

float boxv4[3];float boxv5[3]; 

float boxv6[3];float boxv7[3]; 

}; 

// 構造函數的定義 

CubeView::CubeView(int x,int y,int w,int h,const char *l) 

: Fl_Gl_Window(x,y,w,h,l) 

// 設定變換初值 

vAng = 0.0; 

hAng=0.0; 

size=10.0; 

// 設定小立方體頂點參數 

boxv0[0] = -0.5; boxv0[1] = -0.5; boxv0[2] = -0.5; 

boxv1[0] = 0.5; boxv1[1] = -0.5; boxv1[2] = -0.5; 

boxv2[0] = 0.5; boxv2[1] = 0.5; boxv2[2] = -0.5; 

boxv3[0] = -0.5; boxv3[1] = 0.5; boxv3[2] = -0.5; 

boxv4[0] = -0.5; boxv4[1] = -0.5; boxv4[2] = 0.5; 

boxv5[0] = 0.5; boxv5[1] = -0.5; boxv5[2] = 0.5; 

boxv6[0] = 0.5; boxv6[1] = 0.5; boxv6[2] = 0.5; 

boxv7[0] = -0.5; boxv7[1] = 0.5; boxv7[2] = 0.5; 

}; 

void CubeView::drawCube() { 

// 繪制一個半透明的立方體 

#define ALPHA 0.5 

glShadeModel(GL_FLAT); 

// 用不同的顔色繪制六個面 

glBegin(GL_QUADS); 

glColor4f (0.0, 0.0, 1.0, ALPHA ); 

glVertex3fv ( boxv0 ); glVertex3fv ( boxv1 ); glVertex3fv ( boxv2 ); glVertex3fv( boxv3 ); 

glColor4f(1.0, 1.0, 0.0, ALPHA); 

glVertex3fv ( boxv0 ); glVertex3fv ( boxv4 ); glVertex3fv ( boxv5 ); glVertex3fv ( boxv1 ); 

glColor4f(0.0, 1.0, 1.0, ALPHA); 

glVertex3fv ( boxv2 ); glVertex3fv ( boxv6 ); glVertex3fv ( boxv7 ); glVertex3fv ( boxv3 ); 

glColor4f(1.0, 0.0, 0.0, ALPHA); 

glVertex3fv ( boxv4 ); glVertex3fv ( boxv5 ); glVertex3fv ( boxv6 ); glVertex3fv ( boxv7 ); 

glColor4f(1.0, 0.0, 1.0, ALPHA); 

glVertex3fv ( boxv0 ); glVertex3fv ( boxv3 ); glVertex3fv ( boxv7 ); glVertex3fv ( boxv4 ); 

glColor4f(0.0, 1.0, 0.0, ALPHA); 

glVertex3fv ( boxv1 ); glVertex3fv ( boxv5 ); glVertex3fv ( boxv6 ); glVertex3fv ( boxv2 ); 

glEnd(); 

// 繪制立方體的輪廓線,一共12條 

glColor3f(1.0, 1.0, 1.0); 

glBegin(GL_LINES); 

glVertex3fv ( boxv0 ); glVertex3fv ( boxv1 ); 

glVertex3fv ( boxv1 ); glVertex3fv ( boxv2 ); 

glVertex3fv ( boxv2 ); glVertex3fv ( boxv3 ); 

glVertex3fv ( boxv3 ); glVertex3fv ( boxv0 ); 

glVertex3fv ( boxv4 ); glVertex3fv ( boxv5 ); 

glVertex3fv ( boxv5 ); glVertex3fv ( boxv6 ); 

glVertex3fv ( boxv6 ); glVertex3fv ( boxv7 ); 

glVertex3fv ( boxv7 ); glVertex3fv ( boxv4 ); 

glVertex3fv ( boxv0 ); glVertex3fv ( boxv4 ); 

glVertex3fv ( boxv1 ); glVertex3fv ( boxv5 ); 

glVertex3fv ( boxv2 ); glVertex3fv ( boxv6 ); 

glVertex3fv ( boxv3 ); glVertex3fv ( boxv7 ); 

glEnd(); 

}; 

void CubeView::draw() { 

if (!valid ( ) ) { 

//valid()當視窗大小改變時改變,導緻這一部分内容被執行,重新設定視窗 

glLoadIdentity(); 

glViewport(0,0,w(),h()); 

glOrtho(-10,10,-10,10,-20000,10000); 

glEnable(GL_BLEND); 

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 

glPushMatrix ( ); 

// 變換。參數繪被外部函數修改 

glTranslatef ( xshift, yshift, 0); 

glRotatef ( hAng, 0, 1, 0 ); glRotatef ( vAng, 1, 0, 0 ); 

glScalef ( float ( size ), float ( size ) , float ( size ) ); 

// 繪制立方體 

drawCube ( ); 

glPopMatrix ( ); 

}; 

上面的類CubeView定義了一個繪制立方體的OpenGL視窗,外部函數可以調用它的成員函數v_angle、

h_angle、panx、pany等來修改這個小立方體的屬性,修改以後,可以調用函數redraw()來重新整理視窗。

在下面的CubeViewUI.cxx中,我們定義類CubeViewUI,它繪制主視窗,并在其中定義了類CubeView的一

個執行個體:cube。它同時還定義了用來控制立方體屬性的5個标尺,當使用者操作标尺時,這些标尺調用

v_angle等函數來設定繪制立方體的一些參數。這一部分和我們的主題關系不大,不給出具體的代碼。最

後,我們定義main函數,它的内容相當的簡單。 

#include "CubeViewUI.h" 

int main(int argc, char **argv) { 

// 定義類CubeViewUI的一個執行個體 

CubeViewUI *cvui=new CubeViewUI; 

// 設定FLTK視窗顯示模式 

Fl::visual(FL_DOUBLE|FL_INDEX); 

cvui->show(); 

// 進入消息循環 

return Fl::run(); 

我們編譯、連接配接并執行程式,就可以得到如圖五所示的結果。從上面的例子我們可以看出使用FLTK編寫

OpenGL程式的一些優點,和GLUT它結構清晰,使用友善,而且它和GLUT是相容的。除了glutInit()、

glutMainLoop()等少數函數外,大部分GLUT函數可以在FLTK中使用。FLTK本身也提供了許多OpenGL函

數,如繪制字元串的gl_draw()等。 

4. 結束語 

   熟悉掌握了Linux下OpenGL的開發環境距離開發OpenGL程式還有很大的距離,畢竟問題的難點是如

何很好的使用OpenGL的API。本文為即将在Linux下開發OpenGL的讀者作一些鋪墊和準備工作,希望并相

信對大家有所幫助。

========

linux openGL "Hello world"

1. 安裝OpenGL相關工具 

  sudo apt-get install mesa-common-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev 

note:

       libgl1-mesa-de 對應 GL庫; 

       libglu1-mesa-dev對應GLU庫 TJe opengl utility  library; 

      freeglut3-dev 對應glut庫  

      mesa-common-de :This package includes the specifications for the Mesa-specific 

OpenGL extensions, the complete set of release release notes and the development header 

files common to all Mesa packages. 

2. example 上代碼:

#include <GL/glut.h>

#define window_width 640

#define window_height 480

// Main loop

void main_loop_function()

{

// Z angle

    static float angle;

// Clear color (screen)

// And depth (used internally to block obstructed objects)

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Load identity matrix

    glLoadIdentity();

// Multiply in translation matrix

    glTranslatef(0, 0, -10);

// Multiply in rotation matrix

    glRotatef(angle, 0, 0, 1);

// Render colored quad

    glBegin(GL_QUADS);

    glColor3ub(255, 000, 000);

    glVertex2f(-1, 1);

    glColor3ub(000, 255, 000);

    glVertex2f(1, 1);

    glColor3ub(000, 000, 255);

    glVertex2f(1, -1);

    glColor3ub(255, 255, 000);

    glVertex2f(-1, -1);

    glEnd();

// Swap buffers (color buffers, makes previous render visible)

    glutSwapBuffers();

// Increase angle to rotate

    angle += 0.25;

}

// Initialze OpenGL perspective matrix

void GL_Setup(int width, int height)

{

    glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION);

    glEnable(GL_DEPTH_TEST);

    gluPerspective(45, (float) width / height, .1, 100);

    glMatrixMode(GL_MODELVIEW);

}

// Initialize GLUT and start main loop

int main(int argc, char** argv)

{

    glutInit(&argc, argv);

    glutInitWindowSize(window_width, window_height);

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);

    glutCreateWindow("GLUT Example!!!");

    glutIdleFunc(main_loop_function);

    GL_Setup(window_width, window_height);

    glutMainLoop();

    return 0;

}

3. 編譯:

gcc example.cpp -o example -lglut -lGL -lGLU

4. 運作:

    ./example

========

linux下基于eclipse的opengl開發環境搭建

部落格分類: opengl

eclipseopenglubuntu 

轉自:http://www.cnblogs.com/lycheng/archive/2011/09/13/2174831.html 

1. 安裝OpenGL相關工具 

  sudo apt-get install mesa-common-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev 

       其中, 

       libgl1-mesa-de 對應 GL庫; 

       libglu1-mesa-dev對應GLU庫 TJe opengl utility  library; 

      freeglut3-dev 對應glut庫  

      mesa-common-de :This package includes the specifications for the Mesa-specific 

OpenGL extensions, the complete set of release release notes and the development header 

files common to all Mesa packages. 

2. 設定Eclipse 

        安裝eclipse   cdt插件 

        8.0.0 下載下傳位址: http://www.eclipse.org/cdt/downloads.php 

  Project -> properties -> C / C++ Build / Settings -> Tool Setting 

  然後選擇Cross G++ Linker 選擇 Libraries, 在Libraries 中插入: glut GL GLU 

                      在Libraries Search Paths 中插入: 

/usr/include/GL 

3. 測試代碼 example.cpp 

Java代碼  收藏代碼

#include <GL/glut.h>  

#define window_width 640  

#define window_height 480  

// Main loop  

void main_loop_function()  

{  

// Z angle  

    static float angle;  

// Clear color (screen)  

// And depth (used internally to block obstructed objects)  

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  

// Load identity matrix  

    glLoadIdentity();  

// Multiply in translation matrix  

    glTranslatef(0, 0, -10);  

// Multiply in rotation matrix  

    glRotatef(angle, 0, 0, 1);  

// Render colored quad  

    glBegin(GL_QUADS);  

    glColor3ub(255, 000, 000);  

    glVertex2f(-1, 1);  

    glColor3ub(000, 255, 000);  

    glVertex2f(1, 1);  

    glColor3ub(000, 000, 255);  

    glVertex2f(1, -1);  

    glColor3ub(255, 255, 000);  

    glVertex2f(-1, -1);  

    glEnd();  

// Swap buffers (color buffers, makes previous render visible)  

    glutSwapBuffers();  

// Increase angle to rotate  

    angle += 0.25;  

}  

// Initialze OpenGL perspective matrix  

void GL_Setup(int width, int height)  

{  

    glViewport(0, 0, width, height);  

    glMatrixMode(GL_PROJECTION);  

    glEnable(GL_DEPTH_TEST);  

    gluPerspective(45, (float) width / height, .1, 100);  

    glMatrixMode(GL_MODELVIEW);  

}  

// Initialize GLUT and start main loop  

int main(int argc, char** argv)  

{  

    glutInit(&argc, argv);  

    glutInitWindowSize(window_width, window_height);  

    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);  

    glutCreateWindow("GLUT Example!!!");  

    glutIdleFunc(main_loop_function);  

    GL_Setup(window_width, window_height);  

    glutMainLoop();  

    return 0;  

}  

  Run All 之後, 會顯示旋轉的方型, 如果不需要IDE, 則可用指令行編譯。 

4. 指令行編譯 

  gcc example.cpp -o example -lglut -lGL -lGLU 

  -o 表示輸出的檔案名 

  -l 表示連結的庫

========

繼續閱讀