2 * This file is part of the hkl3d library.
3 * inspired from logo-model.c of the GtkGLExt logo models.
4 * written by Naofumi Yasufuku <naofumi@users.sourceforge.net>
6 * The hkl library is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * The hkl library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
19 * Copyright (C) 2010-2011 Synchrotron SOLEIL
20 * L'Orme des Merisiers Saint-Aubin
21 * BP 48 91192 GIF-sur-YVETTE CEDEX
23 * Authors: Oussama Sboui <oussama.sboui@synchrotron-soleil.fr>
24 * Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
31 public class Hkl3D
.Gui
.Scene
: Gtk
.DrawingArea
33 // Invalidate whole window.
34 public void invalidate()
36 this
.get_window().invalidate_rect((Gdk
.Rectangle
)this
.allocation
, false);
39 // Update window synchronously (fast).
42 this
.get_window().process_updates(false);
45 // timeout signal connection:
46 public signal void m_ConnectionTimeout();
48 // OpenGL scene related methods:
49 public bool BulletDraw_is_enabled()
51 return this
.m_Model
.bullet
;
54 public bool wireframe_is_enabled()
56 return this
.m_Model
.wireframe
;
59 public bool aabbBoxDraw_is_enabled()
61 return this
.m_Model
.aabb
;
65 private Gtk
.Menu m_Menu
;
67 // OpenGL scene related objects:
68 Hkl3D
.Gui
.View m_View
;
69 Hkl3D
.Gui
.ModelDraw m_Model
;
71 private static const uint TIMEOUT_INTERVAL
= 100000000;
73 private const float CLEAR_COLOR
[4] = { 0.9f
, 0.8f
, 0.6f
, 1.0f
};
74 private const float CLEAR_DEPTH
= 1.0f
;
76 private const float LIGHT0_POSITION
[4] = { 0.0f
, 0.0f
, 30.0f
, 0.0f
};
77 private const float LIGHT0_DIFFUSE
[4] = { 1.0f
, 1.0f
, 1.0f
, 1.0f
};
78 private const float LIGHT0_SPECULAR
[4] = { 1.0f
, 1.0f
, 1.0f
, 1.0f
};
80 public Scene(Hkl3D
.Anticollision hkl3d
,
81 bool enableBulletDraw
, bool enableWireframe
,
82 bool enableAAbbBoxDraw
, bool enableOrthoView
)
84 this
.m_View
= new Hkl3D
.Gui
.View();
86 this
.m_Model
= new Hkl3D
.Gui
.ModelDraw(hkl3d
,
87 enableBulletDraw
, enableWireframe
,
88 enableAAbbBoxDraw
, enableOrthoView
);
90 Gdk
.GLConfig? glconfig
= new Gdk
.GLConfig
.by_mode (Gdk
.GLConfigMode
.RGB
91 | Gdk
.GLConfigMode
.DEPTH
92 | Gdk
.GLConfigMode
.DOUBLE
);
94 if (glconfig
== null) {
95 stderr
.printf("*** Cannot find the double-buffered visual.\n");
96 stderr
.printf("*** Trying single-buffered visual.\n");
98 // Try single-buffered visual
99 glconfig
= new Gdk
.GLConfig
.by_mode(Gdk
.GLConfigMode
.RGB
100 | Gdk
.GLConfigMode
.DEPTH
);
101 if (glconfig
== null) {
102 stderr
.printf("*** Cannot find any OpenGL-capable visual.\n");
107 // Set OpenGL-capability to the widget.
109 Gtk
.WidgetGL
.set_gl_capability(this
, glconfig
, null, true,
110 GLRenderType
.RGBA_TYPE
);
115 this
.add_events (Gdk
.EventMask
.BUTTON_PRESS_MASK
116 | Gdk
.EventMask
.BUTTON1_MOTION_MASK
117 | Gdk
.EventMask
.BUTTON2_MOTION_MASK
118 | Gdk
.EventMask
.VISIBILITY_NOTIFY_MASK
);
120 // View transformation signals.
121 //this.button_press_event.connect(m_View.on_button_press_event);
122 //this.motion_notify_event.connect(m_View.on_motion_notify_event);
123 //this.scroll_event.connect(m_View.on_scroll_event);
125 this
.m_Menu
= this
.create_popup_menu();
128 public override void realize()
130 // We need to call the base on_realize()
136 var gldrawable
= Gtk
.WidgetGL
.get_gl_drawable(this
);
141 // *** OpenGL BEGIN ***
142 if (!gldrawable
.gl_begin(Gtk
.WidgetGL
.get_gl_context(this
)))
145 glClearColor(CLEAR_COLOR
[0], CLEAR_COLOR
[1], CLEAR_COLOR
[2], CLEAR_COLOR
[3]);
146 glClearDepth(CLEAR_DEPTH
);
148 glLightfv(GL_LIGHT0
, GL_POSITION
, LIGHT0_POSITION
);
149 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, LIGHT0_DIFFUSE
);
150 glLightfv(GL_LIGHT0
, GL_SPECULAR
, LIGHT0_SPECULAR
);
152 glEnable(GL_LIGHTING
);
155 glEnable(GL_DEPTH_TEST
);
157 glShadeModel(GL_SMOOTH
);
162 // *** OpenGL END ***
165 public override bool configure_event(Gdk
.EventConfigure event
)
170 var gldrawable
= Gtk
.WidgetGL
.get_gl_drawable(this
);
175 // *** OpenGL BEGIN ***
177 if (!gldrawable
.gl_begin(Gtk
.WidgetGL
.get_gl_context(this
)))
180 this
.m_View
.frustum((GL
.GLsizei
)this
.allocation
.width
, (GL
.GLsizei
)this
.allocation
.height
);
182 // *** OpenGL END ***
187 public override bool expose_event(Gdk
.EventExpose event
)
192 var gldrawable
= Gtk
.WidgetGL
.get_gl_drawable(this
);
197 // *** OpenGL BEGIN ***
198 if (!gldrawable
.gl_begin(Gtk
.WidgetGL
.get_gl_context(this
)))
201 glClear(GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
205 // View transformation.
212 if (gldrawable
.is_double_buffered())
213 gldrawable
.swap_buffers();
218 // *** OpenGL END ***
223 public override bool button_press_event(Gdk
.EventButton event
)
225 if (event
.button
== 3) {
226 this
.m_Menu
.popup(null, null, null, event
.button
, event
.time
);
234 public override bool map_event(Gdk
.Event event
)
236 if (this
.m_Model
.bullet
)
242 public override bool unmap_event(Gdk
.Event event
)
244 this
.timeout_remove();
249 public override bool visibility_notify_event(Gdk
.Event event
)
251 if (this
.m_Model
.bullet
) {
252 //if (event.state == GDK_VISIBILITY_FULLY_OBSCURED)
254 // this.timeout_add();
259 public bool on_timeout()
261 // Invalidate whole window.
263 // Update window synchronously (fast).
269 public void timeout_add()
272 if (!m_ConnectionTimeout.connected())
273 GLib.timeout().connect(this.on_timeout, this.TIMEOUT_INTERVAL);
275 m_ConnectionTimeout = Glib::signal_timeout().connect(
276 sigc::mem_fun(*this, &Scene::on_timeout), TIMEOUT_INTERVAL);
280 public void timeout_remove()
283 if (this.m_ConnectionTimeout.connected())
284 m_ConnectionTimeout.disconnect();
288 public void bulletDraw()
290 if (this
.m_Model
.bullet
) {
291 this
.m_Model
.bullet
= false;
292 this
.timeout_remove();
294 this
.m_Model
.bullet
= true;
299 public void wireframe_view()
301 this
.m_Model
.wireframe
= !this
.m_Model
.wireframe
;
304 public void orthoView()
306 if (this
.m_Model
.ortho
){
307 this
.m_View
.frustum((GL
.GLsizei
)this
.allocation
.width
, (GL
.GLsizei
)this
.allocation
.height
);
308 this
.m_Model
.ortho
= false;
310 this
.m_View
.ortho((GL
.GLsizei
)this
.allocation
.width
, (GL
.GLsizei
)this
.allocation
.height
);
311 this
.m_Model
.ortho
= true;
315 public void AAbbBoxDraw()
317 if (this
.m_Model
.aabb
) {
318 this
.m_Model
.aabb
= false;
319 if (this
.m_Model
.bullet
)
322 this
.timeout_remove();
324 this
.m_Model
.aabb
= true;
329 public void init_anim()
332 this
.m_Model
.reset_anim();
337 Gtk
.Menu
create_popup_menu()
339 Gtk
.Menu menu
= new Gtk
.Menu();
341 //Gtk.Menu.MenuList menu_list = menu.items();
343 // Enable/Disable Bullet Draw
346 Gtk::Menu_Helpers::MenuElem("Enable/Disable Bullet Draw",
347 sigc::mem_fun(*this, &Scene::bulletDraw)));
350 Gtk::Menu_Helpers::MenuElem("Wireframe",
351 sigc::mem_fun(*this, &Scene::wireframe_view)));
354 Gtk::Menu_Helpers::MenuElem("Enable/Disable Ortho View",
355 sigc::mem_fun(*this, &Scene::orthoView)));
358 Gtk::Menu_Helpers::MenuElem("Render AABB box",
359 sigc::mem_fun(*this, &Scene::AAbbBoxDraw)));
362 Gtk::Menu_Helpers::MenuElem("Initialize",
363 sigc::mem_fun(*this, &Scene::init_anim)));
367 Gtk::Menu_Helpers::MenuElem("Quit",
368 sigc::ptr_fun(&Gtk::Main::quit)));
373 } // namespace Hkl3dGui