程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 開源項目之C++界面庫 GLUI

開源項目之C++界面庫 GLUI

編輯:C++入門知識

GLUI是一個C++界面庫,它提供了buttons, checkboxes, radio buttons, 等常用控件,以及OPENGL支持。GLUI界面系統依賴於GLUT來處理窗口、和鼠標管理等,而繪制部分采用OPENGL繪制。工程如圖:

這個庫需要用到第三方GLUT工具庫(已放到源碼包中),給出了六個實例,開源庫的原理就引用網上的資料了,接著介紹下實例是如何應用的。
窗體初始化
GLUI包含三個主要的類:
          GLUI_Master_Object
          GLUI
          GLUI_Control
其中有且只有一個全局的GLUI_Master_Object對象GLUI_Master.所有的GLUI窗口的創建都必須通過這個對象.這可以讓GLUI通過一個全局對象來追蹤所有的窗口,方便窗口的管理.這裡簡單介紹一下如何使用GLUI創建和控制窗口.這裡介紹的函數都屬於GLUI_Master_Object和GLUI類.必須注意,任何GLUI_Master_Object類的成員函數都必須通過全局對象GLUI_Master來調用,而任何GLUI類的成員函數都必須通過GLUI指針來調用,並在使用GLUI指針之前,GLUI指針必須獲取GLUI_Master.create_glui()的返回值.

如:

         float version = GLUI_Master.get_version();
         GLUI *glui_window = GLUI_Master.create_glui("GLUI");
         glui_window->add_StaticText("Hello World!");


初始化:首先介紹使用GLUI創建和設置窗口的一下函數.get_version:返回當前GLUI的版本.
用法:float GLUI_Master_Object::get_version(void) 返回值:GLUI版本號

create_glui:創建一個新的窗口. 用法:

GLUI *GLUI_Master_Object::create_glui(char *name, int flags = 0, int x = -1, int y = -1)

參數:
name:GLUI窗口的名字.
flags:初始化標記,如果沒有給出此參數則默認值為0,被定義為在當前版本中.
x,y:初始化窗口的坐標.此參數可以不給出,因為GLUI可以自動調整窗口大小以適應所有的控件.
返回值:
新的GLUI窗口的指針

create_glui_subwindow:
在已經存在的GLUT窗口中創建一個新的子窗口
用法:GLUI *GLUI_Master_Object::create_glui_subwindow(int window, int position)
參數:
window:新建GLUI窗口的父窗口(一個已經存在的GLUT窗口)的ID號.
position:子窗口相對於父窗口的位置,可以為以下的值:
           GLUI_SUBWINDOW_RIGHT
           GLUI_SUBWINDOW_LEFT
           GLUI_SUBWINDOW_TOP
           GLUI_SUBWINDOW_BOTTOM
           (注:可以在同一個位置創建任意個數的子窗口,多個相同位置的子窗口會簡單的相互疊加,如:兩個子窗口都使用了GLUI_SUBWINDOW_TOP參數,這兩個子窗口都會定位在父窗口之上,同時,第一個子窗口也會覆蓋在第二個子窗口之上.)
返回值:
新建的子窗口的指針.

set_glutIdleFunc:
為GLUI注冊一個標准的GLUT空閒回調函數.當GLUI處於空閒時,就會調用該注冊的函數.GLUI會截獲空閒事件用於自身過程處理,然後才把該事件送給GLUT應用程序.需要注意的是,在注冊的空閒回調函數中,當前窗口並沒有被定義,所以,如果要在空閒回調函數中向GLUT窗口獲取或發送redisplay事件,則必須明確的在回調函數中指定當前窗口.
        如:
                 int main_window;
                 void myGlutIdle(void)//被注冊的空閒回調函數
                 {
                    if(glutGetWindow() != main_window)
                    {
                       glutSetWindow(main_window);
                    }
                    glutPostRedisplay();
                 }
用法:
void GLUI_Master_Object::set_glutIdleFunc(void (*f)(void))
參數:
f(void):被注冊的空閒回調函數.

