]> Pileus Git - grits/blobdiff - src/grits-opengl.c
Add support for GTK 3
[grits] / src / grits-opengl.c
index 709e6ed80976b2d8be22bcf20537f31511651e54..2bd00822cea22ace1b4776aba045d3cf6ac2f909 100644 (file)
@@ -40,6 +40,8 @@
 
 // #define ROAM_DEBUG
 
+#define OVERLAY_SLICE 0.01
+
 /* Tessellation, "finding intersecting triangles" */
 /* http://research.microsoft.com/pubs/70307/tr-2006-81.pdf */
 /* http://www.opengl.org/wiki/Alpha_Blending */
@@ -66,8 +68,10 @@ static void _set_projection(GritsOpenGL *opengl)
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
 
-       double width  = GTK_WIDGET(opengl)->allocation.width;
-       double height = GTK_WIDGET(opengl)->allocation.height;
+       GtkAllocation alloc;
+       gtk_widget_get_allocation(GTK_WIDGET(opengl), &alloc);
+       double width  = alloc.width;
+       double height = alloc.height;
        double ang    = atan((height/2)/FOV_DIST)*2;
        double atmos  = 100000;
        double near   = MAX(elev*0.75 - atmos, 50); // View 100km of atmosphere
@@ -217,9 +221,11 @@ static gint run_picking(GritsOpenGL *opengl, GdkEvent *event,
 
 static gboolean run_mouse_move(GritsOpenGL *opengl, GdkEventMotion *event)
 {
-       gdouble height = GTK_WIDGET(opengl)->allocation.height;
+       GtkAllocation alloc;
+       gtk_widget_get_allocation(GTK_WIDGET(opengl), &alloc);
+
        gdouble gl_x   = event->x;
-       gdouble gl_y   = height - event->y;
+       gdouble gl_y   = alloc.height - event->y;
        gdouble delta  = opengl->pickmode ? 200 : 2;
 
        if (opengl->pickmode) {
@@ -290,7 +296,7 @@ static gboolean run_mouse_move(GritsOpenGL *opengl, GdkEventMotion *event)
 static gboolean on_motion_notify(GritsOpenGL *opengl, GdkEventMotion *event, gpointer _)
 {
        opengl->mouse_queue = *event;
-       gtk_widget_queue_draw(GTK_WIDGET(opengl));
+       grits_viewer_queue_draw(GRITS_VIEWER(opengl));
        return FALSE;
 }
 
@@ -312,18 +318,19 @@ static void _draw_level(gpointer _level, gpointer _opengl)
                /* Enable depth and alpha for world levels */
                glEnable(GL_ALPHA_TEST);
                glAlphaFunc(GL_GREATER, 0.1);
+               glDepthRange(OVERLAY_SLICE, 1);
        } else {
-               /* Disable depth for Overlay/HUD levels */
-               glDepthMask(FALSE);
+               /* Draw overlay in front of world */
+               glDepthRange(0, OVERLAY_SLICE);
        }
 
        /* Start ortho */
        if (level->num >= GRITS_LEVEL_HUD) {
+               GtkAllocation alloc;
+               gtk_widget_get_allocation(GTK_WIDGET(opengl), &alloc);
                glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity();
                glMatrixMode(GL_MODELVIEW);  glPushMatrix(); glLoadIdentity();
-               gint win_width  = GTK_WIDGET(opengl)->allocation.width;
-               gint win_height = GTK_WIDGET(opengl)->allocation.height;
-               glOrtho(0, win_width, win_height, 0, 1000, -1000);
+               glOrtho(0, alloc.width, alloc.height, 0, 1000, -1000);
        }
 
        /* Draw unsorted objects without depth testing,
@@ -353,12 +360,12 @@ static void _draw_level(gpointer _level, gpointer _opengl)
                        nunsorted, nsorted);
 }
 
-static gboolean on_expose(GritsOpenGL *opengl, GdkEventExpose *event, gpointer _)
+static gboolean on_expose(GritsOpenGL *opengl, gpointer data, gpointer _)
 {
        g_debug("GritsOpenGL: on_expose - begin");
 
        if (opengl->pickmode)
-               return run_mouse_move(opengl, (GdkEventMotion*)event);
+               return run_mouse_move(opengl, &(GdkEventMotion){});
 
        if (opengl->mouse_queue.type != GDK_NOTHING) {
                run_mouse_move(opengl, &opengl->mouse_queue);
@@ -371,8 +378,10 @@ static gboolean on_expose(GritsOpenGL *opengl, GdkEventExpose *event, gpointer _
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 #ifndef ROAM_DEBUG
+       g_mutex_lock(&opengl->sphere_lock);
        roam_sphere_update_errors(opengl->sphere);
        roam_sphere_split_merge(opengl->sphere);
+       g_mutex_unlock(&opengl->sphere_lock);
 #endif
 
 #ifdef ROAM_DEBUG
@@ -394,24 +403,24 @@ static gboolean on_expose(GritsOpenGL *opengl, GdkEventExpose *event, gpointer _
 static gboolean on_key_press(GritsOpenGL *opengl, GdkEventKey *event, gpointer _)
 {
        g_debug("GritsOpenGL: on_key_press - key=%x, state=%x, plus=%x",
-                       event->keyval, event->state, GDK_plus);
+                       event->keyval, event->state, GDK_KEY_plus);
 
        guint kv = event->keyval;
        /* Testing */
-       if (kv == GDK_w) {
+       if (kv == GDK_KEY_w) {
                opengl->wireframe = !opengl->wireframe;
-               gtk_widget_queue_draw(GTK_WIDGET(opengl));
+               grits_viewer_queue_draw(GRITS_VIEWER(opengl));
        }
-       if (kv == GDK_p) {
+       if (kv == GDK_KEY_p) {
                opengl->pickmode = !opengl->pickmode;
-               gtk_widget_queue_draw(GTK_WIDGET(opengl));
+               grits_viewer_queue_draw(GRITS_VIEWER(opengl));
        }
 #ifdef ROAM_DEBUG
-       else if (kv == GDK_n) roam_sphere_split_one(opengl->sphere);
-       else if (kv == GDK_p) roam_sphere_merge_one(opengl->sphere);
-       else if (kv == GDK_r) roam_sphere_split_merge(opengl->sphere);
-       else if (kv == GDK_u) roam_sphere_update_errors(opengl->sphere);
-       gtk_widget_queue_draw(GTK_WIDGET(opengl));
+       else if (kv == GDK_KEY_n) roam_sphere_split_one(opengl->sphere);
+       else if (kv == GDK_KEY_p) roam_sphere_merge_one(opengl->sphere);
+       else if (kv == GDK_KEY_r) roam_sphere_split_merge(opengl->sphere);
+       else if (kv == GDK_KEY_u) roam_sphere_update_errors(opengl->sphere);
+       grits_viewer_queue_draw(GRITS_VIEWER(opengl));
 #endif
        return FALSE;
 }
@@ -438,7 +447,11 @@ static void on_realize(GritsOpenGL *opengl, gpointer _)
        /* Connect signals and idle functions now that opengl is fully initialized */
        gtk_widget_add_events(GTK_WIDGET(opengl), GDK_KEY_PRESS_MASK);
        g_signal_connect(opengl, "configure-event",  G_CALLBACK(_set_projection), NULL);
+#if GTK_CHECK_VERSION(3,0,0)
+       g_signal_connect(opengl, "draw",             G_CALLBACK(on_expose),       NULL);
+#else
        g_signal_connect(opengl, "expose-event",     G_CALLBACK(on_expose),       NULL);
+#endif
 
        g_signal_connect(opengl, "key-press-event",  G_CALLBACK(on_key_press),    NULL);
 
@@ -510,6 +523,7 @@ static void grits_opengl_unproject(GritsViewer *_opengl,
                glReadPixels(px, py, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &tmp);
                pz = tmp;
        }
+       pz = (pz-OVERLAY_SLICE) * (1.0/(1-OVERLAY_SLICE));
        gluUnProject(px, py, pz,
                opengl->sphere->view->model,
                opengl->sphere->view->proj,
@@ -593,7 +607,7 @@ static void _objects_free(gpointer value, gpointer _)
        g_free(level);
 }
 
-static gpointer grits_opengl_add(GritsViewer *_opengl, GritsObject *object,
+static void grits_opengl_add(GritsViewer *_opengl, GritsObject *object,
                gint num, gboolean sort)
 {
        g_assert(GRITS_IS_OPENGL(_opengl));
@@ -617,26 +631,27 @@ static gpointer grits_opengl_add(GritsViewer *_opengl, GritsObject *object,
        if (list->next)
                list->next->prev = link;
        list->next = link;
+       object->ref = link;
+       g_object_ref(object);
        g_mutex_unlock(&opengl->objects_lock);
-       return link;
 }
 
-static GritsObject *grits_opengl_remove(GritsViewer *_opengl, GritsObject *object)
+void grits_opengl_remove(GritsViewer *_opengl, GritsObject *object)
 {
        g_assert(GRITS_IS_OPENGL(_opengl));
        GritsOpenGL *opengl = GRITS_OPENGL(_opengl);
-       GList *link = object->ref;
+       if (!object->ref)
+               return;
        g_mutex_lock(&opengl->objects_lock);
+       GList *link = object->ref;
        /* Just unlink and free it, link->prev is assured */
        link->prev->next = link->next;
        if (link->next)
                link->next->prev = link->prev;
-       g_mutex_unlock(&opengl->objects_lock);
-       object->ref    = NULL;
-       object->viewer = NULL;
        g_free(link);
+       object->ref = NULL;
        g_object_unref(object);
-       return object;
+       g_mutex_unlock(&opengl->objects_lock);
 }
 
 /****************