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