set_glutReshapeFunc
set_glutKeyboardFunc
set_glutMouseFunc
set_glutSpecialFunc
用法:
void GLUT_Master_Object::set_glutReshapeFunc(void (*f)(int width, int height));
void GLUT_Master_Object::set_glutKeyboardFunc(void (*f)(unsigned char key, int x, int y));
void GLUT_Master_Object::set_glutMouseFunc(void (*f)(int button, int state, int x,int y));
void GLUI_Master_Object::set_glutSpecialFunc(void (*f)(int key, int x, int y));
參數:
詳見glut函數詳解(9)--回調API
(這裡的回調函數與GLUT中對應的回調函數用法相似)

set_main_gfx_window:
將一個GLUT窗口與一個GLUI窗口捆綁,當這個GLUI窗口中的一個控件的值發生改變,則該GLUT窗口將會被重繪.
用法:
void GLUI::set_main_gfx_window(int window_id);
參數:
window_id:被綁定的GLUT窗口ID,此ID號可在GLUT窗口被創建時獲得(即glutCreateWindow()的返回值),或通過glutGetWindow()的返回值獲得.


窗體視口管理
視口管理:這裡介紹使用GLUI結合OpenGL時,如何管理視口.get_viewport_area:
確定當前窗口可繪區域的位置和尺寸.這個函數一般在使用到GLUI子窗口時使用,因為子窗口必然會占據父窗口的一小塊區域,而繪制在父窗口上的圖形並不希望被子窗口覆蓋,所以可以通過此函數調整視口的大小.此函數應該在GLUT的reshape callback function中調用.
用法:void GLUI_Master_Object::get_viewport_area(int *x, int *y, int *w, int *h);
參數:
x,y,w,h:該函數被調用後,就可獲得當前窗口可繪區域的左上角坐標及其寬度和高度,然後可以根據這些數據通過調用glViewport()設置視口區域.
auto_set_viewport:
自動為當前窗口設置尺寸合適的視口
用法:
void GLUI_Master_Object::auto_set_viewport(void);
例子:

int x, y, w, h;
GLUI_Master.get_viewport_area(&x, &y, &w, &h);
glViewport(x, y, w, h);
以上三句的功能與下面一句等價.
GLUI_Master.auto_set_viewport();

窗體管理
窗口管理:當窗體創建之後可以通過下列函數對窗體進行管理
/********************************************************************/

get_glut_window_id:
返回一個GLUI窗口的窗口ID
用法:int GLUI::get_glut_window_id(void);
返回值:GLUI窗口的ID號

enable,disable:
使GLUI窗口可用或不可用,當一個GLUI窗口不可用時,其上的所有控件都不可用.
用法:
void GLUI::enable(void);
void GLUI::disable(void);

hide:
使GLUI窗口或子窗口隱藏.一個被隱藏的窗口或子窗口不能接受任何用戶輸入.
用法:void GLUI::hide(void);

show:
使一個被隱藏的窗口或子窗口可見.
用法:void GLUI::show(void);

close:
銷毀一個GLUI窗口或子窗口.
用法:
void GLUI::close(void);

close_all:
銷毀所有的GLUI窗口和子窗口.此函數應該被全局對象所調用如:GLUI_Master.close_all();
用法:void GLUI_Master_Object::close_all(void);

sync_live:
變量可以與控件相關聯,該函數可以使一個GLUI窗口上的所有控件和與這些控件相關聯的變量保持同步,也即:讀取變量的值,然後根據該值設置與其相關聯的控件,使該值在控件上反映出來
用法:void GLUI::sync_live(void);

sync_live_all:
使所有GLUI窗口上的所有控件與與其相關聯的變量保持同步,這個函數必須通過全局對象調用,如:GLUI_Master.sync_live_all();
用法:void GLUI_Master_Object::sync_live_all(void);

