1 /****************************************************************************
3 GLUI User Interface Toolkit
4 ---------------------------
6 glui_rotation - GLUI_Rotation control class
9 --------------------------------------------------
11 Copyright (c) 1998 Paul Rademacher
13 WWW: http://sourceforge.net/projects/glui/
14 Forums: http://sourceforge.net/forum/?group_id=92496
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of the GNU Lesser General Public
18 License as published by the Free Software Foundation; either
19 version 2.1 of the License, or (at your option) any later version.
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 Lesser General Public License for more details.
26 You should have received a copy of the GNU Lesser General Public
27 License along with this library; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 *****************************************************************************/
36 /*************************** GLUI_Rotation::iaction_mouse_down_handler() ***/
38 int GLUI_Rotation::iaction_mouse_down_handler( int local_x, int local_y )
40 copy_float_array_to_ball();
44 local_y = (int) floor(2.0 * ball->center[1] - local_y);
46 ball->mouse_down( local_x, local_y );
48 /* printf( "%d %d - %f %f\n", local_x, local_y, ball->center[0], ball->center[1] ); */
50 copy_ball_to_float_array();
58 /*********************** GLUI_Rotation::iaction_mouse_up_handler() **********/
60 int GLUI_Rotation::iaction_mouse_up_handler( int local_x, int local_y,
63 copy_float_array_to_ball();
71 /******************* GLUI_Rotation::iaction_mouse_held_down_handler() ******/
73 int GLUI_Rotation::iaction_mouse_held_down_handler( int local_x, int local_y,
79 copy_float_array_to_ball();
81 local_y = (int) floor(2.0 * ball->center[1] - local_y);
83 /* printf( "%d %d\n", local_x, local_y ); */
85 ball->mouse_motion( local_x, local_y, 0,
86 (glui->curr_modifiers & GLUT_ACTIVE_ALT) != 0,
87 (glui->curr_modifiers & GLUT_ACTIVE_CTRL) != 0 );
89 copy_ball_to_float_array();
98 /******************** GLUI_Rotation::iaction_draw_active_area_persp() **************/
100 void GLUI_Rotation::iaction_draw_active_area_persp( void )
102 /********** arcball *******/
103 copy_float_array_to_ball();
108 glEnable(GL_CULL_FACE );
110 glMatrixMode( GL_MODELVIEW );
113 mat4 tmp_rot = *ball->rot_ptr;
114 glMultMatrixf( (float*) &tmp_rot[0][0] );
116 /*** Draw the checkered box ***/
117 /*glDisable( GL_TEXTURE_2D ); */
118 draw_ball(1.35); // 1.96 );
122 glBindTexture(GL_TEXTURE_2D,0); /* unhook our checkerboard texture */
123 glDisable( GL_TEXTURE_2D );
124 glDisable( GL_LIGHTING );
125 glDisable( GL_CULL_FACE );
129 /******************** GLUI_Rotation::iaction_draw_active_area_ortho() **********/
131 void GLUI_Rotation::iaction_draw_active_area_ortho( void )
134 radius = (float)(h-22)/2.0; /*MIN((float)w/2.0, (float)h/2.0); */
136 /********* Draw emboss circles around arcball control *********/
139 glBegin( GL_LINE_LOOP);
140 for( k=0; k<60; k++ ) {
141 float phi = 2*M_PI*(float)k/60.0;
142 vec2 p( cos(phi) * (2.0 + radius), sin(phi) * (2.0 + radius));
143 if ( p[1] < -p[0] ) glColor3ub( 128,128,128 );
144 else glColor3ub( 255,255,255 );
145 glVertex2fv((float*)&p[0]);
149 glBegin( GL_LINE_LOOP);
150 for( k=0; k<60; k++ ) {
151 float phi = 2*M_PI*(float)k/60.0;
152 vec2 p( cos(phi) * (1.0 + radius), sin(phi) * (1.0 + radius));
154 if ( p[1] < -p[0] ) glColor3ub( 0,0,0);
155 else glColor3ub( 192,192,192);
159 if ( p[1] < -p[0] ) glColor3ub( 180,180,180);
160 else glColor3ub( 192,192,192);
162 glVertex2fv((float*)&p[0]);
168 /******************************** GLUI_Rotation::iaction_dump() **********/
170 void GLUI_Rotation::iaction_dump( FILE *output )
175 /******************** GLUI_Rotation::iaction_special_handler() **********/
177 int GLUI_Rotation::iaction_special_handler( int key,int modifiers )
183 /********************************** GLUI_Rotation::init_ball() **********/
185 void GLUI_Rotation::init_ball( void )
187 /*printf( "%f %f %f", float( MIN(w/2,h/2)), (float) w/2, (float) h/2 ); */
189 ball->set_params( vec2( (float)(w/2), (float)((h-18)/2)),
190 (float) 2.0*(h-18) );
191 /*ball->set_damping( .05 ); */
192 /*float( MIN(w/2,h/2))*2.0 ); */
193 /* ball->reset_mouse(); */
197 /****************************** GLUI_Rotation::setup_texture() *********/
199 void GLUI_Rotation::setup_texture( void )
201 static GLuint tex=0u;
202 GLenum t=GL_TEXTURE_2D;
204 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
205 glColor3f( 1.0, 1.0, 1.0 );
207 /* (OSL 2006/06) Just use glBindTexture to avoid having to re-upload the whole checkerboard every frame. */
208 glBindTexture(t,tex);
210 } /* Else need to make a new checkerboard texture */
211 glGenTextures(1,&tex);
212 glBindTexture(t,tex);
216 int dark, light; /*** Dark and light colors for ball checkerboard ***/
218 /* Note: you can change the number of checkers across there sphere in draw_ball */
219 #define CHECKBOARD_SIZE 64 /* pixels across whole texture */
220 #define CHECKBOARD_REPEAT 32u /* pixels across one black/white sector */
221 unsigned char texture_image[CHECKBOARD_SIZE] [CHECKBOARD_SIZE] [3];
223 for( i=0; i<CHECKBOARD_SIZE; i++ )
225 for( j=0; j<CHECKBOARD_SIZE; j++ )
230 if ((((i/CHECKBOARD_REPEAT)&0x1)==0) ^ (((j/CHECKBOARD_REPEAT)&0x1)==0))
235 texture_image[i][j][0] = c;
236 texture_image[i][j][1] = c;
237 texture_image[i][j][2] = c;
241 glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
242 glTexParameteri( t, GL_TEXTURE_WRAP_S, GL_REPEAT );
243 glTexParameteri( t, GL_TEXTURE_WRAP_T, GL_REPEAT );
244 glTexParameteri( t, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
245 glTexParameteri( t, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
246 gluBuild2DMipmaps(t, GL_RGB, CHECKBOARD_SIZE, CHECKBOARD_SIZE,
247 GL_RGB, GL_UNSIGNED_BYTE, texture_image);
249 /* Add some mipmapping LOD bias, to keep sphere texture sharp */
251 /* glTexEnvf(TEXTURE_FILTER_CONTROL_EXT,TEXTURE_LOD_BIAS_EXT,bias); */
252 /* glTexParameteri( t, GL_TEXTURE_MAX_LEVEL,1);*/
253 glTexEnvf(0x8500,0x8501,bias); /* <- numeric version for older OpenGL headers */
254 /* Cap out the mipmap level, to prevent blurring on horizon */
255 glTexParameteri(t, 0x813D, 1);
257 /* Ignore errors in setting funky texture state-- go with defaults.
258 If somebody knows how to check OpenGL 1.2 before doing this, please do!
263 /****************************** GLUI_Rotation::setup_lights() ***********/
265 void GLUI_Rotation::setup_lights( void )
267 glEnable( GL_LIGHTING );
269 glEnable( GL_LIGHTING );
271 glDisable( GL_LIGHTING );*/
273 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE );
274 glEnable(GL_COLOR_MATERIAL);
275 GLfloat light0_position[] = {-1.f, 1.f, 1.0f, 0.0f};
276 glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
277 if (enabled) { /* enabled colors */
278 GLfloat light0_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
279 GLfloat light0_diffuse[] = {1.f, 1.f, 1.0f, 1.0f};
280 glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
281 glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
283 else { /* disabled colors */
284 GLfloat light0_ambient[] = {0.6f, 0.6f, 0.6f, 1.0f};
285 GLfloat light0_diffuse[] = {0.2f, 0.2f, 0.2f, 1.0f};
286 glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
287 glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
293 /****************************** GLUI_Rotation::draw_ball() **************/
295 void GLUI_Rotation::draw_ball( float radius )
297 if ( NOT can_draw() )
300 if (quadObj == NULL) quadObj = gluNewQuadric();
302 gluQuadricDrawStyle(quadObj, GLU_FILL);
303 gluQuadricNormals(quadObj, GLU_SMOOTH);
304 gluQuadricTexture(quadObj, true );
305 glMatrixMode(GL_TEXTURE);
307 double checkerTiles=2.0; /* black-white checker tiles across whole sphere */
308 glScalef(checkerTiles,checkerTiles,1.0);
309 gluSphere(quadObj, radius, 32, 16);
311 glMatrixMode(GL_MODELVIEW);
316 /****************************** GLUI_Rotation::reset() **********/
318 void GLUI_Rotation::reset( void )
320 ball->init(); /** reset quaternion, etc. **/
321 ball->set_params( vec2( (float)(w/2), (float)((h-18)/2)),
322 (float) 2.0*(h-18) );
324 set_spin( this->damping );
326 copy_ball_to_float_array();
328 translate_and_draw_front();
330 output_live(true); /*** Output live and draw main grx window ***/
334 /****************************** GLUI_Rotation::needs_idle() *********/
336 bool GLUI_Rotation::needs_idle( void ) const
342 /****************************** GLUI_Rotation::idle() ***************/
344 void GLUI_Rotation::idle( void )
346 spinning = ball->is_spinning?true:false;
348 if ( can_spin AND spinning ) {
349 copy_float_array_to_ball();
352 *ball->rot_ptr = *ball->rot_ptr * ball->rot_increment;
355 tmp_rot = *ball->rot_ptr;
357 copy_ball_to_float_array();
359 draw_active_area_only = true;
360 translate_and_draw_front();
361 draw_active_area_only = false;
363 output_live(true); /** output live and update gfx **/
370 /********************** GLUI_Rotation::copy_float_array_to_ball() *********/
372 void GLUI_Rotation::copy_float_array_to_ball( void )
375 float *fp_src, *fp_dst;
377 fp_src = &float_array_val[0];
378 fp_dst = &((*ball->rot_ptr)[0][0]);
380 for( i=0; i<16; i++ ) {
389 /********************** GLUI_Rotation::copy_ball_to_float_array() *********/
391 void GLUI_Rotation::copy_ball_to_float_array( void )
394 tmp_rot = *ball->rot_ptr;
396 set_float_array_val( (float*) &tmp_rot[0][0] );
400 /************************ GLUI_Rotation::set_spin() **********************/
402 void GLUI_Rotation::set_spin( float damp_factor )
404 if ( damp_factor == 0.0 )
409 ball->set_damping( 1.0 - damp_factor );
411 this->damping = damp_factor;
415 /************** GLUI_Rotation::GLUI_Rotation() ********************/
417 GLUI_Rotation::GLUI_Rotation( GLUI_Node *parent,
418 const char *name, float *value_ptr,
423 set_ptr_val( value_ptr );
427 parent->add_control( this );
430 /*** Init the live 4x4 matrix. This is different than the standard
431 live variable behavior, since the original value of the 4x4 matrix
432 is ignored and reset to Identity ***/
435 if ( value_ptr != NULL ) {
437 for( i=0; i<4; i++ ) {
438 for( j=0; j<4; j++ ) {
441 value_ptr[index] = 1.0;
443 value_ptr[index] = 0.0;
454 /************** GLUI_Rotation::common_init() ********************/
456 void GLUI_Rotation::common_init( void )
458 glui_format_str( name, "Rotation: %p", this );
459 // type = GLUI_CONTROL_ROTATION;
460 w = GLUI_ROTATION_WIDTH;
461 h = GLUI_ROTATION_HEIGHT;
463 live_type = GLUI_LIVE_FLOAT_ARRAY;
464 float_array_size = 16;
466 alignment = GLUI_ALIGN_CENTER;