Linux 3D 編程學習總結

Linux下應用OGRE開發3D


linux下應用OGRE開發3D的資料網上很是少。今天抽出時間整理一下。



大部份內容參考OGRE主頁http://www.ogre3d.org/。

首先依據主頁提示,咱們可以利用已有資源構建一個project。詳細過程例如如下:

第一步,準備工做,肯定你是在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

至此咱們的準備工做已完畢。接下來就要下載project源碼,而後編譯。

第二步,下載並編譯project:

下載project源代碼文件: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。這個文件時用來存放編譯project項目的。所有的編譯內容都將放在此文件夾下:


mkdir build


進入此文件夾:


cd build


由於此OGREproject採用的CMake工具鏈進行編譯。因此使用CMake命令開始編譯:


cmake ..


編譯器會依據CMakeLists.txt產生一個新的CMakeFile文件。接下來的編譯就和Make編譯同樣:


make -j2


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


最後一步:


sudo make install


所有的編譯工做已完畢。如下就是運行project,看看3D效果的,這裏仍是要說明一下。假設你的電腦不支


持3D那就鬱悶吧。因爲這直接影響3D的渲染。結果固然是沒辦法看到運行的結果。假設支持3D渲染就繼


續一下操做吧。


cd build (這步已經運行了,僅僅是告訴一下是在這個文件夾下)


cd bin


看到可運行文件了吧!php




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


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


,3D的。太棒了!假設願意,你可以改動源文件參數,又一次編譯。html


========
linux

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)參數來移動。其


實它還有第二個參數。就是依照自身座標軸移動仍是依照世界座標軸移動。ubuntu

這裏暫且不表。
  Vector3:表示3D的向量和點。3個參數分別表明了向量x,y,z。
  transform.Translate(Vector3(1,0,0));這句代碼的意思就是,讓被綁定的物體,也就是場景中的


立方體,向x軸的方向移動1個單位.
  Time.deltaTime:是一個時間增量,我想應該是這一幀的時間。像flash中的一秒30幀,每幀多少秒


之類的。在這個程序中它的值是0.016左右。本來移動一個單位,現在乘以0.016,那確定慢了。也就是


說,它的做用事實上就是減慢移動的速度。
  OK。
  本文project源代碼下載:
  免費下載地址在
  username與password都是
  詳細下載文件夾在 /pub/Android源代碼集錦/2011年/11月/Android+Unity3D簡單的物體運動/
========
數組

Linux下的OpenGL編程



    OpenGL是一個工業標準的三維計算機圖形軟件接口,它由SGI公司公佈並普遍應用於Unix、OS/二、


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窗體。響應、處理用戶的交互操做、簡單的彈出式菜單以及一些內置的畫圖和字體處


理功能。eclipse

GLUT和OpenGL同樣,可以移植於多種平臺。由於它良好的表現,現在它已經成爲Mesa公佈的標


準套件之中的一個。 
   還有一個很是好的開發工具包是FLTK(Fast Light Tool Kit),這是一個用C++編寫的圖形界面開發工


具。ide

和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_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); 

/*調用GLUT函數,繪製一個球*/ 
void display ( void ) 

glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glutSolidSphere (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 ( unsigned char key, int x, int y) 

/*按Esc鍵退出*/ 
switch (key) { 
case 27: 
exit ( 0 ); 
break; 




int main(int argc, char** argv) 

/* GLUT環境初始化*/ 
glutInit (&argc, argv); 
/* 顯示模式初始化 */ 
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); 
/* 定義窗體大小 */ 
glutInitWindowSize (300, 300); 
/* 定義窗體位置 */ 
glutInitWindowPosition (100, 100); 
/* 顯示窗體。窗體標題爲運行函數名 */ 
glutCreateWindow ( argv [ 0 ] ); 
/* 調用OpenGL初始化函數 */ 
init ( ); 
/* 註冊OpenGL畫圖函數 */ 
glutDisplayFunc ( display ); 
/* 註冊窗體大小改變時的響應函數 */ 
glutReshapeFunc ( reshape ); 
/* 註冊鍵盤響應函數 */ 
glutKeyboardFunc ( keyboard ); 
/* 進入GLUT消息循環。開始運行程序 */ 
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 一個更有表明性的樣例 
   如下咱們來看一個稍稍複雜的樣例。

咱們繪製一個平面,用戶的左鍵點擊被本身主動鏈接成一個多邊形


。當用戶點擊右鍵,會彈出菜單供用戶選擇。

用戶可以選擇清除、鑲嵌和退出。選擇清除將回到初始狀


態;選擇鑲嵌程序本身主動對多邊形進行三角剖分。選擇退出則終止程序。

(見圖2、圖三和圖四) 




       圖二                圖三               圖四 
/* tessdemo.c 多邊形鑲嵌的樣例,使用函數gluTessCallback和函數gluTessVertex。*/ 
#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; /* OpenGL窗體的大小 */ 
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 ]; 


/* 窗體大小改變時。設定width和height值,用於又一次繪製網格 */ 
void set_screen_wh ( GLsizei w, GLsizei h ) 
{ width = w; height = h; } 


void tesse ( void ) 
{ /* 鑲嵌函數,調用gluTess* 函數實現*/ } 


/* 對點擊鼠標左鍵事件的響應函數:更新當前多邊形頂點數組,並又一次繪製 */ 
void left_down ( int x1, int y1 ) 

GLfloat P[2]; 
GLuint point_cnt; 


/* 將GLUT窗體座標變換爲GL座標:前者(0,0)在左上角然後者在左下角*/ 
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 ) 

/* 將OpenGL的像素座標換爲背景的網格座標,背景網格爲邊長爲10的小正方形 */ 
x -= x%10; 
y -= y%10; 
switch ( button ) { 
case GLUT_LEFT_BUTTON: /* GLUT發現左鍵被點擊 */ 
if ( state == GLUT_DOWN ) { 
left_down( x, y ); 

break; 
case GLUT_MIDDLE_BUTTON: /* 中鍵被點擊 */ 
if ( state == GLUT_DOWN ) { 
middle_down( x, y ); 

break; 


/* OpenGL繪製函數,有兩種模式 */ 
void display( void ) 

GLuint i,j; 
GLuint point_cnt; 


glClear( GL_COLOR_BUFFER_BIT ); 
switch ( mode ) 

case DEFINE: /* 多邊形定義階段 */ 
/* 繪製網格。單個網格大小爲10像素,網格數目取決於OpenGL窗體大小 */ 
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: /* 繪製鑲嵌後的多邊形,顯示列表由函數tesse()給出 */ 
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 ); 



/* 菜單選項clear的響應函數,將所有變量清零,繪製模式設爲DEFINE */ 
void clear( void ) 

contour_cnt = 0; 
contours[0].point_cnt = 0; 
triangle_cnt = 0; 
mode = DEFINE; 
glDeleteLists( list_start, 2 ); 
list_start = 0; 



/* 菜單選項quit的響應函數,退出程序 */ 
void quit( void ) 

exit( 0 ); 



/* 定義菜單的響應函數 */ 
void menu_selected( int entry ) 

switch ( entry ) { 
case CLEAR: 
clear ( ); 
break; 
case TESSELATE: 
tesse ( ); 
break; 
case QUIT: 
quit ( ); 
break; 

/* 選擇菜單後重繪OpenGL窗體 */ 
glutPostRedisplay(); 



/* 定義快捷鍵響應函數 */ 
void key_pressed( unsigned char key, int x, int y ) 

/* 在此樣例中,不需要用代表鼠標位置的變量x和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編程提供了可能,但是做爲應用程序,它是遠


遠不夠的。它僅僅提供了原始、簡陋的控制和操做方式。沒有通常應用程序所需要的button、菜單欄、輸入


框等控件。其實,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 表示連接的庫 ========

相關文章
相關標籤/搜索