控件
    GLUI中,所有的控件都是源於GLUI_Control類,所以,他們的操作都非常相似.我們有兩種方法創建控件:一種是使用add_control()直接將控件放在窗口之上,另一種是使用add_control_to_panel()將控件置於panel之內. panel是一個可以內置其他控件的容器,panel也可以置於另一個panel之內.這裡介紹的函數可以被許多控件調用,用來改變其屬性,因此這裡介紹的函數可以稱為公共函數.
set_name:
為button,checkbox等控件設置名字.
用法:
void GLUI_Control::set_name(char *name);
參數:
name:控件的名字(即:在控件上或控件旁顯示的文字)
set_w, set_h:
設置控件的最小寬度或高度
用法:
void GLUI_Control::set_w(int new_size);
void GLUI_Control::set_h(int new_size);
參數:
new_size:控件的最小寬度或高度.
get, set:
獲取或設置控件的當前值.
用法:
int GLUI_Control::get_int_val(void);
float GLUI_Control::get_float_val(void);
void GLUI_Control::get_float_array_val(float *float_array_ptr);
char *GLUI_Control::get_text(void);
void GLUI_Control::set_int_val(int int_val);
void GLUI_Control::set_float_val(float float_val);
void GLUI_Control::set_float_array_val(float *float_array_val);
void GLUI_Control::set_text(char *text);
(根據控件對輸入輸出數據值類型的要求,選取相應的函數)
disable, enable:
使控件可用或不可用,radio group不可用時,其中的button也不可用,panel不可用時,其中的所有控件都不可用.
用法:
void GLUI_Control::enable(void);
void GLUI_Control::disable(void);
set_alignment:
設置控件的對齊方式(居左,居中,居右)
用法:
void GLUI_Control::set_alignment(int align);
參數:
align:對齊方式.可選下面之一:
       GLUI_ALIGN_CENTER
       GLUI_ALIGN_RIGHT
       GLUI_ALIGN_LEFT

Panels:一個容器,可以內置其他控件,也可以內置另一個panel.
add_panel:
在GLUI窗口上新建一個panel控件.
用法:GLUI_Panel *GLUI::add_panel(char *name, int tyep = GLUI_PANEL_EMBOSSED);

add_panel_to_panel:
在另一個panel之內新建一個panel控件.
用法:GLUI_Panel *GLUI::add_panel_to_panel(GLUI_Panel *panel, char *name, int type = GLUI_PANEL_EMBOSSED);

參數:

name:panel控件的名字(可以為空,如若指定了名字,會在panel的左上角顯示).

type:panel的樣式.
       GLUI_PANEL_EMBOSSED:用內嵌的線條畫一個矩形框(默認值).
       GLUI_PANEL_RAISED:用外凸的線條畫一個矩形框,不顯示名字.
       GLUI_PANEL_NONE:不繪制矩形框,只用來將控件組織成一個控件組.
panel:指向另一個panel控件的指針.新建的panel控件將會置於該panel之中.

返回值:新建的panel控件的指針.

Rollouts:類似於panel也是一個容器,功能上可以與panel互相替代,不同之處在於該控件可以被折疊起來,此時其內置的控件不可見,只有當其展開後,內置控件才可見.

add_rollout:
在GLUI窗口中新建rollout控件.
用法:GLUI_Rollout *GLUI::add_rollout(char *name, int open = true);

add_rollout_to_panel:
在另一個已經存在的rollout或panel中新建一個rollout控件.
用法:GLUI_Rollout *GLUI::add_rollout_to_panel(GLUI_Panel *panel, char *name, int open = true);

參數:
name:控件的名字.
open:如果為true,則rollout初始設置為打開;如果為false,則初始設置為閉合.
panel:指向另一個panel或rollout控件的指針.新建的rollout控件將會置於該panel或rollout之中.

返回值:
新建rollout控件的指針.

Columns:控件在GLUI窗口中的布局是按照控件定義的順序自上而下放置的,在豎直方向上形成一個控件列,而column則會開辟一個新的控件列(即在舊的控件列的右側新建一個新的控件列),其後所定義的控件將置於該新建的控件列中(即在新的控件列中自上而下布局),直至新的控件列被創建.

