glui_rotation.cpp
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:13k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /****************************************************************************
  2.   
  3.   GLUI User Interface Toolkit
  4.   ---------------------------
  5.      glui_rotation - GLUI_Rotation control class
  6.           --------------------------------------------------
  7.   Copyright (c) 1998 Paul Rademacher
  8.   WWW:    http://sourceforge.net/projects/glui/
  9.   Forums: http://sourceforge.net/forum/?group_id=92496
  10.   This library is free software; you can redistribute it and/or
  11.   modify it under the terms of the GNU Lesser General Public
  12.   License as published by the Free Software Foundation; either
  13.   version 2.1 of the License, or (at your option) any later version.
  14.   This library is distributed in the hope that it will be useful,
  15.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.   Lesser General Public License for more details.
  18.   You should have received a copy of the GNU Lesser General Public
  19.   License along with this library; if not, write to the Free Software
  20.   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  21. *****************************************************************************/
  22. #include "GL/glui.h"
  23. #include "arcball.h"
  24. #include "algebra3.h"
  25. /*************************** GLUI_Rotation::iaction_mouse_down_handler() ***/
  26. int    GLUI_Rotation::iaction_mouse_down_handler( int local_x, int local_y )
  27. {
  28.   copy_float_array_to_ball();
  29.   init_ball();
  30.   local_y = (int) floor(2.0 * ball->center[1] - local_y);
  31.   ball->mouse_down( local_x, local_y );
  32.   /* printf( "%d %d - %f %fn", local_x, local_y, ball->center[0], ball->center[1] );              */
  33.   copy_ball_to_float_array();
  34.   spinning = false;
  35.   return false;
  36. }
  37. /*********************** GLUI_Rotation::iaction_mouse_up_handler() **********/
  38. int    GLUI_Rotation::iaction_mouse_up_handler( int local_x, int local_y, 
  39. bool inside )
  40. {
  41.   copy_float_array_to_ball();
  42.   ball->mouse_up();
  43.   return false;
  44. }
  45. /******************* GLUI_Rotation::iaction_mouse_held_down_handler() ******/
  46. int    GLUI_Rotation::iaction_mouse_held_down_handler( int local_x, int local_y,
  47.        bool inside)
  48. {  
  49.   if ( NOT glui )
  50.     return 0;
  51.   copy_float_array_to_ball();
  52.   local_y = (int) floor(2.0 * ball->center[1] - local_y);
  53.   /* printf( "%d %dn", local_x, local_y );              */
  54.   ball->mouse_motion( local_x, local_y, 0, 
  55.      (glui->curr_modifiers & GLUT_ACTIVE_ALT) != 0, 
  56.      (glui->curr_modifiers & GLUT_ACTIVE_CTRL) != 0 );
  57.  
  58.   copy_ball_to_float_array();
  59.   if ( can_spin )
  60.     spinning = true;
  61.   return false;
  62. }
  63. /******************** GLUI_Rotation::iaction_draw_active_area_persp() **************/
  64. void    GLUI_Rotation::iaction_draw_active_area_persp( void )
  65. {
  66.   /********** arcball *******/
  67.   copy_float_array_to_ball();
  68.   setup_texture();
  69.   setup_lights();
  70.   glEnable(GL_CULL_FACE );
  71.   glMatrixMode( GL_MODELVIEW );
  72.   glPushMatrix();
  73.   mat4 tmp_rot = *ball->rot_ptr;
  74.   glMultMatrixf( (float*) &tmp_rot[0][0] ); 
  75.   /*** Draw the checkered box ***/
  76.   /*glDisable( GL_TEXTURE_2D );              */
  77.   draw_ball(1.35); // 1.96 );
  78.   glPopMatrix();
  79.   glBindTexture(GL_TEXTURE_2D,0); /* unhook our checkerboard texture */
  80.   glDisable( GL_TEXTURE_2D );
  81.   glDisable( GL_LIGHTING );
  82.   glDisable( GL_CULL_FACE );
  83. }
  84. /******************** GLUI_Rotation::iaction_draw_active_area_ortho() **********/
  85. void    GLUI_Rotation::iaction_draw_active_area_ortho( void )
  86. {
  87.   float radius;
  88.   radius = (float)(h-22)/2.0;  /*MIN((float)w/2.0, (float)h/2.0);  */
  89.   /********* Draw emboss circles around arcball control *********/
  90.   int k;     
  91.   glLineWidth( 1.0 );
  92.   glBegin( GL_LINE_LOOP);
  93.   for( k=0; k<60; k++ ) {
  94.     float phi = 2*M_PI*(float)k/60.0;
  95.     vec2 p( cos(phi) * (2.0 + radius), sin(phi) * (2.0 + radius));
  96.     if ( p[1] < -p[0] )  glColor3ub( 128,128,128 );
  97.     else glColor3ub( 255,255,255 );
  98.     glVertex2fv((float*)&p[0]);
  99.   }
  100.   glEnd();
  101.   glBegin( GL_LINE_LOOP);
  102.   for( k=0; k<60; k++ ) {
  103.     float phi = 2*M_PI*(float)k/60.0;
  104.     vec2 p( cos(phi) * (1.0 + radius), sin(phi) * (1.0 + radius));
  105.     if ( enabled ) {
  106.       if ( p[1] < -p[0] )  glColor3ub( 0,0,0);
  107.       else glColor3ub( 192,192,192);
  108.     }
  109.     else
  110.     {
  111.       if ( p[1] < -p[0] )  glColor3ub( 180,180,180);
  112.       else glColor3ub( 192,192,192);
  113.     }
  114.     glVertex2fv((float*)&p[0]);
  115.   }
  116.   glEnd();
  117. }
  118. /******************************** GLUI_Rotation::iaction_dump() **********/
  119. void     GLUI_Rotation::iaction_dump( FILE *output )
  120. {
  121. }
  122. /******************** GLUI_Rotation::iaction_special_handler() **********/
  123. int    GLUI_Rotation::iaction_special_handler( int key,int modifiers )
  124. {
  125.   return false;
  126. }
  127. /********************************** GLUI_Rotation::init_ball() **********/
  128. void  GLUI_Rotation::init_ball( void )
  129. {
  130.   /*printf( "%f %f %f", float( MIN(w/2,h/2)), (float) w/2, (float) h/2 );              */
  131.   ball->set_params( vec2( (float)(w/2), (float)((h-18)/2)), 
  132.    (float) 2.0*(h-18) );
  133.   /*ball->set_damping( .05 );              */
  134.   /*float( MIN(w/2,h/2))*2.0  );              */
  135.   /* ball->reset_mouse();              */
  136. }
  137. /****************************** GLUI_Rotation::setup_texture() *********/
  138. void GLUI_Rotation::setup_texture( void )
  139. {
  140.   static GLuint tex=0u;
  141.   GLenum t=GL_TEXTURE_2D;
  142.   glEnable(t);
  143.   glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
  144.   glColor3f( 1.0, 1.0, 1.0 );
  145.   if (tex!=0u) {
  146.   /* (OSL 2006/06) Just use glBindTexture to avoid having to re-upload the whole checkerboard every frame. */
  147.     glBindTexture(t,tex);
  148.     return;
  149.   } /* Else need to make a new checkerboard texture */
  150.   glGenTextures(1,&tex);
  151.   glBindTexture(t,tex);
  152.   glEnable(t);
  153.   
  154.   unsigned int i, j;
  155.   int dark, light;   /*** Dark and light colors for ball checkerboard  ***/
  156. /* Note: you can change the number of checkers across there sphere in draw_ball */
  157. #define CHECKBOARD_SIZE 64 /* pixels across whole texture */
  158. #define CHECKBOARD_REPEAT 32u /* pixels across one black/white sector */
  159.   unsigned char texture_image[CHECKBOARD_SIZE] [CHECKBOARD_SIZE] [3];
  160.   unsigned char c;
  161.   for( i=0; i<CHECKBOARD_SIZE; i++ ) 
  162.   {
  163.     for( j=0; j<CHECKBOARD_SIZE; j++ ) 
  164.     {
  165.       dark = 110;
  166.       light = 220;
  167.       if ((((i/CHECKBOARD_REPEAT)&0x1)==0) ^ (((j/CHECKBOARD_REPEAT)&0x1)==0))
  168.         c = light;
  169.       else
  170.         c = dark;
  171.       texture_image[i][j][0] = c;
  172.       texture_image[i][j][1] = c;
  173.       texture_image[i][j][2] = c;
  174.     }    
  175.   }
  176.   
  177.   glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
  178.   glTexParameteri( t, GL_TEXTURE_WRAP_S, GL_REPEAT );
  179.   glTexParameteri( t, GL_TEXTURE_WRAP_T, GL_REPEAT );
  180.   glTexParameteri( t, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  181.   glTexParameteri( t, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
  182.   gluBuild2DMipmaps(t, GL_RGB, CHECKBOARD_SIZE, CHECKBOARD_SIZE,
  183.    GL_RGB, GL_UNSIGNED_BYTE, texture_image);
  184. /* Add some mipmapping LOD bias, to keep sphere texture sharp */
  185.   float bias=-0.5; 
  186.   /* glTexEnvf(TEXTURE_FILTER_CONTROL_EXT,TEXTURE_LOD_BIAS_EXT,bias); */
  187.   /* glTexParameteri( t, GL_TEXTURE_MAX_LEVEL,1);*/
  188.   glTexEnvf(0x8500,0x8501,bias); /* <- numeric version for older OpenGL headers */
  189.   /* Cap out the mipmap level, to prevent blurring on horizon */
  190.   glTexParameteri(t, 0x813D, 1);
  191.   if (glGetError()) {
  192.    /* Ignore errors in setting funky texture state-- go with defaults.
  193.   If somebody knows how to check OpenGL 1.2 before doing this, please do!
  194. */
  195.   }
  196. }
  197. /****************************** GLUI_Rotation::setup_lights() ***********/
  198. void    GLUI_Rotation::setup_lights( void )
  199. {
  200.   glEnable( GL_LIGHTING );
  201.   /*  if ( enabled ) 
  202.       glEnable( GL_LIGHTING );
  203.       else
  204.       glDisable( GL_LIGHTING );*/
  205.   glEnable(GL_LIGHT0);
  206.   glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE );
  207.   glEnable(GL_COLOR_MATERIAL);
  208.   GLfloat light0_position[] = {-1.f, 1.f, 1.0f, 0.0f};
  209.   glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
  210.   if (enabled) { /* enabled colors */
  211. GLfloat light0_ambient[] =  {0.2f, 0.2f, 0.2f, 1.0f};
  212. GLfloat light0_diffuse[] =  {1.f, 1.f, 1.0f, 1.0f};
  213. glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
  214. glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
  215.   }
  216.   else { /* disabled colors */
  217. GLfloat light0_ambient[] =  {0.6f, 0.6f, 0.6f, 1.0f};
  218. GLfloat light0_diffuse[] =  {0.2f, 0.2f, 0.2f, 1.0f};
  219. glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
  220. glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
  221.   }
  222.   
  223. }
  224. /****************************** GLUI_Rotation::draw_ball() **************/
  225. void    GLUI_Rotation::draw_ball( float radius )
  226. {
  227.   if ( NOT can_draw() )
  228.     return;
  229.   if (quadObj == NULL) quadObj = gluNewQuadric();
  230.   if (quadObj) {
  231.     gluQuadricDrawStyle(quadObj, GLU_FILL);
  232.     gluQuadricNormals(quadObj, GLU_SMOOTH);
  233.     gluQuadricTexture(quadObj, true );
  234.     glMatrixMode(GL_TEXTURE);
  235.     glLoadIdentity();
  236.     double checkerTiles=2.0; /* black-white checker tiles across whole sphere */
  237.     glScalef(checkerTiles,checkerTiles,1.0);
  238.     gluSphere(quadObj, radius, 32, 16);
  239.     glLoadIdentity();
  240.     glMatrixMode(GL_MODELVIEW);
  241.   }
  242. }
  243. /****************************** GLUI_Rotation::reset() **********/
  244. void  GLUI_Rotation::reset( void )
  245. {
  246.   ball->init(); /** reset quaternion, etc. **/
  247.   ball->set_params( vec2( (float)(w/2), (float)((h-18)/2)), 
  248.    (float) 2.0*(h-18) );
  249.   set_spin( this->damping );
  250.   copy_ball_to_float_array();
  251.   translate_and_draw_front();
  252.   output_live(true); /*** Output live and draw main grx window ***/
  253. }
  254. /****************************** GLUI_Rotation::needs_idle() *********/
  255. bool GLUI_Rotation::needs_idle( void ) const
  256. {
  257.   return can_spin;
  258. }
  259. /****************************** GLUI_Rotation::idle() ***************/
  260. void        GLUI_Rotation::idle( void )
  261. {
  262.   spinning = ball->is_spinning?true:false;
  263.   if ( can_spin AND spinning ) {
  264.     copy_float_array_to_ball();
  265.     ball->idle();
  266.     *ball->rot_ptr = *ball->rot_ptr * ball->rot_increment;
  267.     mat4 tmp_rot;
  268.     tmp_rot = *ball->rot_ptr;
  269.     copy_ball_to_float_array();
  270.     draw_active_area_only = true;
  271.     translate_and_draw_front();
  272.     draw_active_area_only = false;
  273.     output_live(true); /** output live and update gfx **/
  274.   }
  275.   else { 
  276.   }
  277. }
  278. /********************** GLUI_Rotation::copy_float_array_to_ball() *********/
  279. void     GLUI_Rotation::copy_float_array_to_ball( void )
  280. {
  281.   int i;
  282.   float *fp_src, *fp_dst;
  283.   fp_src = &float_array_val[0];
  284.   fp_dst = &((*ball->rot_ptr)[0][0]);
  285.   for( i=0; i<16; i++ ) {
  286.     *fp_dst = *fp_src;
  287.     fp_src++;
  288.     fp_dst++;
  289.   }
  290. }
  291. /********************** GLUI_Rotation::copy_ball_to_float_array() *********/
  292. void     GLUI_Rotation::copy_ball_to_float_array( void )
  293. {
  294.   mat4 tmp_rot;
  295.   tmp_rot = *ball->rot_ptr;
  296.   set_float_array_val( (float*) &tmp_rot[0][0] );
  297. }
  298. /************************ GLUI_Rotation::set_spin() **********************/
  299. void   GLUI_Rotation::set_spin( float damp_factor )
  300. {
  301.   if ( damp_factor == 0.0 ) 
  302.     can_spin = false;
  303.   else
  304.     can_spin = true;
  305.   ball->set_damping( 1.0 - damp_factor );
  306.   this->damping = damp_factor;
  307. }
  308. /************** GLUI_Rotation::GLUI_Rotation() ********************/
  309. GLUI_Rotation::GLUI_Rotation( GLUI_Node *parent,
  310.                               const char *name, float *value_ptr,
  311.                               int id, 
  312.                               GLUI_CB cb )
  313. {
  314.   common_init();
  315.   set_ptr_val( value_ptr );
  316.   user_id    = id;
  317.   set_name( name );
  318.   callback    = cb;
  319.   parent->add_control( this );
  320.   init_live();
  321.   
  322.   /*** Init the live 4x4 matrix.  This is different than the standard
  323.        live variable behavior, since the original value of the 4x4 matrix
  324.        is ignored and reset to Identity  ***/
  325. /*
  326. NO! WVB
  327.     if ( value_ptr != NULL ) {
  328.       int i, j, index;
  329.       for( i=0; i<4; i++ ) {
  330. for( j=0; j<4; j++ ) {
  331.   index = i*4+j;
  332.   if ( i==j )
  333.     value_ptr[index] = 1.0;
  334.   else
  335.     value_ptr[index] = 0.0;
  336. }
  337.       }
  338.     }
  339. */
  340.     /*init_ball();              */
  341. }
  342. /************** GLUI_Rotation::common_init() ********************/
  343. void GLUI_Rotation::common_init( void ) 
  344. {
  345.   glui_format_str( name, "Rotation: %p", this );
  346. //  type                = GLUI_CONTROL_ROTATION;
  347.   w                   = GLUI_ROTATION_WIDTH;
  348.   h                   = GLUI_ROTATION_HEIGHT;
  349.   can_activate        = true;
  350.   live_type           = GLUI_LIVE_FLOAT_ARRAY;
  351.   float_array_size    = 16;
  352.   quadObj             = NULL;
  353.   alignment           = GLUI_ALIGN_CENTER;
  354.   can_spin            = false;
  355.   spinning            = false;
  356.   damping             = 0.0;
  357.   ball                = new Arcball;
  358.   reset();
  359. }