summaryrefslogtreecommitdiff
path: root/src/gpudataviz.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpudataviz.cc')
-rw-r--r--src/gpudataviz.cc184
1 files changed, 128 insertions, 56 deletions
diff --git a/src/gpudataviz.cc b/src/gpudataviz.cc
index 6f1ebd0..eef7e5c 100644
--- a/src/gpudataviz.cc
+++ b/src/gpudataviz.cc
@@ -3,7 +3,7 @@
#include "gpudataviz.h"
#include "boring_parts.h"
#include "gtk_win_main.h"
-#include "my_gtk_gl_scene.h"
+#include "my_gtk_gl_scene_widget.h"
// Macro to make things readable in main() function
#define EXIT_IF_FAIL(val, expr) do { \
@@ -13,6 +13,7 @@
} \
} while(0)
+// For understanding the event sequences
#define CALL_TRACE do { \
std::cout << "trace " <<__PRETTY_FUNCTION__ << std::endl; \
} while(0)
@@ -27,9 +28,9 @@ int main(int argc, char* argv[]) {
Gtk::GL::init(argc, argv); // gtkglextmm
// Query and print OpenGL version
- int glVersionMajor, glVersionMinor;
- EXIT_IF_FAIL(1, Gdk::GL::query_version(glVersionMajor, glVersionMinor) );
- std::cout << "OpenGL extension version - " << glVersionMajor << "." << glVersionMinor << std::endl;
+ int glVersionMajor, glVersionMinor;
+ EXIT_IF_FAIL(1, Gdk::GL::query_version(glVersionMajor, glVersionMinor) );
+ std::cout << "OpenGL extension version - " << glVersionMajor << "." << glVersionMinor << std::endl;
// Initialize OpenGL
Gdk::GL::ConfigMode glMode = Gdk::GL::MODE_RGB | Gdk::GL::MODE_DEPTH | Gdk::GL::MODE_DOUBLE;
@@ -44,7 +45,7 @@ int main(int argc, char* argv[]) {
EXIT_IF_FAIL(4, hostWorkMem);
// Initialize the OpenGL scene
- MyGTKGLScene glScene(glconfig);
+ MyGTKGLSceneWidget glScene(glconfig);
// Instantiate and run the GTK app
GTKWinMain gtkwinmain(glScene);
@@ -53,28 +54,27 @@ int main(int argc, char* argv[]) {
return 0;
}
-/* MyGTKGLScene implementation
+/* MyGTKGLSceneWidget implementation
I want to keep interesting code part in this file
in natural reading order
*/
-MyGTKGLScene::MyGTKGLScene(Glib::RefPtr<Gdk::GL::Config> &glconfig) {
- CALL_TRACE;
- set_gl_capability(glconfig); // Set OpenGL-capability to the widget.
+MyGTKGLSceneWidget::MyGTKGLSceneWidget(Glib::RefPtr<Gdk::GL::Config> &glconfig) {
+ set_gl_capability(glconfig);
+ Gdk::EventMask mask = Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK;
+ set_events(mask); // The containing window should have those attributes too
}
-MyGTKGLScene::~MyGTKGLScene() {
- CALL_TRACE;
-}
+MyGTKGLSceneWidget::~MyGTKGLSceneWidget() { }
-void MyGTKGLScene::on_size_request(Gtk::Requisition* requisition) {
- CALL_TRACE;
-
- *requisition = Gtk::Requisition();
- requisition->width = 320; requisition->height = 240;
+void MyGTKGLSceneWidget::on_size_request(Gtk::Requisition* requisition) {
+ CALL_TRACE; // Technical stuff : GTK call this to ask the widget minimal size
+ *requisition = Gtk::Requisition();
+ requisition->width = 320; requisition->height = 240;
}
-void MyGTKGLScene::on_realize() {
- CALL_TRACE; // This run once at window creation time
+void MyGTKGLSceneWidget::on_realize() {
+ CALL_TRACE; // This one runs once at window creation time
+ // It's time to setup GL things that don't change on each frame
Gtk::DrawingArea::on_realize();
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
@@ -85,12 +85,14 @@ void MyGTKGLScene::on_realize() {
return;
}
+ // Programmatically create rendering lists : opengl will able to replay that efficiently
GLUquadricObj* qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_FILL);
glNewList(1, GL_COMPILE);
gluSphere(qobj, 1.0, 20, 20);
glEndList();
+ // Setup scene envrionnement
static GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0};
static GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
@@ -101,69 +103,139 @@ void MyGTKGLScene::on_realize() {
glClearColor(1.0, 1.0, 1.0, 1.0);
glClearDepth(1.0);
-/*
- glViewport(0, 0, get_width(), get_height());
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(40.0, 1.0, 1.0, 10.0);
- glMatrixMode(GL_MODELVIEW);
-*/
- glLoadIdentity();
- gluLookAt(0.0, 0.0, 3.0,
- 0.0, 0.0, 0.0,
- 0.0, 1.0, 0.0);
- glTranslatef(0.0, 0.0, -3.0);
-
+
+ // Projection setup is done at on_configure_event
+ // Camera setup (ie initial MODELVIEW matrix) is done at on_expose_event
+
glwindow->gl_end();
// *** OpenGL END ***
}
-bool MyGTKGLScene::on_configure_event(GdkEventConfigure* event) {
- CALL_TRACE ; // This run mainly when GTK GL Widget is resized
+bool MyGTKGLSceneWidget::on_configure_event(GdkEventConfigure* event) {
+ CALL_TRACE ; // This one runs mainly when GTK GL Widget is resized
+ // See boring_parts.cc. In short : gluPerspective(60.0, aspect, 0.1, 10.0);
+ return updateGLProjectionMatrix(get_gl_context(), get_gl_window(), get_width(), get_height());
+}
+
+bool MyGTKGLSceneWidget::on_expose_event(GdkEventExpose* event) {
+ CALL_TRACE ; // This one runs mainly when GTK GL Widget have to be redrawn
Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
+
// *** OpenGL BEGIN ***
if (!glwindow->gl_begin(get_gl_context())) {
std::cerr << "Oups : glwindow->gl_begin(get_gl_context())" << std::endl;
return false;
}
- int width = get_width();
- int height = get_height();
- GLdouble ratio = (GLdouble) width/height;
- glViewport(0, 0, width, height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(60.0, ratio, 0.1, 10.0);
+ //Camera position update
glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ gluLookAt(0.0, 0.0, 3.0,
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+ glTranslatef(0.0, 0.0, -3.0);
+
+ // Drawing all the stuff
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glCallList(1);
glwindow->gl_end();
// *** OpenGL END ***
+ glwindow->swap_buffers(); // Display the rendered image
+
return true;
}
-bool MyGTKGLScene::on_expose_event(GdkEventExpose* event) {
- CALL_TRACE ; // This run mainly when GTK GL Widget have to be redrawn
+bool MyGTKGLSceneWidget::on_motion_notify_event (GdkEventMotion *event) {
+ return do_mouse_logic(event->type, event->state, event->x, event->y);
+}
- Glib::RefPtr<Gdk::GL::Window> glwindow = get_gl_window();
+bool MyGTKGLSceneWidget::on_button_press_event(GdkEventButton *event) {
+ return do_mouse_logic(event->type, event->state, event->x, event->y);
+}
- // *** OpenGL BEGIN ***
- if (!glwindow->gl_begin(get_gl_context())) {
- std::cerr << "Oups : glwindow->gl_begin(get_gl_context())" << std::endl;
- return false;
+bool MyGTKGLSceneWidget::on_button_release_event(GdkEventButton *event) {
+ return do_mouse_logic(event->type, event->state, event->x, event->y);
+}
+
+#define KEYBOARD_MODIFIERS ( \
+ GDK_SHIFT_MASK | GDK_LOCK_MASK | GDK_CONTROL_MASK \
+ | GDK_SUPER_MASK | GDK_HYPER_MASK | GDK_META_MASK \
+)
+/* | GDK_MOD1_MASK | GDK_MOD2_MASK | GDK_MOD3_MASK | GDK_MOD4_MASK |GDK_MOD5_MASK \ */
+
+#define MOUSE_CLIC(button, allowed_modifier_mask) if ( \
+ type == GDK_BUTTON_RELEASE \
+ && ( state & button ) == button \
+ && ( ( state & KEYBOARD_MODIFIERS ) & ~allowed_modifier_mask ) == 0 \
+)
+#define MOUSE_DOUBLECLIC(state_mask) if ( \
+ type == GDK_BUTTON_RELEASE \
+ && ( state & state_mask ) == state_mask \
+ && prev_type == GDK_2BUTTON_PRESS \
+)
+#define MOUSE_DRAGING(state_mask) if ( \
+ ( type == GDK_BUTTON_PRESS || type == GDK_MOTION_NOTIFY ) \
+ && ( state & state_mask ) == state_mask \
+)
+#define MOUSE_DRAG_END(state_mask) if ( \
+ type == GDK_BUTTON_RELEASE \
+ && ( state & state_mask ) == state_mask \
+)
+
+bool MyGTKGLSceneWidget::do_mouse_logic(GdkEventType type, guint state, guint x, guint y) {
+/*
+ * type : the type of the event.
+ * Simple motion : GDK_MOTION_NOTIFY (3)
+ * Simple clic : GDK_BUTTON_PRESS then GDK_BUTTON_RELEASE (4 then 7)
+ * Double clic : GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE, GDK_BUTTON_PRESS, GDK_2BUTTON_PRESS, GDK_BUTTON_RELEASE (4 7 4 5 7)
+ *
+ * stat : a bit-mask representing the state of the modifier keys and the pointer buttons.
+ * GDK_BUTTON1_MASK, ... , GDK_BUTTON5_MASK (mouse buttons)
+ * GDK_SHIFT_MASK, GDK_LOCK_MASK, GDK_CONTROL_MASK (keyboard standard modifier keys)
+ * GDK_MOD1_MASK, ... (normally MOD1 it is the Alt key)
+ * GDK_SUPER_MASK, GDK_HYPER_MASK, GDK_META_MASK (extra keybord modifier keys)
+ */
+ static GdkEventType prev_type = GDK_NOTHING;
+// static guint prev_state= 0; // Empty mask
+//
+ std::cout << "event type " << type << " state " << state << " on (" << x << "," << y << ") " << std::endl;
+// std::cout << "DEBUG ( state & KEYBOARD_MODIFIERS ) == " << ( state & KEYBOARD_MODIFIERS ) << std::endl;
+
+
+ /* *** BEGIN event filtering *** */
+ MOUSE_DOUBLECLIC(GDK_BUTTON1_MASK) {
+ std::cout << "Mouse 1 double clic" << std::endl;
}
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glCallList(1);
+ MOUSE_DRAGING(GDK_BUTTON2_MASK) {
+ std::cout << "Mouse 2 dragging" << " on (" << x << "," << y << ") " << std::endl;
+ }
- glwindow->gl_end();
- // *** OpenGL END ***
+ MOUSE_CLIC(GDK_BUTTON3_MASK, 0) {
+ std::cout << "Mouse 3 clic without any key modifier" << std::endl;
+ }
+
+ //FIXME : this is buggy !!!
+ MOUSE_CLIC(GDK_BUTTON3_MASK, GDK_SHIFT_MASK) {
+ std::cout << "Mouse 3 clic with shift or control" << std::endl;
+ }
- // Display the rendered image
- glwindow->swap_buffers();
+ /* *** END event filtering *** */
+
+ // Previous button event retention for double-clic filtering
+ switch(type) {
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_2BUTTON_PRESS:
+ prev_type=type;
+// prev_state=state;
+ break;
+ default:
+ break;
+ }
return true;
}
-