add_column:
在GLUI窗口上新建column.
用法:void GLUI::add_column(int draw_bar = true);

add_column_to_panel:
在panel中新建column.
用法:void GLUI::add_column_to_panel(GLUI_Panel *panel, int draw_bar = true);

參數:
draw_bar:如果為true,則在新建控件列時,會繪制一條豎線將其與原先的控件列區分開;如為false,則只創建控件列,不繪制豎線.
panel:指向一個panel控件的指針.新建的column控件將會置於該panel之中.


Buttons:按鈕

add_button:
在GLUI窗口上直接新建按鈕.
用法:GLUI_Button *GLUI::add_button(char *name, int id = -1, GLUI_Update_CB callback = NULL);

add_button_to_panel:在一個已經存在的panel中創建按鈕.
用法:GLUI_Button *GLUI::add_button_to_panel(GLUI_Panel *panel,char *name,int id = -1,GLUI_Update_CB callback = NULL);

參數:
name:按鈕的名字,即在按鈕上顯示的文字.
id:按鈕的ID值.如果callback被定義了,則當callback被調用時,id值會作為參數傳遞給callback.
callback:接受一個整形參數的callback函數.當按鈕被觸發時,它會被調用.
panel:指向一個panel控件的指針.新建的button控件將會置於該panel之中.

返回值:
新建的按鈕控件的指針.

Checkboxes:復選框

add_checkbox:
在GLUI窗口上直接創建新的checkbox.
用法:GLUI_Checkbox *GLUI::add_checkbox(char *name, int *live_var = NULL, int id = -1,GLUI_Update_CB callback = NULL);

add_checkbox_to_panel:
在已經存在的panel中創建新的checkbox.
用法:GLUI_Checkbox *GLUI::add_check_to_panel(GLUI_Panel *panel, char *name, int *live_var = NULL, int id = -1, GLUI_Update_CB callback = NULL);

參數:
name:checkbox的名字.
live_var:與控件checkbox相關聯的整形指針,當checkbox控件狀態發生變化時,該整形值會自動更新.
id:復選框的ID值.如果callback被定義了,則當callback被調用時,id值會作為參數傳遞給callback.
callback:接受一個整形參數的callback函數.當按復選框觸發時,它會被調用.
panel:指向一個panel控件的指針.新建的checkbox控件將會置於該panel之中.

返回值:新建的checkbox控件的指針.


example1 效果如圖:

主要的源碼:

[cpp]
int main(int argc, char* argv[]) 

  /****************************************/ 
  /*   Initialize GLUT and create window  */ 
  /****************************************/ 
  //初始化操作 
  glutInit(&argc, argv); 
  glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 
  glutInitWindowPosition( 50, 50 ); 
  glutInitWindowSize( 300, 300 ); 
  
  main_window = glutCreateWindow( "GLUI Example 1" ); 
  glutDisplayFunc( myGlutDisplay ); 
  glutReshapeFunc( myGlutReshape );   
 
  /****************************************/ 
  /*       Set up OpenGL lights           */ 
  /****************************************/ 
 
  GLfloat light0_ambient[] =  {0.1f, 0.1f, 0.3f, 1.0f}; 
  GLfloat light0_diffuse[] =  {.6f, .6f, 1.0f, 1.0f}; 
  GLfloat light0_position[] = {1.0f, 1.0f, 1.0f, 0.0f}; 
 
  glEnable(GL_LIGHTING); 
  glEnable(GL_LIGHT0); 
  glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); 
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); 
  glLightfv(GL_LIGHT0, GL_POSITION, light0_position); 
 
  /****************************************/ 
  /*          Enable z-buferring          */ 
  /****************************************/ 
 
  glEnable(GL_DEPTH_TEST); 
 
 
  /****************************************/ 
  /*         Here's the GLUI code         */ 
  /****************************************/ 
   
  GLUI *glui = GLUI_Master.create_glui( "GLUI" ); 
  new GLUI_Checkbox( glui, "Wireframe", &wireframe ); 
  (new GLUI_Spinner( glui, "Segments:", &segments )) 
    ->set_int_limits( 3, 60 );  
    
  glui->set_main_gfx_window( main_window ); 
 
  /* We register the idle callback with GLUI, *not* with GLUT */ 
  GLUI_Master.set_glutIdleFunc( myGlutIdle );  
 
  glutMainLoop(); 
 
  return EXIT_SUCCESS; 

