From 33171efc37387fc1641063abd4ca4c6828653b7c Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Sun, 31 Mar 2013 10:50:36 +0000 Subject: Amélioration de la gestio nde la boucle d'events GTK (utilisation du signal idle pour le continuous_play) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///var/svn/2013-gpudataviz/trunk@25 371a6b4a-a258-45f8-9dcc-bdd82ce0ac9d --- src/gpudataviz.cpp | 91 ++++++++++++++++++++++-------------------- src/my_gtk_gl_scene_widget.hpp | 1 + 2 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/gpudataviz.cpp b/src/gpudataviz.cpp index d3b950d..3ef881e 100644 --- a/src/gpudataviz.cpp +++ b/src/gpudataviz.cpp @@ -30,8 +30,8 @@ int main(int argc, char* argv[]) { 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; Glib::RefPtr glconfig; + Gdk::GL::ConfigMode glMode = Gdk::GL::MODE_RGB | Gdk::GL::MODE_DEPTH; EXIT_IF_FAIL(2, glconfig=Gdk::GL::Config::create(glMode) ); // Initialize the OpenGL scene widget (realization came later) @@ -42,22 +42,7 @@ int main(int argc, char* argv[]) { GTKWinMain gtkwinmain(glScene); // Run the app - //gtkKit.run(gtkwinmain); - - //FIXME : handle main loop quit, maybe do that logic inside MyGTKGLSceneWidget, find bug with multiple mouse button release - while ( true ) { - while ( Gtk::Main::events_pending() ) { - Gtk::Main::iteration(false); - } - if ( glScene.continuous_play ) { - glScene.step(); - glScene.queue_draw(); - std::cout << "." << std::flush; - } else { - Gtk::Main::iteration(true); - std::cout << "!" << std::flush; - } - } + gtkKit.run(gtkwinmain); return 0; } @@ -206,10 +191,11 @@ bool MyGTKGLSceneWidget::on_expose_event(GdkEventExpose* event) { // *** OpenCL BEGIN if (this->need_recompute) { this->need_recompute=false; -// std::cout << "execKernel(\"water1\", " << this->time << ");" << std::endl; + //std::cout << "execKernel(\"water1\", " << this->time << ");" << std::endl; + //TODO : Dynamic kernel usage ? int res = this->clKit.execKernel("water1", this->time); if ( res !=0 ) std::cerr << "execKernel() has returned " << res << std::endl; -// std::cout << " -> " << res << std::endl; + //std::cout << " -> " << res << std::endl; } // *** OpenCL END @@ -236,20 +222,22 @@ bool MyGTKGLSceneWidget::on_expose_event(GdkEventExpose* event) { float s_h=this->get_height(); float t_z=this->camera.tz; -/* The comprehensible one + // Vertex alpha blending automatic tuning (if big density then high transparency) + /* The comprehensible one float c1=(1024*1024)/(m_w*m_h); float c2=(s_h*s_h)/(1024*1024); float c3=(-2*-2)/(t_z*t_z); float alpha=0.5*c1*c2*c3; if (alpha < 0.01f) alpha = 0.01f; if (alpha > 1.0f) alpha = 1.0f; - std::cout << "c1 == " << c1 << " c2 == " << c2 << " c3 == " << c3 << " alpha == " << alpha << std::endl;; -*/ + */ + //std::cout << "c1 == " << c1 << " c2 == " << c2 << " c3 == " << c3 << " alpha == " << alpha << std::endl;; -/* The optimized one */ + /* The optimized one */ float alpha=2.0f*(s_h*s_h)/(m_w*m_h)/(t_z*t_z); if (alpha < 0.01f) alpha = 0.01f; if (alpha > 1.0f) alpha = 1.0f; + //std::cout << "c1 == " << c1 << " c2 == " << c2 << " c3 == " << c3 << " alpha == " << alpha << std::endl;; glColor4f(0.40f,0.78f,0.97f,alpha); glBindBuffer(GL_ARRAY_BUFFER, this->clKit.getGLVBO()); @@ -268,8 +256,8 @@ bool MyGTKGLSceneWidget::on_expose_event(GdkEventExpose* event) { } void MyGTKGLSceneWidget::step() { - this->time += 0.01f; - this->need_recompute = true; + this->time += 0.01f; + this->need_recompute = true; } bool MyGTKGLSceneWidget::on_motion_notify_event (GdkEventMotion *event) { @@ -318,35 +306,35 @@ bool MyGTKGLSceneWidget::on_scroll_event(GdkEventScroll *event) { ( type == GDK_MOTION_NOTIFY ) \ && ( state & state_mask ) == state_mask \ ) + +//FIXME find bug with multiple mouse button release #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) - * Scroll : GDK_SCROLL (31) - * event type 31 state 144 on (475,67) - * event type 31 state 272 on (475,67) - * - * - * state : a bit-mask representing the state of the modifier keys and the pointer buttons. - * GDK_BUTTON1_MASK, ... , GDK_BUTTON5_MASK (mouse buttons) - * GDK_SCROLL_UP, GDK_SCROLL_DOWN, GDK_SCROLL_LEFT, GDK_SCROLL_RIGHT (mouse wheel scroll) - * 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) - */ + //CALL_TRACE ; // This one runs when a mouse event is catched by the GTK GL Widget + /* + * 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) + * Scroll : GDK_SCROLL (31) + * + * state : a bit-mask representing the state of the modifier keys and the pointer buttons. + * GDK_BUTTON1_MASK, ... , GDK_BUTTON5_MASK (mouse buttons) + * GDK_SCROLL_UP, GDK_SCROLL_DOWN, GDK_SCROLL_LEFT, GDK_SCROLL_RIGHT (mouse wheel scroll) + * 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 variable to hold previous mouse button event static guint drag_x=0, drag_y=0; // Static for DRAGING displacement calculus bool recompute=false; // Setting it to true will call OpenCL on next redraw bool redraw=false; // Setting it to true will queue a redraw to the widget (invalidate) - // For event filter debug (display all events) + //XXX For event filter debug (display all events) //std::cout << "event type " << type << " state " << state << " on (" << x << "," << y << ") " << std::endl; /* *** BEGIN event filtering *** */ @@ -394,6 +382,8 @@ bool MyGTKGLSceneWidget::do_mouse_logic(GdkEventType type, guint state, guint x, MOUSE_DRAG_START(GDK_BUTTON1_MASK) { this->continuous_play=true; + // The trick to have a perpetual redraw : generate a draw event in the idle signal + Glib::signal_idle().connect( sigc::mem_fun(*this, &MyGTKGLSceneWidget::on_gtk_idle) ); } MOUSE_DRAG_END(GDK_BUTTON1_MASK) { @@ -411,7 +401,7 @@ bool MyGTKGLSceneWidget::do_mouse_logic(GdkEventType type, guint state, guint x, /* *** END event filtering *** */ - // Previous button event retention for double-clic filtering + // Previous button event retention for double-clic filtering (used by the macros) if ( type == GDK_BUTTON_PRESS || type == GDK_2BUTTON_PRESS || type == GDK_BUTTON_RELEASE ) { prev_type=type; } @@ -420,3 +410,16 @@ bool MyGTKGLSceneWidget::do_mouse_logic(GdkEventType type, guint state, guint x, if ( recompute ) this->need_recompute=true; return true; } + +bool MyGTKGLSceneWidget::on_gtk_idle() { + CALL_TRACE ; // This one runs when there is no more GTK event in the current iteration + // Note : This signal is not always connected. + // Connected by Glib::signal_idle().connect() call + // Disconnected automatically if it returns false + if ( ! continuous_play ) return false; + + this->step(); + this->queue_draw(); + return true; +} + diff --git a/src/my_gtk_gl_scene_widget.hpp b/src/my_gtk_gl_scene_widget.hpp index 6196ae8..1c7e305 100644 --- a/src/my_gtk_gl_scene_widget.hpp +++ b/src/my_gtk_gl_scene_widget.hpp @@ -26,6 +26,7 @@ class MyGTKGLSceneWidget : public Gtk::DrawingArea, public Gtk::GL::Widget