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;