example2 效果如圖:

主要代碼:
[cpp] 
void myGlutKeyboard(unsigned char Key, int x, int y) 

  switch(Key) 
  { 
    // A few keys here to test the sync_live capability. 
  case 'o': 
    // Cycle through object types 
    ++obj %= 3; 
    GLUI_Master.sync_live_all(); 
    break; 
  case 'w': 
    // Toggle wireframe mode 
    wireframe = !wireframe; 
    GLUI_Master.sync_live_all(); 
    break; 
  case 27:  
  case 'q': 
    exit(0); 
    break; 
  }; 
  glutPostRedisplay(); 

 
 
/***************************************** myGlutMenu() ***********/ 
 
void myGlutMenu( int value ) 

  myGlutKeyboard( value, 0, 0 ); 

 
/***************************************** myGlutMouse() **********/ 
 
void myGlutMouse(int button, int button_state, int x, int y ) 

  if ( button == GLUT_LEFT_BUTTON && button_state == GLUT_DOWN ) { 
    last_x = x; 
    last_y = y; 
  } 

 
 
/***************************************** myGlutMotion() **********/ 
 
void myGlutMotion(int x, int y ) 

  rotationX += (float) (y - last_y); 
  rotationY += (float) (x - last_x); 
 
  last_x = x; 
  last_y = y; 
 
  glutPostRedisplay();  

 
/**************************************** myGlutReshape() *************/ 
 
void myGlutReshape( int x, int y ) 

  xy_aspect = (float)x / (float)y; 
  glViewport( 0, 0, x, y ); 
 
  glutPostRedisplay(); 

 
/***************************************** myGlutDisplay() *****************/ 
 
void myGlutDisplay( void ) 

  glClearColor( .9f, .9f, .9f, 1.0f ); 
  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
 
  glMatrixMode( GL_PROJECTION ); 
  glLoadIdentity(); 
  glFrustum( -xy_aspect*.08, xy_aspect*.08, -.08, .08, .1, 15.0 ); 
 
  glMatrixMode( GL_MODELVIEW ); 
  glLoadIdentity(); 
  glTranslatef( 0.0f, 0.0f, -1.6f ); 
  glRotatef( rotationY, 0.0, 1.0, 0.0 ); 
  glRotatef( rotationX, 1.0, 0.0, 0.0 ); 
 
  /*** Now we render object, using the variables 'obj', 'segments', and
    'wireframe'.  These are _live_ variables, which are transparently 
    updated by GLUI ***/ 
   
  if ( obj == 0 ) { 
    if ( wireframe )       
      glutWireSphere( .6, segments, segments ); 
    else                   
      glutSolidSphere( .6, segments, segments ); 
  } 
  else if ( obj == 1 ) { 
    if ( wireframe ) 
      glutWireTorus( .2,.5,16,segments ); 
    else 
      glutSolidTorus( .2,.5,16,segments ); 
  } 
  else if ( obj == 2 ) { 
    if ( wireframe ) 
      glutWireTeapot( .5 ); 
    else 
      glutSolidTeapot( .5 ); 
  } 
 
  glDisable( GL_LIGHTING );  /* Disable lighting while we render text */ 
  glMatrixMode( GL_PROJECTION ); 
  glLoadIdentity(); 
  gluOrtho2D( 0.0, 100.0, 0.0, 100.0  ); 
  glMatrixMode( GL_MODELVIEW ); 
  glLoadIdentity(); 
  glColor3ub( 0, 0, 0 ); 
  glRasterPos2i( 10, 10 ); 
 
  //  printf( "text: %s\n", text ); 
 
  /*** Render the live character array 'text' ***/ 
  for (unsigned int i=0; i<text.length(); ++i) 
    glutBitmapCharacter( GLUT_BITMAP_HELVETICA_18, text[i] ); 
 
  glEnable( GL_LIGHTING ); 
 
  glutSwapBuffers();  

 
 
