contrib/brl/bbas/bgui3d/bgui3d_tableau.cxx
Go to the documentation of this file.
00001 // This is brl/bbas/bgui3d/bgui3d_tableau.cxx
00002 #include "bgui3d_tableau.h"
00003 //:
00004 // \file
00005 
00006 #include "bgui3d_translate_event.h"
00007 #include <vgui/vgui_gl.h>
00008 #include <vgui/vgui_macro.h>
00009 
00010 #include <Inventor/SbColor.h>
00011 #include <Inventor/SoDB.h>
00012 #include <Inventor/SbViewportRegion.h>
00013 #include <Inventor/nodes/SoNode.h>
00014 #include <Inventor/SoSceneManager.h>
00015 #include <Inventor/actions/SoGLRenderAction.h>
00016 
00017 
00018 //: The callback called by the scene manager to initiate a redraw
00019 //  Second argument might just be 0, since it's not used
00020 static void
00021 bgui3d_render_callback(void *tableau, SoSceneManager* /*mgr*/)
00022 {
00023   bgui3d_tableau * tab = (bgui3d_tableau *) tableau;
00024   tab->request_render();
00025 }
00026 
00027 //: The callback called by the overlay scene manager to initiate a redraw
00028 //  Second argument might just be 0, since it's not used
00029 static void
00030 bgui3d_render_overlay_callback(void *tableau, SoSceneManager * /*mgr*/)
00031 {
00032   bgui3d_tableau * tab = (bgui3d_tableau *) tableau;
00033   tab->request_render_overlay();
00034 }
00035 
00036 //------------------------------------------------------------------
00037 
00038 //: Constructor - don't use this, use bgui3d_tableau_new.
00039 bgui3d_tableau::bgui3d_tableau(SoNode * scene_root)
00040  : scene_root_(NULL), overlay_scene_root_(NULL),
00041    scene_manager_(NULL), overlay_scene_manager_(NULL),
00042    idle_enabled_(false), interaction_type_(SCENEGRAPH)
00043 {
00044   this->set_scene_root(scene_root);
00045 }
00046 
00047 
00048 //: Destructor
00049 bgui3d_tableau::~bgui3d_tableau()
00050 {
00051   this->disable_idle();
00052 
00053   if (scene_root_)
00054     scene_root_->unref();
00055   if (overlay_scene_root_)
00056     overlay_scene_root_->unref();
00057 
00058 #if 0 // Ming: no need to release memory of the SoSceneManager* scene_manager_ & overlay_scene_manager_
00059   if (scene_manager_)         delete scene_manager_;
00060   if (overlay_scene_manager_) delete overlay_scene_manager_;
00061 #endif // 0
00062 }
00063 
00064 
00065 vcl_string bgui3d_tableau::type_name() const {return "bgui3d_tableau";}
00066 
00067 
00068 //: Set up OpenGL for rendering
00069 void
00070 bgui3d_tableau::setup_opengl() const
00071 {
00072   // This call is still needed on the linux side
00073   glEnable(GL_DEPTH_TEST);
00074 
00075   glLineWidth( 1.0 );
00076   glPointSize( 1.0 );
00077 }
00078 
00079 
00080 //: Render the scene graph (called on draw events)
00081 bool
00082 bgui3d_tableau::render()
00083 {
00084   if (!scene_manager_)
00085     return false;
00086 
00087   glPushAttrib(GL_ALL_ATTRIB_BITS);
00088 
00089   // Set up OpenGL for Rendering
00090   this->setup_opengl();
00091 
00092   // Update the scene manager if the viewport has changed
00093   GLint vp[4];
00094   glGetIntegerv(GL_VIEWPORT, vp);
00095   SbViewportRegion vguiViewport;
00096   vguiViewport.setViewportPixels(vp[0], vp[1], vp[2], vp[3]);
00097 
00098   if ( !(scene_manager_->getViewportRegion() == vguiViewport) ) {
00099     scene_manager_->setViewportRegion(vguiViewport);
00100   }
00101 
00102   // Reinitialize to account for changes in the OpenGL context
00103   scene_manager_->reinitialize();
00104 
00105   // Do the rendering
00106   scene_manager_->render(scene_manager_->getGLRenderAction(), false, false);
00107 
00108   glPopAttrib();
00109 
00110   return true;
00111 }
00112 
00113 
00114 //: Render the overlay scene graph (called on draw overlay events)
00115 bool
00116 bgui3d_tableau::render_overlay()
00117 {
00118   if (!overlay_scene_manager_)
00119     return false;
00120 
00121   glPushAttrib(GL_ALL_ATTRIB_BITS);
00122 
00123   // Set up OpenGL for Rendering
00124   this->setup_opengl();
00125 
00126   // Update the scene manager if the viewport has changed
00127   GLint vp[4];
00128   glGetIntegerv(GL_VIEWPORT, vp);
00129   SbViewportRegion vguiViewport;
00130   vguiViewport.setViewportPixels(vp[0], vp[1], vp[2], vp[3]);
00131 
00132   if ( !(overlay_scene_manager_->getViewportRegion() == vguiViewport) ) {
00133     overlay_scene_manager_->setViewportRegion(vguiViewport);
00134   }
00135 
00136   // Reinitialize to account for changes in the OpenGL context
00137   overlay_scene_manager_->reinitialize();
00138 
00139   // Do the rendering
00140   overlay_scene_manager_->render(overlay_scene_manager_->getGLRenderAction(),false,false);
00141 
00142   glPopAttrib();
00143 
00144   return true;
00145 }
00146 
00147 
00148 //: Handle vgui events
00149 bool bgui3d_tableau::handle(const vgui_event& e)
00150 {
00151   // Handle draw events
00152   if ( e.type == vgui_DRAW )
00153     return this->render();
00154 
00155   if ( e.type == vgui_DRAW_OVERLAY )
00156     return this->render_overlay();
00157 
00158   if (!scene_manager_)
00159     return false;
00160 
00161   // Attempt to convert all unhandled events to SoEvents
00162   // and pass the SoEvents to the scene graph for handling
00163   SoDB::getSensorManager()->processDelayQueue(TRUE);
00164   SoDB::getSensorManager()->processTimerQueue();
00165   if ( interaction_type_ == SCENEGRAPH )
00166   {
00167     bool handled = false;
00168     SoEvent* event = bgui3d_translate_event(e);
00169     if (event) {
00170       handled = scene_manager_->processEvent(event) > 0;
00171       if (handled)
00172         return true;
00173     }
00174   }
00175   request_render();
00176 
00177   return vgui_tableau::handle(e);
00178 }
00179 
00180 
00181 bool
00182 bgui3d_tableau::idle()
00183 {
00184   SoDB::getSensorManager()->processTimerQueue();
00185   SoDB::getSensorManager()->processDelayQueue(TRUE);
00186   return idle_enabled_;
00187 }
00188 
00189 
00190 //: Enable handling of idle events
00191 void
00192 bgui3d_tableau::enable_idle()
00193 {
00194   idle_enabled_ = true;
00195   this->post_idle_request();
00196 }
00197 
00198 
00199 //: Disable handling of idle events
00200 void
00201 bgui3d_tableau::disable_idle()
00202 {
00203   idle_enabled_ = false;
00204 }
00205 
00206 
00207 //: Returns true if idle event handling is enabled
00208 bool
00209 bgui3d_tableau::is_idle_enabled()
00210 {
00211   return idle_enabled_;
00212 }
00213 
00214 
00215 //: Called when the scene manager requests a render action
00216 void
00217 bgui3d_tableau::request_render()
00218 {
00219   this->post_redraw();
00220 }
00221 
00222 
00223 //: Called when the overlay scene manager requests a render action
00224 void
00225 bgui3d_tableau::request_render_overlay()
00226 {
00227   this->post_overlay_redraw();
00228 }
00229 
00230 
00231 //: Set scene root node
00232 void
00233 bgui3d_tableau::set_scene_root(SoNode* scene_root)
00234 {
00235   if (scene_root_)
00236     scene_root_->unref();
00237   scene_root_ = scene_root;
00238   if (scene_root_)
00239     scene_root_->ref();
00240 
00241   if (scene_root_) {
00242     if (!scene_manager_)
00243     {
00244       scene_manager_ = new SoSceneManager();
00245       scene_manager_->getGLRenderAction()->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_BLEND);
00246       //DELAYED_BLEND
00247     }
00248     else
00249       scene_manager_->deactivate();
00250 
00251     scene_manager_->setSceneGraph(scene_root_);
00252     scene_manager_->setRenderCallback(bgui3d_render_callback, this);
00253     scene_manager_->activate();
00254   }
00255 }
00256 
00257 
00258 //: Set overlay scene root node
00259 void
00260 bgui3d_tableau::set_overlay_scene_root(SoNode* scene_root)
00261 {
00262   if (overlay_scene_root_)
00263     overlay_scene_root_->unref();
00264   overlay_scene_root_ = scene_root;
00265   if (overlay_scene_root_)
00266     overlay_scene_root_->ref();
00267 
00268   if (overlay_scene_root_) {
00269     if (!overlay_scene_manager_)
00270       overlay_scene_manager_ = new SoSceneManager();
00271     else
00272       overlay_scene_manager_->deactivate();
00273 
00274     overlay_scene_manager_->setSceneGraph(scene_root_);
00275     overlay_scene_manager_->setRenderCallback(bgui3d_render_overlay_callback, this);
00276     overlay_scene_manager_->activate();
00277   }
00278 }
00279 
00280 
00281 //: Set the scene camera
00282 // creates a graphics camera from a vpgl camera (either perspective or affine)
00283 bool
00284 bgui3d_tableau::set_camera(const vpgl_proj_camera<double>& /*camera*/)
00285 {
00286   // FIXME - not yet implemented
00287   return false;
00288 }
00289 
00290 
00291 //: Get the scene camera
00292 // creates a vpgl camera (either perspective or affine) from the graphics camera
00293 vcl_auto_ptr<vpgl_proj_camera<double> >
00294 bgui3d_tableau::camera() const
00295 {
00296   return vcl_auto_ptr<vpgl_proj_camera<double> >(NULL);
00297 }
00298 
00299 
00300 void
00301 bgui3d_tableau::set_viewport_region(const SbViewportRegion& region)
00302 {
00303   if (region.getWindowSize()[0] == -1) return;
00304 
00305   scene_manager_->setViewportRegion(region);
00306   overlay_scene_manager_->setViewportRegion(region);
00307 }
00308 
00309 const SbViewportRegion &
00310 bgui3d_tableau::get_viewport_region() const
00311 {
00312   return scene_manager()->getViewportRegion();
00313 }
00314 
00315 //: Set the interaction type
00316 void
00317 bgui3d_tableau::set_interaction_type(interaction_type_enum type)
00318 {
00319   interaction_type_ = type;
00320 }
00321 
00322 //: Get the interaction type
00323 bgui3d_tableau::interaction_type_enum
00324 bgui3d_tableau::interaction_type() const
00325 {
00326   return interaction_type_;
00327 }
00328 
00329 
00330 SoSceneManager*
00331 bgui3d_tableau::scene_manager() const
00332 {
00333   if (!scene_manager_)
00334   {
00335     SoSceneManager*& sm = const_cast<SoSceneManager*&>(scene_manager_);
00336     sm = new SoSceneManager();
00337     sm->getGLRenderAction()->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_BLEND);
00338     //BLEND
00339   }
00340   return scene_manager_;
00341 }