X-Git-Url: http://pileus.org/git/?p=grits;a=blobdiff_plain;f=src%2Fgis-opengl.c;h=65821d74038872e2f04d09d51d3dd77466b88e25;hp=f420e759394ffcac758b0dde1b28ad73180d60c3;hb=fc67f407d6493f57b5ab0ed32c4902cbf304e96b;hpb=f93aa6df36b91a106bd9be7e8dd60b83b0f6a0cb diff --git a/src/gis-opengl.c b/src/gis-opengl.c index f420e75..65821d7 100644 --- a/src/gis-opengl.c +++ b/src/gis-opengl.c @@ -30,9 +30,12 @@ #include "gis-opengl.h" #include "gis-util.h" -#include "gis-object.h" #include "roam.h" +#include "objects/gis-object.h" +#include "objects/gis-marker.h" +#include "objects/gis-callback.h" + #define FOV_DIST 2000.0 #define MPPX(dist) (4*dist/FOV_DIST) @@ -41,24 +44,6 @@ /*********** * Helpers * ***********/ -static void _gis_opengl_begin(GisOpenGL *self) -{ - g_assert(GIS_IS_OPENGL(self)); - - GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(self)); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self)); - - if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) - g_assert_not_reached(); -} - -static void _gis_opengl_end(GisOpenGL *self) -{ - g_assert(GIS_IS_OPENGL(self)); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self)); - gdk_gl_drawable_gl_end(gldrawable); -} - static void _set_visuals(GisOpenGL *self) { glMatrixMode(GL_MODELVIEW); @@ -292,7 +277,6 @@ static void _load_object(GisOpenGL *self, GisObject *object) gdouble width = cairo_image_surface_get_width(surface); gdouble height = cairo_image_surface_get_height(surface); - _gis_opengl_begin(self); glEnable(GL_TEXTURE_2D); glGenTextures(1, &marker->tex); glBindTexture(GL_TEXTURE_2D, marker->tex); @@ -304,7 +288,6 @@ static void _load_object(GisOpenGL *self, GisObject *object) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); g_debug("load_texture: %d", marker->tex); - _gis_opengl_end(self); } } @@ -313,7 +296,6 @@ static void _unload_object(GisOpenGL *self, GisObject *object) g_debug("GisOpenGL: unload_object"); if (GIS_IS_MARKER(object)) { GisMarker *marker = GIS_MARKER(object); - g_debug("delete_texture: %d", marker->tex); glDeleteTextures(1, &marker->tex); } } @@ -333,15 +315,21 @@ struct RenderLevel { static void on_realize(GisOpenGL *self, gpointer _) { g_debug("GisOpenGL: on_realize"); + + GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(self)); + GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self)); + if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) + g_assert_not_reached(); + _set_visuals(self); g_mutex_lock(self->sphere_lock); roam_sphere_update_errors(self->sphere); g_mutex_unlock(self->sphere_lock); } + static gboolean on_configure(GisOpenGL *self, GdkEventConfigure *event, gpointer _) { g_debug("GisOpenGL: on_configure"); - _gis_opengl_begin(self); double width = GTK_WIDGET(self)->allocation.width; double height = GTK_WIDGET(self)->allocation.height; @@ -359,7 +347,6 @@ static gboolean on_configure(GisOpenGL *self, GdkEventConfigure *event, gpointer g_mutex_unlock(self->sphere_lock); #endif - _gis_opengl_end(self); return FALSE; } @@ -394,7 +381,6 @@ static gboolean _draw_level(gpointer key, gpointer value, gpointer user_data) static gboolean on_expose(GisOpenGL *self, GdkEventExpose *event, gpointer _) { g_debug("GisOpenGL: on_expose - begin"); - _gis_opengl_begin(self); glClear(GL_COLOR_BUFFER_BIT); @@ -408,6 +394,7 @@ static gboolean on_expose(GisOpenGL *self, GdkEventExpose *event, gpointer _) #else g_tree_foreach(self->objects, _draw_level, self); if (self->wireframe) { + glClear(GL_DEPTH_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); roam_sphere_draw(self->sphere); } @@ -416,7 +403,6 @@ static gboolean on_expose(GisOpenGL *self, GdkEventExpose *event, gpointer _) GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self)); gdk_gl_drawable_swap_buffers(gldrawable); - _gis_opengl_end(self); g_debug("GisOpenGL: on_expose - end\n"); return FALSE; } @@ -456,13 +442,12 @@ static void on_view_changed(GisOpenGL *self, { g_debug("GisOpenGL: on_view_changed"); gdk_threads_enter(); - _gis_opengl_begin(self); _set_visuals(self); #ifndef ROAM_DEBUG - g_idle_add_full(G_PRIORITY_HIGH_IDLE+30, _update_errors_cb, self->sphere, NULL); + self->ue_source = g_idle_add_full(G_PRIORITY_HIGH_IDLE+30, + _update_errors_cb, self->sphere, NULL); //roam_sphere_update_errors(self->sphere); #endif - _gis_opengl_end(self); gdk_threads_leave(); } @@ -470,12 +455,10 @@ static gboolean on_idle(GisOpenGL *self) { //g_debug("GisOpenGL: on_idle"); gdk_threads_enter(); - _gis_opengl_begin(self); g_mutex_lock(self->sphere_lock); if (roam_sphere_split_merge(self->sphere)) gtk_widget_queue_draw(GTK_WIDGET(self)); g_mutex_unlock(self->sphere_lock); - _gis_opengl_end(self); gdk_threads_leave(); return TRUE; } @@ -561,18 +544,6 @@ static void gis_opengl_clear_height_func(GisViewer *_self) _gis_opengl_clear_height_func_rec(self->sphere->roots[i]); } -static void gis_opengl_begin(GisViewer *_self) -{ - g_assert(GIS_IS_OPENGL(_self)); - _gis_opengl_begin(GIS_OPENGL(_self)); -} - -static void gis_opengl_end(GisViewer *_self) -{ - g_assert(GIS_IS_OPENGL(_self)); - _gis_opengl_end(GIS_OPENGL(_self)); -} - static gpointer gis_opengl_add(GisViewer *_self, GisObject *object, gint key, gboolean sort) { @@ -585,29 +556,49 @@ static gpointer gis_opengl_add(GisViewer *_self, GisObject *object, g_tree_insert(self->objects, (gpointer)key, level); } GList *list = sort ? &level->sorted : &level->unsorted; - list->next = g_list_prepend(list->next, object); - return list->next; + /* Put the link in the list */ + GList *next = g_new0(GList, 1); + next->data = object; + next->prev = list; + next->next = list->next; + list->next = next; + return next; } -static void gis_opengl_remove(GisViewer *_self, gpointer _link) +static GisObject *gis_opengl_remove(GisViewer *_self, gpointer _link) { g_assert(GIS_IS_OPENGL(_self)); - GList *link = _link; GisOpenGL *self = GIS_OPENGL(_self); - _unload_object(self, link->data); - /* Just unlink and free it (blowup link to avoid warnings) */ - link = g_list_delete_link(NULL, link); + GList *link = _link; + GisObject *object = link->data; + _unload_object(self, object); + /* Just unlink and free it, link->prev is assured */ + link->prev->next = link->next; + if (link->next) + link->next->prev = link->prev; + g_free(link); + g_object_unref(object); + return object; } /**************** * GObject code * ****************/ -static int _objects_cmp(gconstpointer _a, gconstpointer _b) +static int _objects_cmp(gconstpointer _a, gconstpointer _b, gpointer _) { gint a = (int)_a, b = (int)_b; return a < b ? -1 : a > b ? 1 : 0; } +static void _objects_free(gpointer value) +{ + struct RenderLevel *level = value; + if (level->sorted.next) + g_list_free(level->sorted.next); + if (level->unsorted.next) + g_list_free(level->unsorted.next); + g_free(level); +} G_DEFINE_TYPE(GisOpenGL, gis_opengl, GIS_TYPE_VIEWER); static void gis_opengl_init(GisOpenGL *self) @@ -631,7 +622,7 @@ static void gis_opengl_init(GisOpenGL *self) GDK_KEY_PRESS_MASK); g_object_set(self, "can-focus", TRUE, NULL); - self->objects = g_tree_new(_objects_cmp); + self->objects = g_tree_new_full(_objects_cmp, NULL, NULL, _objects_free); self->sphere = roam_sphere_new(self); self->sphere_lock = g_mutex_new(); @@ -661,14 +652,18 @@ static void gis_opengl_dispose(GObject *_self) g_source_remove(self->sm_source[1]); self->sm_source[1] = 0; } - /* TODO: Cleanup/free objects tree */ + if (self->ue_source) { + g_source_remove(self->ue_source); + self->ue_source = 0; + } G_OBJECT_CLASS(gis_opengl_parent_class)->dispose(_self); } static void gis_opengl_finalize(GObject *_self) { - g_debug("GisViewer: finalize"); + g_debug("GisOpenGL: finalize"); GisOpenGL *self = GIS_OPENGL(_self); roam_sphere_free(self->sphere); + g_tree_destroy(self->objects); g_mutex_free(self->sphere_lock); G_OBJECT_CLASS(gis_opengl_parent_class)->finalize(_self); } @@ -676,6 +671,7 @@ static void gis_opengl_class_init(GisOpenGLClass *klass) { g_debug("GisOpenGL: class_init"); GObjectClass *gobject_class = G_OBJECT_CLASS(klass); + gobject_class->finalize = gis_opengl_finalize; gobject_class->dispose = gis_opengl_dispose; GisViewerClass *viewer_class = GIS_VIEWER_CLASS(klass); @@ -683,8 +679,6 @@ static void gis_opengl_class_init(GisOpenGLClass *klass) viewer_class->project = gis_opengl_project; viewer_class->clear_height_func = gis_opengl_clear_height_func; viewer_class->set_height_func = gis_opengl_set_height_func; - viewer_class->begin = gis_opengl_begin; - viewer_class->end = gis_opengl_end; viewer_class->add = gis_opengl_add; viewer_class->remove = gis_opengl_remove; }