/**************************************** main() ********************/ 
 
int main(int argc, char* argv[]) 

  /****************************************/ 
  /*   Initialize GLUT and create window  */ 
  /****************************************/ 
 
  glutInit(&argc, argv); 
  glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 
  glutInitWindowPosition( 50, 50 ); 
  glutInitWindowSize( 300, 300 ); 
  
  main_window = glutCreateWindow( "GLUI Example 2" ); 
  glutDisplayFunc( myGlutDisplay ); 
  glutReshapeFunc( myGlutReshape );   
  glutKeyboardFunc( myGlutKeyboard ); 
  glutMotionFunc( myGlutMotion ); 
  glutMouseFunc( myGlutMouse ); 
 
  /****************************************/ 
  /*       Set up OpenGL lights           */ 
  /****************************************/ 
 
  GLfloat light0_ambient[] =  {0.1f, 0.1f, 0.3f, 1.0f}; 
  GLfloat light0_diffuse[] =  {.6f, .6f, 1.0f, 1.0f}; 
  GLfloat light0_position[] = {1.0f, 1.0f, 1.0f, 0.0f}; 
 
  glEnable(GL_LIGHTING); 
  glEnable(GL_LIGHT0); 
  glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); 
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); 
  glLightfv(GL_LIGHT0, GL_POSITION, light0_position); 
 
  /****************************************/ 
  /*          Enable z-buferring          */ 
  /****************************************/ 
 
  glEnable(GL_DEPTH_TEST); 
 
  /****************************************/ 
  /*         Here's the GLUI code         */ 
  /****************************************/ 
 
  GLUI *glui = GLUI_Master.create_glui( "GLUI", 0, 400, 50 ); /* name, flags,
                                 x, and y */ 
  new GLUI_StaticText( glui, "GLUI Example 2" ); 
  new GLUI_Separator( glui ); 
  checkbox = new GLUI_Checkbox( glui, "Wireframe", &wireframe, 1, control_cb ); 
  spinner  = new GLUI_Spinner( glui, "Segments:", &segments, 2, control_cb ); 
  spinner->set_int_limits( 3, 60 ); 
  edittext = new GLUI_EditText( glui, "Text:", text, 3, control_cb ); 
  GLUI_Panel *obj_panel = new GLUI_Panel( glui, "Object Type" ); 
  radio = new GLUI_RadioGroup( obj_panel,&obj,4,control_cb ); 
  new GLUI_RadioButton( radio, "Sphere" ); 
  new GLUI_RadioButton( radio, "Torus" ); 
  new GLUI_RadioButton( radio, "Teapot" ); 
  new GLUI_Button( glui, "Quit", 0,(GLUI_Update_CB)exit ); 
  
  glui->set_main_gfx_window( main_window ); 
 
  /* We register the idle callback with GLUI, *not* with GLUT */ 
  //GLUI_Master.set_glutIdleFunc( myGlutIdle ); 
  GLUI_Master.set_glutIdleFunc( NULL ); 
 
  glutMainLoop(); 
 
  return EXIT_SUCCESS; 

example3 效果如圖:

