glh_glut2.h
Go to the documentation of this file.
00001 /*
00002     glh - is a platform-indepenedent C++ OpenGL helper library 
00003 
00004 
00005     Copyright (c) 2000 Cass Everitt
00006         Copyright (c) 2000 NVIDIA Corporation
00007     All rights reserved.
00008 
00009     Redistribution and use in source and binary forms, with or
00010         without modification, are permitted provided that the following
00011         conditions are met:
00012 
00013      * Redistributions of source code must retain the above
00014            copyright notice, this list of conditions and the following
00015            disclaimer.
00016 
00017      * Redistributions in binary form must reproduce the above
00018            copyright notice, this list of conditions and the following
00019            disclaimer in the documentation and/or other materials
00020            provided with the distribution.
00021 
00022      * The names of contributors to this software may not be used
00023            to endorse or promote products derived from this software
00024            without specific prior written permission. 
00025 
00026        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027            ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028            LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00029            FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00030            REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00031            INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00032            BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00033            LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00034            CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00035            LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00036            ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
00037            POSSIBILITY OF SUCH DAMAGE. 
00038 
00039 
00040     Cass Everitt - cass@r3.nu
00041 */
00042 
00043 #ifndef GLH_GLUT_H
00044 #define GLH_GLUT_H
00045 
00046 // some helper functions and objects to
00047 // make writing simple glut programs even easier! :-)
00048 #ifndef _WIN32
00049 #include <string.h>
00050 #endif
00051 #include <algorithm>
00052 #include <list>
00053 
00054 #ifdef MACOS
00055 #include <GLUT/glut.h>
00056 #else
00057 #include <GL/glut.h>
00058 #endif
00059 
00060 #include <glh/glh_interactors.h>
00061 #include <glh/glh_convenience.h>
00062 
00063 namespace glh
00064 {
00065 
00066   class glut_interactor
00067   {
00068   public:
00069         glut_interactor() { enabled = true; }
00070 
00071         virtual void display() {}
00072         virtual void idle() {}
00073         virtual void keyboard(unsigned char key, int x, int y) {}
00074         virtual void menu_status(int status, int x, int y) {}
00075         virtual void motion(int x, int y) {}
00076         virtual void mouse(int button, int state, int x, int y) {}
00077         virtual void passive_motion(int x, int y) {}
00078         virtual void reshape(int w, int h) {}
00079         virtual void special(int  key, int x, int y) {}
00080         virtual void timer(int value) {}
00081         virtual void visibility(int v) {}
00082 
00083         virtual void enable()  { enabled = true; }
00084         virtual void disable() { enabled = false; }
00085 
00086         bool enabled;
00087   };
00088 
00089   std::list<glut_interactor *> interactors;
00090   bool propagate;
00091 
00092   void glut_display_function()
00093   {
00094         propagate = true;
00095         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00096                 (*it)->display();
00097   }
00098 
00099   void glut_idle_function()
00100   {
00101         propagate = true;
00102         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00103                 (*it)->idle();
00104   }
00105 
00106   void glut_keyboard_function(unsigned char k, int x, int y)
00107   {
00108         propagate = true;
00109         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00110           (*it)->keyboard(k, x, y);
00111   }
00112 
00113   void glut_menu_status_function(int status, int x, int y)
00114   {
00115         propagate = true;
00116         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00117                 (*it)->menu_status(status, x, y);
00118   }
00119 
00120   void glut_motion_function(int x, int y)
00121   {
00122         propagate = true;
00123         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00124                 (*it)->motion(x, y);
00125   }
00126 
00127   void glut_mouse_function(int button, int state, int x, int y)
00128   {
00129         propagate = true;
00130         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00131           (*it)->mouse(button, state, x, y);
00132   }
00133   
00134   void glut_passive_motion_function(int x, int y)
00135   {
00136         propagate = true;
00137         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00138                 (*it)->passive_motion(x, y);
00139   }
00140 
00141   void glut_reshape_function(int w, int h)
00142   {
00143         propagate = true;
00144         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00145           (*it)->reshape(w,h);
00146   }
00147 
00148   void glut_special_function(int k, int x, int y)
00149   {
00150         propagate = true;
00151         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00152           (*it)->special(k, x, y);
00153   }
00154 
00155   void glut_timer_function(int v)
00156   {
00157         propagate = true;
00158         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00159           (*it)->timer(v);
00160   }
00161 
00162   void glut_visibility_function(int v)
00163   {
00164         propagate = true;
00165         for(std::list<glut_interactor *>::iterator it=interactors.begin(); it != interactors.end() && propagate; it++)
00166           (*it)->visibility(v);
00167   }
00168 
00169   // stop processing the current event 
00170   inline void glut_event_processed()
00171   {
00172           propagate = false;
00173   }
00174 
00175   inline void glut_helpers_initialize()
00176   {
00177         glutDisplayFunc(glut_display_function);
00178         glutIdleFunc(0);
00179         glutKeyboardFunc(glut_keyboard_function);
00180         glutMenuStatusFunc(glut_menu_status_function);
00181         glutMotionFunc(glut_motion_function);
00182         glutMouseFunc(glut_mouse_function);
00183         glutPassiveMotionFunc(glut_passive_motion_function);
00184         glutReshapeFunc(glut_reshape_function);
00185         glutSpecialFunc(glut_special_function);
00186         glutVisibilityFunc(glut_visibility_function);
00187   }
00188 
00189   inline void glut_remove_interactor(glut_interactor *gi)
00190   {
00191       if (interactors.empty())
00192           return;
00193           std::list<glut_interactor *>::iterator it = 
00194                   std::find(interactors.begin(), interactors.end(), gi);
00195         if(it != interactors.end())
00196           interactors.erase(it);
00197   }
00198 
00199   inline void glut_add_interactor(glut_interactor *gi, bool append=true)
00200   {
00201         glut_remove_interactor(gi);
00202         if(append)
00203                 interactors.push_back(gi);
00204         else
00205                 interactors.push_front(gi);
00206   }
00207 
00208   inline void glut_timer(int msec, int value)
00209   {
00210         glutTimerFunc(msec, glut_timer_function, value);
00211   }
00212 
00213   inline void glut_idle(bool do_idle)
00214   {
00215         glutIdleFunc(do_idle ? glut_idle_function : 0);
00216   }
00217 
00218   class glut_callbacks : public glut_interactor
00219   {
00220   public:
00221         glut_callbacks() :
00222                 display_function(0),
00223                 idle_function(0),
00224                 keyboard_function(0),
00225                 menu_status_function(0),
00226                 motion_function(0),
00227                 mouse_function(0),
00228                 passive_motion_function(0),
00229                 reshape_function(0),
00230                 special_function(0),
00231                 timer_function(0),
00232                 visibility_function()
00233         {}
00234 
00235         virtual void display()
00236         { if(display_function) display_function(); }
00237 
00238         virtual void idle()
00239         { if(idle_function) idle_function(); }
00240 
00241         virtual void keyboard(unsigned char k, int x, int y)
00242         { if(keyboard_function) keyboard_function(k, x, y); }
00243 
00244         virtual void menu_status(int status, int x, int y)
00245         { if(menu_status_function) menu_status_function(status, x, y); }
00246 
00247         virtual void motion(int x, int y)
00248         { if(motion_function) motion_function(x,y); }
00249 
00250         virtual void mouse(int button, int state, int x, int y)
00251         { if(mouse_function) mouse_function(button, state, x, y); }
00252 
00253         virtual void passive_motion(int x, int y)
00254         { if(passive_motion_function) passive_motion_function(x, y); }
00255 
00256         virtual void reshape(int w, int h)
00257         { if(reshape_function) reshape_function(w, h); }
00258 
00259         virtual void special(int key, int x, int y)
00260         { if(special_function) special_function(key, x, y); }
00261 
00262         virtual void timer(int value)
00263         { if(timer_function) timer_function(value); }
00264 
00265         virtual void visibility(int v)
00266         { if(visibility_function) visibility_function(v); }
00267 
00268         void (* display_function) ();
00269         void (* idle_function) ();
00270         void (* keyboard_function) (unsigned char, int, int);
00271         void (* menu_status_function) (int, int, int);
00272         void (* motion_function) (int, int);
00273         void (* mouse_function) (int, int, int, int);
00274         void (* passive_motion_function) (int, int);
00275         void (* reshape_function) (int, int);
00276         void (* special_function) (int, int, int);
00277         void (* timer_function) (int);
00278         void (* visibility_function) (int);
00279 
00280   };
00281 
00282 
00283 
00284   class glut_perspective_reshaper : public glut_interactor
00285   {
00286   public:
00287           glut_perspective_reshaper(float infovy = 60.f, float inzNear = .1f, float inzFar = 10.f)
00288                   : fovy(infovy), zNear(inzNear), zFar(inzFar), aspect_factor(1) {}
00289           
00290           void reshape(int w, int h)
00291           {
00292                   width = w; height = h;
00293 
00294                   if(enabled) apply();
00295           }
00296 
00297           void apply()
00298           {
00299                   glViewport(0,0,width,height);
00300                   glMatrixMode(GL_PROJECTION);
00301                   glLoadIdentity();
00302                   apply_projection();
00303                   glMatrixMode(GL_MODELVIEW);
00304           }
00305 
00306           matrix4f get_projection()
00307           {
00308                   aspect = aspect_factor * float(width)/float(height);
00309           if ( aspect < 1 )
00310                   {
00311                           // fovy is a misnomer.. we really mean the fov applies to the
00312                           // smaller dimension
00313                           float fovx = fovy; 
00314                           float real_fov = to_degrees(2 * atan(tan(to_radians(fovx/2))/aspect));
00315               return perspective(real_fov, aspect, zNear, zFar);
00316                   }
00317           else
00318                     return perspective(fovy, aspect, zNear, zFar);
00319           }
00320 
00321           void apply_projection()
00322           {
00323                 glMultMatrixf(get_projection().m);
00324           }
00325 
00326           matrix4f get_projection_inverse()
00327           {
00328                   aspect = aspect_factor * float(width)/float(height);
00329           if ( aspect < 1 )
00330                   {
00331                           // fovy is a misnomer.. we really mean the fov applies to the
00332                           // smaller dimension
00333                           float fovx = fovy; 
00334                           float real_fov = to_degrees(2 * atan(tan(to_radians(fovx/2))/aspect));
00335               return perspective_inverse(real_fov, aspect, zNear, zFar);
00336                   }
00337           else
00338                     return perspective_inverse(fovy, aspect, zNear, zFar);
00339           }
00340 
00341           void apply_projection_inverse()
00342           {
00343                   glMultMatrixf(get_projection_inverse().m);
00344           }
00345 
00346           int width, height;
00347           float fovy, aspect, zNear, zFar;
00348           float aspect_factor;
00349   };
00350 
00351 
00352   // activates/deactivates on particular mouse button/modifier combinations
00353   // and calculates deltas while active
00354   class glut_simple_interactor : public glut_interactor
00355   {
00356   public:
00357         glut_simple_interactor()
00358         {
00359           num_modes = 0;
00360           active = false;
00361           width = height = 0;
00362           x0 = y0 = x = y = dx = dy = 0;
00363         }
00364 
00365         virtual void mouse(int button, int state, int X, int Y)
00366         {
00367                 for(int i=0; i < num_modes; i++)
00368                 {
00369                         if(enabled && button == cond[i].activate_on && state == GLUT_DOWN &&
00370                                 (! cond[i].use_modifiers || (cond[i].modifiers == glutGetModifiers())) )
00371                         {
00372                                 mode = i;
00373                                 active = true;
00374                                 x = x0 = X;
00375                                 y = y0 = height - Y;
00376                                 dx = dy = 0;
00377                                 break;
00378                         }
00379                         else if (enabled && button == cond[i].activate_on && state == GLUT_UP)
00380                         {
00381                                 if(dx == 0 && dy == 0)
00382                                         update();
00383                                 active = false;
00384                                 dx = dy = 0;
00385                                 mode = -1;
00386                                 break;
00387                         }
00388                 }
00389         }
00390 
00391         virtual void motion(int X, int Y)
00392         {
00393           if(enabled && active)
00394           {
00395                 dx = X - x;   dy = (height - Y) - y;
00396                 x = X;   y = height - Y;
00397                 update();
00398           }
00399         }
00400 
00401         void reshape(int w, int h)
00402         {
00403                   width = w; height = h;
00404         }
00405 
00406         virtual void apply_transform() = 0; 
00407         virtual void apply_inverse_transform() = 0;
00408         virtual matrix4f get_transform() = 0;
00409         virtual matrix4f get_inverse_transform() = 0;
00410 
00411         virtual void update() {}
00412 
00413         struct activate_condition
00414         {
00415                 activate_condition()
00416                 {
00417                         activate_on = GLUT_LEFT_BUTTON;
00418                         use_modifiers = true;
00419                         modifiers = 0;
00420                 }
00421                 int activate_on;
00422                 bool use_modifiers;
00423                 int modifiers;
00424         };
00425 
00426         activate_condition cond[2];
00427         bool active;
00428         int x0, y0;
00429         int x, y;
00430         int dx, dy;
00431         int width, height;
00432         int num_modes;
00433         int mode;
00434   };
00435 
00436 
00437   class glut_translator : public translator, public glut_simple_interactor
00438   {
00439   public:
00440 
00441         void update()
00442         {
00443           if(mode == 0)
00444                   pan(dx, dy);
00445           else if(mode == 1)
00446                   dolly(-dy);
00447           glutPostRedisplay();
00448         }
00449 
00450         void apply_transform()
00451         {
00452           //cerr << "Applying transform: " << (x - x0) << ", " << (y - y0) << endl;
00453           glTranslatef(t[0], t[1], t[2]);
00454         }
00455 
00456         void apply_inverse_transform()
00457         {
00458           //cerr << "Applying transform: " << (x - x0) << ", " << (y - y0) << endl;
00459           glTranslatef(-t[0], -t[1], -t[2]);
00460         }
00461 
00462         matrix4f get_transform()
00463         {
00464                 return translator::get_transform();
00465         }
00466 
00467         matrix4f get_inverse_transform()
00468         {
00469                 return translator::get_inverse_transform();
00470         }
00471 
00472   };
00473 
00474 
00475   class glut_trackball : public glut_simple_interactor, public trackball
00476   {
00477   public:
00478 
00479         void update()
00480         {
00481                 radius = width < height ? width : height;
00482                 radius /= 2.f;
00483                 offset = vec3f(width/2.f, height/2.f, 0);
00484                 rotate(x-dx, y-dy, x, y);
00485                 glutPostRedisplay();
00486         }
00487 
00488         void apply_transform()
00489         {
00490                 glTranslatef(centroid[0], centroid[1], centroid[2]);
00491                 glh_rotate(r);
00492                 glTranslatef(-centroid[0], -centroid[1], -centroid[2]);
00493         }
00494 
00495         void apply_inverse_transform()
00496         {
00497                 glTranslatef(centroid[0], centroid[1], centroid[2]);
00498                 glh_rotate(r.inverse());
00499                 glTranslatef(-centroid[0], -centroid[1], -centroid[2]);
00500         }
00501 
00502         matrix4f get_transform()
00503         {
00504                 return trackball::get_transform();
00505         }
00506 
00507         matrix4f get_inverse_transform()
00508         {
00509                 return trackball::get_inverse_transform();
00510         }
00511 
00512   }; 
00513 
00514   inline void glut_exit_on_escape(unsigned char k, int x = 0, int y = 0)
00515   { if(k==27) exit(0); }
00516 
00517   struct glut_simple_mouse_interactor : public glut_interactor
00518   {
00519 
00520   public:
00521         glut_simple_mouse_interactor(int num_buttons_to_use=3)
00522         {
00523           configure_buttons(num_buttons_to_use);
00524           camera_mode = false;
00525         }
00526 
00527         void enable()
00528         {
00529                 trackball.enable();
00530                 translator.enable();
00531         }
00532 
00533         void disable()
00534         {
00535                 trackball.disable();
00536                 translator.disable();
00537         }
00538 
00539         void set_camera_mode(bool cam)
00540         {
00541                 camera_mode = cam;
00542                 if(camera_mode)
00543                 {
00544                         trackball.invert_increment = true;
00545                         translator.invert_increment = true;
00546                         translator.parent_rotation = & trackball.r;
00547                 }
00548                 else
00549                 {
00550                         trackball.invert_increment = false;
00551                         translator.invert_increment = false;
00552                         if(translator.parent_rotation == &trackball.r) translator.parent_rotation = 0;
00553                 }
00554         }
00555         void configure_buttons(int num_buttons_to_use = 3)
00556         {
00557           switch(num_buttons_to_use)
00558           {
00559           case 1:
00560 
00561                 trackball.num_modes = 1;
00562                 trackball.cond[0].activate_on = GLUT_LEFT_BUTTON;
00563                 trackball.cond[0].modifiers = 0;
00564                 trackball.cond[0].use_modifiers = true;
00565 
00566                 translator.num_modes = 2;
00567                 translator.cond[0].activate_on = GLUT_LEFT_BUTTON;
00568                 translator.cond[0].modifiers = GLUT_ACTIVE_SHIFT;
00569                 translator.cond[0].use_modifiers = true;
00570                 translator.cond[1].activate_on = GLUT_LEFT_BUTTON;
00571                 translator.cond[1].modifiers = GLUT_ACTIVE_CTRL;
00572                 translator.cond[1].use_modifiers = true;
00573                 break;
00574 
00575           case 2:
00576 
00577                 trackball.num_modes = 1;
00578                 trackball.cond[0].activate_on = GLUT_LEFT_BUTTON;
00579                 trackball.cond[0].modifiers = 0;
00580                 trackball.cond[0].use_modifiers = true;
00581 
00582                 translator.num_modes = 2;
00583                 translator.cond[0].activate_on = GLUT_MIDDLE_BUTTON;
00584                 translator.cond[0].modifiers = 0;
00585                 translator.cond[0].use_modifiers = true;
00586                 translator.cond[1].activate_on = GLUT_LEFT_BUTTON;
00587                 translator.cond[1].modifiers = GLUT_ACTIVE_CTRL;
00588                 translator.cond[1].use_modifiers = true;
00589 
00590                 break;
00591 
00592           case 3:
00593           default:
00594 
00595                 trackball.num_modes = 1;
00596                 trackball.cond[0].activate_on = GLUT_LEFT_BUTTON;
00597                 trackball.cond[0].modifiers = 0;
00598                 trackball.cond[0].use_modifiers = true;
00599 
00600                 translator.num_modes = 2;
00601                 translator.cond[0].activate_on = GLUT_MIDDLE_BUTTON;
00602                 translator.cond[0].modifiers = 0;
00603                 translator.cond[0].use_modifiers = true;
00604                 translator.cond[1].activate_on = GLUT_RIGHT_BUTTON;
00605                 translator.cond[1].modifiers = 0;
00606                 translator.cond[1].use_modifiers = true;
00607 
00608                 break;
00609           }
00610         }
00611 
00612         virtual void motion(int x, int y)
00613         { 
00614                 trackball.motion(x,y);
00615                 translator.motion(x,y);
00616         }
00617 
00618         virtual void mouse(int button, int state, int x, int y)
00619         {
00620           trackball.mouse(button, state, x, y);
00621           translator.mouse(button, state, x, y);
00622         }
00623 
00624         virtual void reshape(int x, int y)
00625         {
00626                 trackball.reshape(x,y);
00627                 translator.reshape(x,y);
00628         }
00629 
00630         void apply_transform()
00631         {
00632           translator.apply_transform();
00633           trackball.apply_transform();
00634         }
00635 
00636         void apply_inverse_transform()
00637         {
00638           trackball.apply_inverse_transform();
00639           translator.apply_inverse_transform();
00640         }
00641 
00642         matrix4f get_transform()
00643         {
00644           return ( translator.get_transform()       *
00645                            trackball.get_transform() );
00646         }
00647 
00648         matrix4f get_inverse_transform()
00649         {
00650           return ( trackball.get_inverse_transform() *
00651                            translator.get_inverse_transform()       );
00652         }
00653 
00654         void set_parent_rotation(rotationf *rp)
00655         {
00656                 trackball.parent_rotation = rp;
00657                 translator.parent_rotation = rp;
00658         }
00659 
00660         bool camera_mode;
00661         glut_trackball trackball;
00662         glut_translator  translator;
00663   };
00664 
00665 }
00666 
00667 #endif


nao_openni
Author(s): Bener SUAY
autogenerated on Mon Jan 6 2014 11:27:50