summaryrefslogtreecommitdiff
path: root/src/gpudataviz.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpudataviz.cpp')
-rw-r--r--src/gpudataviz.cpp301
1 files changed, 301 insertions, 0 deletions
diff --git a/src/gpudataviz.cpp b/src/gpudataviz.cpp
new file mode 100644
index 0000000..a9fdb8e
--- /dev/null
+++ b/src/gpudataviz.cpp
@@ -0,0 +1,301 @@
+#include <iostream>
+
+
+//#include "gtk_includes.h"
+#include "gtk_win_main.hpp"
+//#include "my_gtk_gl_scene_widget.hpp"
+#include "boring_parts.hpp"
+
+#include <gdk/x11/gdkglx.h> // X11 specific
+
+// Macro to make things readable in main() function
+#define EXIT_IF_FAIL(val, expr) do { \
+ if ( ! (expr) ) { \
+ std::cerr << "Init error " << val << std::endl; \
+ exit(val); \
+ } \
+} while(0)
+
+// For understanding the event sequences
+#define CALL_TRACE do { \
+ std::cout << "trace " <<__PRETTY_FUNCTION__ << std::endl; \
+} while(0)
+
+int main(int argc, char* argv[]) {
+ CALL_TRACE;
+
+ // Initialize GTK
+ Gtk::Main gtkKit(argc, argv); // gtk itself
+ 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;
+
+ // Initialize OpenGL
+ Gdk::GL::ConfigMode glMode = Gdk::GL::MODE_RGB | Gdk::GL::MODE_DEPTH | Gdk::GL::MODE_DOUBLE;
+ Glib::RefPtr<Gdk::GL::Config> glconfig;
+ EXIT_IF_FAIL(2, glconfig=Gdk::GL::Config::create(glMode) );
+
+ // Initialize the OpenGL scene widget (realization came later)
+ MyGTKGLSceneWidget glScene(glconfig);
+
+ // Instantiate the GTK app (and realize glScene)
+ // Could exit() the program if problem with OpenGL or OpenCL
+ GTKWinMain gtkwinmain(glScene);
+
+ // Initialize OpenCL (only after the MyGTKGLSceneWidget realize)
+ //EXIT_IF_FAIL(3, initLibs()==0 ); // See boring_parts.cc
+
+ gtkKit.run(gtkwinmain);
+
+ return 0;
+}
+
+/* MyGTKGLSceneWidget implementation
+ I want to keep interesting code part in this file
+ in natural reading order
+*/
+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
+ this->camera.rx = this->camera.ry = 0.0f; this->camera.tz = -3.0f;
+}
+
+MyGTKGLSceneWidget::~MyGTKGLSceneWidget() { }
+
+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 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
+
+ GLenum gl_res;
+
+ Gtk::DrawingArea::on_realize();
+ 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;
+ }
+
+ EXIT_IF_FAIL(3, Gdk::GL::query_gl_extension("GL_ARB_vertex_buffer_object") );
+
+ size_t mesh_width=64;
+ size_t mesh_height=64;
+ GLsizeiptr gl_vbo_data_size = mesh_width * mesh_height * sizeof(cl_float4);
+ intptr_t gl_vbo=0;
+
+ glGenBuffers(1, &gl_vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, gl_vbo);
+ /*
+ STREAM : The data store contents will be modified once and used at most a few times.
+ STATIC : The data store contents will be modified once and used many times.
+ DYNAMIC : The data store contents will be modified repeatedly and used many times.
+ */
+ glBufferData(GL_ARRAY_BUFFER, gl_vbo_data_size, NULL, GL_DYNAMIC_DRAW);
+ if ( gl_res=glGetError() ) {
+ std::cerr << "glBufferData(). Unable to allocate " << gl_vbo_data_size << "bytes in VRAM";
+ std::cerr << gluErrorString(gl_res);
+ }
+
+#ifdef HAS_OPENCL
+// static bool isOpenCLInitialized=false;
+
+// if (! isOpenCLInitialized) {
+// #ifdef X11
+ intptr_t gl_context = (intptr_t)glXGetCurrentContext();
+ intptr_t gl_display = (intptr_t)glXGetCurrentDisplay();
+
+// std::cerr << "DEBUG : begin initOpenCL()" << std::endl;
+ initOpenCL(gl_display, gl_context, gl_vbo); /* See boring_parts.cc */
+// isOpenCLInitialized=true;
+// #else
+// #error initOpenCL works only for X11 systems for now
+// #endif
+// }
+#endif
+
+
+ // 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);
+ gluSphere(qobj, 1.0, 5, 5);
+ 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);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_position);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ glClearColor(1.0, 1.0, 1.0, 1.0);
+ glClearDepth(1.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 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;
+ }
+
+ //Camera position update
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, this->camera.tz);
+ glRotatef(this->camera.rx, 1.0, 0.0, 0.0);
+ glRotatef(this->camera.ry, 0.0, 1.0, 0.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 MyGTKGLSceneWidget::on_motion_notify_event (GdkEventMotion *event) {
+ return do_mouse_logic(event->type, event->state, event->x, event->y);
+}
+
+bool MyGTKGLSceneWidget::on_button_press_event(GdkEventButton *event) {
+ return do_mouse_logic(event->type, event->state | 1<<(7+event->button) , event->x, event->y);
+}
+
+bool MyGTKGLSceneWidget::on_button_release_event(GdkEventButton *event) {
+ return do_mouse_logic(event->type, event->state, event->x, event->y);
+}
+
+#define ALL_KEYBOARD_MODIFIERS ( GDK_SHIFT_MASK | GDK_CONTROL_MASK \
+ | GDK_SUPER_MASK | GDK_HYPER_MASK | GDK_META_MASK )
+
+#define MOUSE_CLIC(button, required_modifier_mask, allowed_extra_modifier_mask) if ( \
+ type == GDK_BUTTON_RELEASE \
+ && ( state & button ) == button \
+ && ( state & required_modifier_mask ) == required_modifier_mask \
+ && ( ( state & ALL_KEYBOARD_MODIFIERS ) & ~( required_modifier_mask | allowed_extra_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_DRAG_START(state_mask) if ( \
+ type == GDK_BUTTON_PRESS \
+ && ( state & state_mask ) == state_mask \
+)
+#define MOUSE_DRAGING(state_mask) if ( \
+ ( 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 variables to hold previous mouse button event
+ static GdkEventType prev_type = GDK_NOTHING;
+ /*static guint prev_state=0; UNUSED FOR NOW */
+ static guint drag_x=0, drag_y=0;
+
+ bool redraw=false; // Setting it to true will queue a redraw to the widget (invalidate)
+
+// std::cout << "event type " << type << " state " << state << " on (" << x << "," << y << ") " << std::endl;
+
+ /* *** BEGIN event filtering *** */
+ MOUSE_DRAG_START(GDK_BUTTON2_MASK) {
+ drag_x=x; drag_y=y;
+ }
+
+ MOUSE_DRAGING(GDK_BUTTON2_MASK) {
+ float mouse_sensivity = 0.2f;
+ gint dx = drag_x - x; // Delta movement (since last event)
+ gint dy = drag_y - y; // Not unsigned !
+ // Yes dy for camera.rx, and -= operator
+ // GTK mouse coords and Opengl are not on the same coords system
+ this->camera.rx -= mouse_sensivity * dy;
+ this->camera.ry -= mouse_sensivity * dx;
+ drag_x = x; drag_y = y;
+ redraw=true;
+ }
+
+ MOUSE_CLIC(GDK_BUTTON1_MASK, 0, 0) {
+ //TODO
+ }
+
+
+ // Demo filters
+ MOUSE_CLIC(GDK_BUTTON1_MASK, GDK_SHIFT_MASK, GDK_CONTROL_MASK) {
+ std::cout << "Mouse 1 clic with shift or control-shift" << std::endl;
+ }
+
+ MOUSE_DOUBLECLIC(GDK_BUTTON3_MASK) {
+ std::cout << "Mouse 1 double clic" << std::endl;
+ }
+ /* *** 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;
+ }
+
+ if ( redraw ) queue_draw();
+ return true;
+}