主要源碼:
[cpp] 
int main(int argc, char* argv[]) 

  /****************************************/ 
  /*   Initialize GLUT and create window  */ 
  /****************************************/ 
 
  glutInit(&argc, argv); 
  glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 
  glutInitWindowPosition( 50, 50 ); 
  glutInitWindowSize( 300, 300 ); 
  
  main_window = glutCreateWindow( "GLUI Example 3" ); 
  glutDisplayFunc( myGlutDisplay ); 
  glutReshapeFunc( myGlutReshape );   
  glutKeyboardFunc( myGlutKeyboard ); 
  glutMotionFunc( myGlutMotion ); 
  glutMouseFunc( myGlutMouse ); 
 
  /****************************************/ 
  /*       Set up OpenGL lights           */ 
  /****************************************/ 
 
  glEnable(GL_LIGHTING); 
  glEnable( GL_NORMALIZE ); 
 
  glEnable(GL_LIGHT0); 
  glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient); 
  glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse); 
  glLightfv(GL_LIGHT0, GL_POSITION, light0_position); 
 
  glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient); 
  glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); 
  glLightfv(GL_LIGHT1, GL_POSITION, light1_position); 
 
  /****************************************/ 
  /*          Enable z-buferring          */ 
  /****************************************/ 
 
  glEnable(GL_DEPTH_TEST); 
 
  /****************************************/ 
  /*         Here's the GLUI code         */ 
  /****************************************/ 
 
  printf( "GLUI version: %3.2f\n", GLUI_Master.get_version() ); 
 
  glui = GLUI_Master.create_glui( "GLUI", 0, 400, 50 ); /* name, flags,
                               x, and y */ 
  new GLUI_StaticText( glui, "GLUI Example 3" );  
  obj_panel = new GLUI_Panel(glui, "Object" ); 
 
  /***** Control for the object type *****/ 
 
  GLUI_Panel *type_panel = new GLUI_Panel( obj_panel, "Type" ); 
  radio = new GLUI_RadioGroup(type_panel,&obj_type,4,control_cb); 
  new GLUI_RadioButton( radio, "Sphere" ); 
  new GLUI_RadioButton( radio, "Torus" ); 
  new GLUI_RadioButton( radio, "Teapot" ); 
 
  checkbox =  
    new GLUI_Checkbox(obj_panel, "Wireframe", &wireframe, 1, control_cb ); 
  spinner = 
    new GLUI_Spinner( obj_panel, "Segments:", &segments); 
  spinner->set_int_limits( 3, 60 ); 
  spinner->set_alignment( GLUI_ALIGN_RIGHT ); 
 
  scale_spinner =  
    new GLUI_Spinner( obj_panel, "Scale:", &scale); 
  scale_spinner->set_float_limits( .2f, 4.0 ); 
  scale_spinner->set_alignment( GLUI_ALIGN_RIGHT ); 
 
  new GLUI_Separator( obj_panel ); 
  edittext = new GLUI_EditText( obj_panel, "Text:", text ); 
  edittext->set_w( 150 ); 
 
  /******** Add some controls for lights ********/ 
 
  GLUI_Panel *light0 = new GLUI_Panel( glui, "Light 1" ); 
  GLUI_Panel *light1 = new GLUI_Panel( glui, "Light 2" ); 
 
  new GLUI_Checkbox( light0, "Enabled", &light0_enabled,  
                     LIGHT0_ENABLED_ID, control_cb ); 
  light0_spinner =  
    new GLUI_Spinner( light0, "Intensity:", 
                      &light0_intensity, LIGHT0_INTENSITY_ID, 
                      control_cb ); 
  light0_spinner->set_float_limits( 0.0, 1.0 ); 
 
  new GLUI_Checkbox( light1, "Enabled", &light1_enabled, 
                     LIGHT1_ENABLED_ID, control_cb ); 
  light1_spinner =  
    new GLUI_Spinner( light1, "Intensity:",  
                      &light1_intensity, LIGHT1_INTENSITY_ID, 
                      control_cb ); 
  light1_spinner->set_float_limits( 0.0, 1.0 ); 
  light1_spinner->disable();   /* Disable this light initially */ 
 
  /****** Add a grayed-out counter *****/ 
   
  GLUI_EditText *counter_edittext =  
    new GLUI_EditText( glui, "Count:", &counter ); 
  counter_edittext->disable(); 
 
  /****** Button to Open Command Line Window ******/ 
  open_console_btn =  
    new GLUI_Button(glui, "Open Console", OPEN_CONSOLE_ID, pointer_cb); 
 
  /****** A 'quit' button *****/ 
 
  new GLUI_Button(glui, "Quit", 0,(GLUI_Update_CB)exit ); 
 
  /**** Link windows to GLUI, and register idle callback ******/ 
   
  glui->set_main_gfx_window( main_window ); 
 
  /* We register the idle callback with GLUI, not with GLUT */ 
  GLUI_Master.set_glutIdleFunc( myGlutIdle ); 
 
  /**** Regular GLUT main loop ****/   
  glutMainLoop(); 
 
  return EXIT_SUCCESS; 

