00001 #ifndef OPENTISSUE_UTILITY_GLUT_GLUT_PERSPECTIVE_VIEW_APPLICATION_H
00002 #define OPENTISSUE_UTILITY_GLUT_GLUT_PERSPECTIVE_VIEW_APPLICATION_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/glut/glut_application.h>
00013
00014 #include <OpenTissue/gpu/image/image.h>
00015 #include <OpenTissue/gpu/image/image_screen_capture.h>
00016 #include <OpenTissue/gpu/image/io/image_write.h>
00017
00018 #ifndef WIN32
00019 # include <unistd.h>
00020 #endif
00021
00022 #include <sstream>
00023 #include <iomanip>
00024
00025 namespace OpenTissue
00026 {
00027 namespace glut
00028 {
00029
00040 template<
00041 typename math_types_
00042 >
00043 class BasePerspectiveViewApplication : public Application
00044 {
00045 public:
00046
00047 typedef math_types_ math_types;
00048
00049 protected:
00050
00051 OpenTissue::gl::Camera<math_types> m_camera;
00052 OpenTissue::gl::Frustum<math_types> m_frustum;
00053 bool m_screen_capture;
00054 bool m_zoom_mode;
00055 bool m_pan_mode;
00056 bool m_trackball_mode;
00057 double m_begin_x;
00058 double m_begin_y;
00059 double m_zoom_sensitivity;
00060 double m_pan_sensitivity;
00061
00062 public:
00063
00064 OpenTissue::gl::Camera<math_types> const & camera() const { return m_camera; }
00065 OpenTissue::gl::Camera<math_types> & camera() { return m_camera; }
00066 OpenTissue::gl::Frustum<math_types> const & frustum() const { return m_frustum; }
00067 OpenTissue::gl::Frustum<math_types> & frustum() { return m_frustum; }
00068 double const & zoom_sensitivity() const { return m_zoom_sensitivity; }
00069 double & zoom_sensitivity() { return m_zoom_sensitivity; }
00070 double const & pan_sensitivity() const { return m_pan_sensitivity; }
00071 double & pan_sensitivity() { return m_pan_sensitivity; }
00072
00073 public:
00074
00075 BasePerspectiveViewApplication()
00076 : Application()
00077 , m_screen_capture(false)
00078 , m_zoom_mode(false)
00079 , m_pan_mode(false)
00080 , m_trackball_mode(false)
00081 , m_begin_x(0.)
00082 , m_begin_y(0.)
00083 , m_zoom_sensitivity(0.25)
00084 , m_pan_sensitivity(0.25)
00085 {}
00086
00087 virtual ~BasePerspectiveViewApplication(){}
00088
00089 public:
00090
00091 virtual void do_display()=0;
00092 virtual void do_action(unsigned char choice)=0;
00093 virtual void do_special_action(int choice){ };
00094 virtual void do_init_right_click_menu(int main_menu, void menu(int entry)) = 0;
00095 virtual void do_init() = 0;
00096 virtual void do_run() = 0;
00097 virtual void do_shutdown() = 0;
00098 virtual char const * do_get_title() const=0;
00099
00100 public:
00101
00102 char const * get_title() const { return this->do_get_title(); }
00103
00104 void run() { this->do_run(); }
00105
00106 void shutdown() { this->do_shutdown(); }
00107
00108 void special_action(int choice){ this->do_special_action(choice); }
00109
00110 void action(unsigned char choice)
00111 {
00112 switch (choice)
00113 {
00114 case 'o':
00115 m_camera.orbit_mode() = !m_camera.orbit_mode();
00116 if(m_camera.orbit_mode())
00117 std::cout << "orbit mode on" << std::endl;
00118 else
00119 std::cout << "orbit mode off " << std::endl;
00120 break;
00121 case 'l':
00122 m_camera.target_locked() = !m_camera.target_locked();
00123 if(m_camera.target_locked())
00124 std::cout << "target is locked" << std::endl;
00125 else
00126 std::cout << "target is free " << std::endl;
00127 break;
00128 case 'y':
00129 m_screen_capture = true;
00130 break;
00131 default:
00132 this->do_action(choice);
00133 };
00134 }
00135
00136 void init_right_click_menu(int main_menu, void menu(int entry))
00137 {
00138 int controls = glutCreateMenu( menu );
00139 glutAddMenuEntry("quit [esc][q]", 'q' );
00140 glutAddMenuEntry("toggle idle [ ]", ' ' );
00141 glutAddMenuEntry("toggle camera orbit/rotate [o]", 'o' );
00142 glutAddMenuEntry("toggle camera target locked [l]", 'l' );
00143 glutAddMenuEntry("screen capture [y]", 'y' );
00144 glutSetMenu( main_menu );
00145 glutAddSubMenu( "controls", controls );
00146
00147 this->do_init_right_click_menu(main_menu, menu);
00148 }
00149
00150 void init()
00151 {
00152
00153 m_zoom_mode = false;
00154 m_pan_mode = false;
00155 m_trackball_mode = false;
00156 m_camera.target_locked() = true;
00157
00158 std::cout << "Rotating: hold down left mouse button" << std::endl;
00159 std::cout << "Zooming: hold down middle mouse button" << std::endl;
00160 std::cout << "Panning: press shift and hold down left mouse button" << std::endl;
00161
00162 typedef typename math_types::vector3_type vector3_type;
00163 vector3_type position = vector3_type(0,0,100);
00164 vector3_type target = vector3_type(0,0,0);
00165 vector3_type up = vector3_type(0,1,0);
00166
00167 m_camera.init(position,target,up);
00168
00169 this->do_init();
00170 }
00171
00172 virtual void mouse_down(double cur_x,double cur_y,bool shift,bool ctrl,bool alt,bool left,bool middle,bool right)
00173 {
00174 if (middle || alt)
00175 m_zoom_mode = true;
00176 if ( shift && left )
00177 m_pan_mode = true;
00178 if(!middle && !right && !ctrl && !alt && !shift && left)
00179 {
00180 m_camera.mouse_down( cur_x, cur_y );
00181 m_trackball_mode = true;
00182 }
00183 m_begin_x = cur_x;
00184 m_begin_y = cur_y;
00185 }
00186
00187 virtual void mouse_up(double cur_x,double cur_y,bool ,bool ,bool ,bool ,bool ,bool )
00188 {
00189 if ( m_zoom_mode )
00190 {
00191 m_camera.move( m_zoom_sensitivity*(cur_y - m_begin_y) );
00192 m_zoom_mode = false;
00193 }
00194 else if ( m_pan_mode )
00195 {
00196 m_camera.pan( m_pan_sensitivity*(m_begin_x - cur_x) , m_pan_sensitivity*(cur_y - m_begin_y) );
00197 m_pan_mode = false;
00198 }
00199 else if ( m_trackball_mode )
00200 {
00201 m_camera.mouse_up( cur_x, cur_y );
00202 m_trackball_mode = false;
00203 }
00204 m_begin_x = cur_x;
00205 m_begin_y = cur_y;
00206 }
00207
00208 virtual void mouse_move(double cur_x,double cur_y)
00209 {
00210 if ( m_zoom_mode )
00211 {
00212 m_camera.move( m_zoom_sensitivity*(cur_y - m_begin_y) );
00213 }
00214 else if ( m_pan_mode )
00215 {
00216 m_camera.pan( m_pan_sensitivity*(m_begin_x - cur_x) , m_pan_sensitivity*(cur_y - m_begin_y) );
00217 }
00218 else if ( m_trackball_mode )
00219 {
00220 m_camera.mouse_move( cur_x, cur_y);
00221 }
00222 m_begin_x = cur_x;
00223 m_begin_y = cur_y;
00224 }
00225
00233 void display()
00234 {
00235 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00236
00237 glMatrixMode( GL_MODELVIEW );
00238 gl::LoadCameraMatrix(m_camera);
00239 m_frustum.update();
00240
00241 this->do_display();
00242
00243 if(m_screen_capture)
00244 {
00245 std::stringstream filename;
00246 static int cnt = 0;
00247 filename << "screen_" << std::setw(4) << std::setfill('0') << ++cnt << ".png";
00248 OpenTissue::image::write( filename.str() , *OpenTissue::image::screen_capture() );
00249 m_screen_capture = false;
00250 }
00251
00252 glFinish();
00253 glutSwapBuffers();
00254 }
00255
00262 void init_gl_state()
00263 {
00264 int err = glewInit();
00265 if ( GLEW_OK != err )
00266 {
00267
00268 std::cerr << "GLEW Error: " << glewGetErrorString( err ) << std::endl;
00269 exit( 1 );
00270 }
00271 std::cout << "GLEW status: Using GLEW " << glewGetString( GLEW_VERSION ) << std::endl;
00272
00273 glClearColor( .7, .7, .7, 1.0 );
00274 glEnable( GL_DEPTH_TEST );
00275
00276 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00277 glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
00278
00279
00280 glEnable( GL_LIGHTING );
00281 glEnable( GL_LIGHT0 );
00282
00283
00284
00285
00286
00287 glShadeModel( GL_SMOOTH );
00288 glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE );
00289 glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE );
00290
00291 this->setup_lights();
00292 }
00293
00300 void setup_lights()
00301 {
00302
00303
00304
00305
00306 GLfloat AmbientLight[] = { .5, .5, .5, 1.0 };
00307 GLfloat DiffuseLight[] = { 1., 1., 1., 1.0 };
00308 GLfloat SpecularLight[] = { 1.0, 1.0, 1.0, 1.0 };
00309
00310 glLightfv( GL_LIGHT0, GL_AMBIENT, AmbientLight );
00311 glLightfv( GL_LIGHT0, GL_DIFFUSE, DiffuseLight );
00312 glLightfv( GL_LIGHT0, GL_SPECULAR, SpecularLight );
00313
00314 GLfloat LightPosition[] = { 0.0, 0.0, 1.0, 0. };
00315 glLightfv( GL_LIGHT0, GL_POSITION, LightPosition );
00316 }
00317
00324 void setup_model_view_projection( )
00325 {
00326 glMatrixMode( GL_PROJECTION );
00327 glLoadIdentity();
00328 this->aspect() = ( 1.0 * this->width() ) / this->height();
00329 gluPerspective( this->fovy(), this->aspect(), this->z_near(), this->z_far() );
00330 glMatrixMode( GL_MODELVIEW );
00331 glLoadIdentity();
00332 }
00333 };
00334
00335 typedef BasePerspectiveViewApplication<OpenTissue::math::default_math_types> PerspectiveViewApplication;
00336
00337 }
00338 }
00339
00340
00341 #endif