1 // This is brl/bbas/bgui3d/bgui3d_tableau.cxx
2 #include "bgui3d_tableau.h"
3 //:
4 // \file
5 
6 #include "bgui3d_translate_event.h"
7 #include "vgui/vgui_gl.h"
8 #include "vgui/vgui_macro.h"
9 #include "vgui/vgui_utils.h"
10 
11 #include <Inventor/SbColor.h>
12 #include <Inventor/SoDB.h>
13 #include <Inventor/SbViewportRegion.h>
14 #include <Inventor/nodes/SoNode.h>
15 #include <Inventor/SoSceneManager.h>
16 #include <Inventor/actions/SoGLRenderAction.h>
17 
18 
19 //: The callback called by the scene manager to initiate a redraw
20 //  Second argument might just be 0, since it's not used
21 static void
bgui3d_render_callback(void * tableau,SoSceneManager *)22 bgui3d_render_callback(void *tableau, SoSceneManager* /*mgr*/)
23 {
24   bgui3d_tableau * tab = (bgui3d_tableau *) tableau;
25   tab->request_render();
26 }
27 
28 //: The callback called by the overlay scene manager to initiate a redraw
29 //  Second argument might just be 0, since it's not used
30 static void
bgui3d_render_overlay_callback(void * tableau,SoSceneManager *)31 bgui3d_render_overlay_callback(void *tableau, SoSceneManager * /*mgr*/)
32 {
33   bgui3d_tableau * tab = (bgui3d_tableau *) tableau;
34   tab->request_render_overlay();
35 }
36 
37 //------------------------------------------------------------------
38 
39 //: Constructor - don't use this, use bgui3d_tableau_new.
bgui3d_tableau(SoNode * scene_root)40 bgui3d_tableau::bgui3d_tableau(SoNode * scene_root)
41  : scene_root_(NULL), overlay_scene_root_(NULL),
42    scene_manager_(NULL), overlay_scene_manager_(NULL),
43    idle_enabled_(false), interaction_type_(SCENEGRAPH)
44 {
45   this->set_scene_root(scene_root);
46 }
47 
48 
49 //: Destructor
~bgui3d_tableau()50 bgui3d_tableau::~bgui3d_tableau()
51 {
52   this->disable_idle();
53 
54   if (scene_root_)
55     scene_root_->unref();
56   if (overlay_scene_root_)
57     overlay_scene_root_->unref();
58 
59 #if 0 // Ming: no need to release memory of the SoSceneManager* scene_manager_ & overlay_scene_manager_
60   if (scene_manager_)         delete scene_manager_;
61   if (overlay_scene_manager_) delete overlay_scene_manager_;
62 #endif // 0
63 }
64 
65 
type_name() const66 std::string bgui3d_tableau::type_name() const {return "bgui3d_tableau";}
67 
68 
69 //: Set up OpenGL for rendering
70 void
setup_opengl() const71 bgui3d_tableau::setup_opengl() const
72 {
73   // This call is still needed on the linux side
74   glEnable(GL_DEPTH_TEST);
75 
76   vgui_utils::set_glLineWidth( 1.0 );
77   vgui_utils::set_glPointSize( 1.0 );
78 }
79 
80 
81 //: Render the scene graph (called on draw events)
82 bool
render()83 bgui3d_tableau::render()
84 {
85   if (!scene_manager_)
86     return false;
87 
88   glPushAttrib(GL_ALL_ATTRIB_BITS);
89 
90   // Set up OpenGL for Rendering
91   this->setup_opengl();
92 
93   // Update the scene manager if the viewport has changed
94   GLint vp[4];
95   vgui_utils::get_glViewport(vp);
96   SbViewportRegion vguiViewport;
97   vguiViewport.setViewportPixels(vp[0], vp[1], vp[2], vp[3]);
98 
99   if ( !(scene_manager_->getViewportRegion() == vguiViewport) ) {
100     scene_manager_->setViewportRegion(vguiViewport);
101   }
102 
103   // Reinitialize to account for changes in the OpenGL context
104   scene_manager_->reinitialize();
105 
106   // Do the rendering
107   scene_manager_->render(scene_manager_->getGLRenderAction(), false, false);
108 
109   glPopAttrib();
110 
111   return true;
112 }
113 
114 
115 //: Render the overlay scene graph (called on draw overlay events)
116 bool
render_overlay()117 bgui3d_tableau::render_overlay()
118 {
119   if (!overlay_scene_manager_)
120     return false;
121 
122   glPushAttrib(GL_ALL_ATTRIB_BITS);
123 
124   // Set up OpenGL for Rendering
125   this->setup_opengl();
126 
127   // Update the scene manager if the viewport has changed
128   GLint vp[4];
129   vgui_utils::get_glViewport(vp);
130   SbViewportRegion vguiViewport;
131   vguiViewport.setViewportPixels(vp[0], vp[1], vp[2], vp[3]);
132 
133   if ( !(overlay_scene_manager_->getViewportRegion() == vguiViewport) ) {
134     overlay_scene_manager_->setViewportRegion(vguiViewport);
135   }
136 
137   // Reinitialize to account for changes in the OpenGL context
138   overlay_scene_manager_->reinitialize();
139 
140   // Do the rendering
141   overlay_scene_manager_->render(overlay_scene_manager_->getGLRenderAction(),false,false);
142 
143   glPopAttrib();
144 
145   return true;
146 }
147 
148 
149 //: Handle vgui events
handle(const vgui_event & e)150 bool bgui3d_tableau::handle(const vgui_event& e)
151 {
152   // Handle draw events
153   if ( e.type == vgui_DRAW )
154     return this->render();
155 
156   if ( e.type == vgui_DRAW_OVERLAY )
157     return this->render_overlay();
158 
159   if (!scene_manager_)
160     return false;
161 
162   // Attempt to convert all unhandled events to SoEvents
163   // and pass the SoEvents to the scene graph for handling
164   SoDB::getSensorManager()->processDelayQueue(TRUE);
165   SoDB::getSensorManager()->processTimerQueue();
166   if ( interaction_type_ == SCENEGRAPH )
167   {
168     bool handled = false;
169     SoEvent* event = bgui3d_translate_event(e);
170     if (event) {
171       handled = scene_manager_->processEvent(event) > 0;
172       if (handled)
173         return true;
174     }
175   }
176   request_render();
177 
178   return vgui_tableau::handle(e);
179 }
180 
181 
182 bool
idle()183 bgui3d_tableau::idle()
184 {
185   SoDB::getSensorManager()->processTimerQueue();
186   SoDB::getSensorManager()->processDelayQueue(TRUE);
187   return idle_enabled_;
188 }
189 
190 
191 //: Enable handling of idle events
192 void
enable_idle()193 bgui3d_tableau::enable_idle()
194 {
195   idle_enabled_ = true;
196   this->post_idle_request();
197 }
198 
199 
200 //: Disable handling of idle events
201 void
disable_idle()202 bgui3d_tableau::disable_idle()
203 {
204   idle_enabled_ = false;
205 }
206 
207 
208 //: Returns true if idle event handling is enabled
209 bool
is_idle_enabled()210 bgui3d_tableau::is_idle_enabled()
211 {
212   return idle_enabled_;
213 }
214 
215 
216 //: Called when the scene manager requests a render action
217 void
request_render()218 bgui3d_tableau::request_render()
219 {
220   this->post_redraw();
221 }
222 
223 
224 //: Called when the overlay scene manager requests a render action
225 void
request_render_overlay()226 bgui3d_tableau::request_render_overlay()
227 {
228   this->post_overlay_redraw();
229 }
230 
231 
232 //: Set scene root node
233 void
set_scene_root(SoNode * scene_root)234 bgui3d_tableau::set_scene_root(SoNode* scene_root)
235 {
236   if (scene_root_)
237     scene_root_->unref();
238   scene_root_ = scene_root;
239   if (scene_root_)
240     scene_root_->ref();
241 
242   if (scene_root_) {
243     if (!scene_manager_)
244     {
245       scene_manager_ = new SoSceneManager();
246       scene_manager_->getGLRenderAction()->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_BLEND);
247       //DELAYED_BLEND
248     }
249     else
250       scene_manager_->deactivate();
251 
252     scene_manager_->setSceneGraph(scene_root_);
253     scene_manager_->setRenderCallback(bgui3d_render_callback, this);
254     scene_manager_->activate();
255   }
256 }
257 
258 
259 //: Set overlay scene root node
260 void
set_overlay_scene_root(SoNode * scene_root)261 bgui3d_tableau::set_overlay_scene_root(SoNode* scene_root)
262 {
263   if (overlay_scene_root_)
264     overlay_scene_root_->unref();
265   overlay_scene_root_ = scene_root;
266   if (overlay_scene_root_)
267     overlay_scene_root_->ref();
268 
269   if (overlay_scene_root_) {
270     if (!overlay_scene_manager_)
271       overlay_scene_manager_ = new SoSceneManager();
272     else
273       overlay_scene_manager_->deactivate();
274 
275     overlay_scene_manager_->setSceneGraph(scene_root_);
276     overlay_scene_manager_->setRenderCallback(bgui3d_render_overlay_callback, this);
277     overlay_scene_manager_->activate();
278   }
279 }
280 
281 
282 //: Set the scene camera
283 // creates a graphics camera from a vpgl camera (either perspective or affine)
284 bool
set_camera(const vpgl_proj_camera<double> &)285 bgui3d_tableau::set_camera(const vpgl_proj_camera<double>& /*camera*/)
286 {
287   // FIXME - not yet implemented
288   return false;
289 }
290 
291 
292 //: Get the scene camera
293 // creates a vpgl camera (either perspective or affine) from the graphics camera
294 std::unique_ptr<vpgl_proj_camera<double> >
camera() const295 bgui3d_tableau::camera() const
296 {
297   return std::unique_ptr<vpgl_proj_camera<double> >(nullptr);
298 }
299 
300 
301 void
set_viewport_region(const SbViewportRegion & region)302 bgui3d_tableau::set_viewport_region(const SbViewportRegion& region)
303 {
304   if (region.getWindowSize()[0] == -1) return;
305 
306   scene_manager_->setViewportRegion(region);
307   overlay_scene_manager_->setViewportRegion(region);
308 }
309 
310 const SbViewportRegion &
get_viewport_region() const311 bgui3d_tableau::get_viewport_region() const
312 {
313   return scene_manager()->getViewportRegion();
314 }
315 
316 //: Set the interaction type
317 void
set_interaction_type(interaction_type_enum type)318 bgui3d_tableau::set_interaction_type(interaction_type_enum type)
319 {
320   interaction_type_ = type;
321 }
322 
323 //: Get the interaction type
324 bgui3d_tableau::interaction_type_enum
interaction_type() const325 bgui3d_tableau::interaction_type() const
326 {
327   return interaction_type_;
328 }
329 
330 
331 SoSceneManager*
scene_manager() const332 bgui3d_tableau::scene_manager() const
333 {
334   if (!scene_manager_)
335   {
336     SoSceneManager*& sm = const_cast<SoSceneManager*&>(scene_manager_);
337     sm = new SoSceneManager();
338     sm->getGLRenderAction()->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_BLEND);
339     //BLEND
340   }
341   return scene_manager_;
342 }
343