……
example6 效果如圖:

主要的代碼:
[cpp] 
int main(int argc, char* argv[]) 

  glutInit(&argc, argv); 
 
  GLUI *edit = GLUI_Master.create_glui("Help on GLUI Widgets", 0); 
  main_window = edit->get_glut_window_id(); 
  GLUI_Panel *ep = new GLUI_Panel(edit,"",true); 
  new GLUI_StaticText(ep,"Widget Information:"); 
  hah = new GLUI_List(ep,true,1,control_cb); 
  hah->add_item(0,"GLUI 2.3"); 
  hah->add_item(1,"TextBox"); 
  hah->add_item(2,"Scrollbar"); 
  hah->add_item(3,"GLUI_String"); 
  hah->add_item(4,"CommandLine"); 
  hah->add_item(5,"Tree"); 
  hah->add_item(6,"List"); 
  hah->add_item(7,"FileBrowser"); 
  new GLUI_StaticText(ep,"Open Text File:"); 
  fb = new GLUI_FileBrowser(ep, "", false, 7, control_cb); 
  fb->set_h(180); 
  hah->set_h(180); 
  new GLUI_Column(ep,false);  
 
  moo = new GLUI_TextBox(ep,true); 
  moo->set_text(general); 
  moo->set_h(400); 
  moo->set_w(410); 
  moo->disable(); 
  enable_textbox=0; 
  new GLUI_Checkbox(ep, "Enable text box:",&enable_textbox,12,control_cb); 
 
  tree = GLUI_Master.create_glui("Tree Test", 0); 
  ep = new GLUI_Panel(tree, "Tree Controls"); 
  bedit = new GLUI_EditText(ep, "New Branch Name:"); 
  new GLUI_Checkbox(ep, "Display Numbers", &num_display); 
  new GLUI_StaticText(ep, "Number format:"); 
  GLUI_RadioGroup *rg = new GLUI_RadioGroup(ep, &num_format); 
  new GLUI_RadioButton(rg, "Level Only"); 
  new GLUI_RadioButton(rg, "Hierarchal"); 
  new GLUI_Button(ep, "Update Format", 11, control_cb);  
  new GLUI_Column(ep); 
  new GLUI_Button(ep, "Add Branch", 2, control_cb);  
  new GLUI_Button(ep, "Del Branch", 3, control_cb); 
  new GLUI_Button(ep, "Up Branch", 4, control_cb);  
  new GLUI_Button(ep, "Goto Root", 5, control_cb); 
  new GLUI_Column(ep); 
  new GLUI_Button(ep, "Descend to Leaf", 6, control_cb);  
  new GLUI_Button(ep, "Next Branch", 8, control_cb);  
  new GLUI_Button(ep, "Expand All", 9, control_cb);  
  new GLUI_Button(ep, "Collapse All", 10, control_cb);  
  tp = new GLUI_TreePanel(tree,"Tree Test"); 
  tp->set_format(GLUI_TREEPANEL_ALTERNATE_COLOR |  
                 GLUI_TREEPANEL_CONNECT_CHILDREN_ONLY | 
                 GLUI_TREEPANEL_DISPLAY_HIERARCHY |  
                 GLUI_TREEPANEL_HIERARCHY_NUMERICDOT); 
  tp->set_level_color(1,1,1); 
  tp->ab("foo you"); 
  tree->hide(); 
  
  edit->set_main_gfx_window(main_window);  
  tree->set_main_gfx_window(main_window);  
 
  glutMainLoop(); 
  return 0; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved