]> Pileus Git - grits/blobdiff - src/gis-opengl.c
Remove properties from gis-viewer
[grits] / src / gis-opengl.c
index ec703371ada11008f5d027f6020d6b7c175cff41..b1886c2b2ce0c36b321f348ba1de50835a0a3013 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <config.h>
 #include <math.h>
+#include <string.h>
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
 #include <gtk/gtkgl.h>
@@ -29,6 +30,7 @@
 
 #include "gis-opengl.h"
 #include "gis-util.h"
+#include "gis-object.h"
 #include "roam.h"
 
 #define FOV_DIST   2000.0
@@ -57,6 +59,111 @@ static void _gis_opengl_end(GisOpenGL *self)
        gdk_gl_drawable_gl_end(gldrawable);
 }
 
+
+/********************
+ * Object handleing *
+ ********************/
+static void _draw_marker(GisOpenGL *self, GisMarker *marker)
+{
+       GisPoint *point = gis_object_center(GIS_OBJECT(marker));
+       gdouble px, py, pz;
+       gis_viewer_project(GIS_VIEWER(self),
+                       point->lat, point->lon, point->elev,
+                       &px, &py, &pz);
+
+       g_debug("GisOpenGL: draw_marker - texture=%d", marker->tex);
+
+       cairo_surface_t *surface = cairo_get_target(marker->cairo);
+       gdouble width  = cairo_image_surface_get_width(surface);
+       gdouble height = cairo_image_surface_get_height(surface);
+
+       glMatrixMode(GL_PROJECTION); glLoadIdentity();
+       glMatrixMode(GL_MODELVIEW);  glLoadIdentity();
+       glOrtho(0, GTK_WIDGET(self)->allocation.width,
+               0, GTK_WIDGET(self)->allocation.height, -1, 1);
+       glTranslated(px - marker->xoff,
+                    py - marker->yoff, 0);
+
+       glDisable(GL_LIGHTING);
+       glDisable(GL_COLOR_MATERIAL);
+       glDisable(GL_DEPTH_TEST);
+       glEnable(GL_TEXTURE_2D);
+       glBindTexture(GL_TEXTURE_2D, marker->tex);
+       g_debug("bind_texture: %d", marker->tex);
+       glBegin(GL_QUADS);
+       glTexCoord2f(1, 1); glVertex3f(width, 0     , 0);
+       glTexCoord2f(1, 0); glVertex3f(width, height, 0);
+       glTexCoord2f(0, 0); glVertex3f(0    , height, 0);
+       glTexCoord2f(0, 1); glVertex3f(0    , 0     , 0);
+       glEnd();
+}
+
+
+static void _draw_objects(GisOpenGL *self)
+{
+       g_debug("GisOpenGL: draw_objects");
+       /* Draw objects */
+       for (GList *cur = self->objects; cur; cur = cur->next) {
+               glMatrixMode(GL_PROJECTION); glPushMatrix();
+               glMatrixMode(GL_MODELVIEW);  glPushMatrix();
+               GisObject *object = cur->data;
+               switch (object->type) {
+               case GIS_TYPE_MARKER:
+                       _draw_marker(self, GIS_MARKER(object));
+                       break;
+               default:
+                       break;
+               }
+               glMatrixMode(GL_PROJECTION); glPopMatrix();
+               glMatrixMode(GL_MODELVIEW);  glPopMatrix();
+       }
+}
+
+static void _load_object(GisOpenGL *self, GisObject *object)
+{
+       g_debug("GisOpenGL: load_object");
+       switch (object->type) {
+       case GIS_TYPE_MARKER: {
+               GisMarker *marker = GIS_MARKER(object);
+               cairo_surface_t *surface = cairo_get_target(marker->cairo);
+               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);
+
+               glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+               glPixelStorei(GL_PACK_ALIGNMENT, 1);
+               glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+                               cairo_image_surface_get_data(surface));
+               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);
+               break;
+       }
+       default:
+               break;
+       }
+}
+
+static void _free_object(GisOpenGL *self, GisObject *object)
+{
+       g_debug("GisOpenGL: free_object");
+       switch (object->type) {
+       case GIS_TYPE_MARKER: {
+               GisMarker *marker = GIS_MARKER(object);
+               g_debug("delete_texture: %d", marker->tex);
+               glDeleteTextures(1, &marker->tex);
+               break;
+       }
+       default:
+               break;
+       }
+}
+
 /*************
  * ROAM Code *
  *************/
@@ -148,8 +255,9 @@ static gboolean on_configure(GisOpenGL *self, GdkEventConfigure *event, gpointer
 
        double width  = GTK_WIDGET(self)->allocation.width;
        double height = GTK_WIDGET(self)->allocation.height;
-       glViewport(0, 0, width, height);
 
+       /* Setup OpenGL Window */
+       glViewport(0, 0, width, height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        double ang = atan(height/FOV_DIST);
@@ -163,7 +271,7 @@ static gboolean on_configure(GisOpenGL *self, GdkEventConfigure *event, gpointer
        return FALSE;
 }
 
-static void on_expose_plugin(GisPlugin *plugin, gchar *name, GisOpenGL *self)
+static void _on_expose_plugin(GisPlugin *plugin, gchar *name, GisOpenGL *self)
 {
        _set_visuals(self);
        glMatrixMode(GL_PROJECTION); glPushMatrix();
@@ -180,8 +288,9 @@ static gboolean on_expose(GisOpenGL *self, GdkEventExpose *event, gpointer _)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 #ifndef ROAM_DEBUG
-       gis_plugins_foreach(GIS_VIEWER(self)->plugins, G_CALLBACK(on_expose_plugin), self);
-
+       gis_plugins_foreach(GIS_VIEWER(self)->plugins,
+                       G_CALLBACK(_on_expose_plugin), self);
+       _draw_objects(self);
        if (self->wireframe) {
                _set_visuals(self);
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -193,7 +302,6 @@ static gboolean on_expose(GisOpenGL *self, GdkEventExpose *event, gpointer _)
        glDisable(GL_TEXTURE_2D);
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
        roam_sphere_draw(self->sphere);
-
        //roam_sphere_draw_normals(self->sphere);
 #endif
 
@@ -227,8 +335,7 @@ static gboolean on_key_press(GisOpenGL *self, GdkEventKey *event, gpointer _)
 #else
        gdk_threads_enter();
 #endif
-
-       return TRUE;
+       return FALSE;
 }
 
 static gboolean _update_errors_cb(gpointer sphere)
@@ -418,6 +525,22 @@ static void gis_opengl_end(GisViewer *_self)
        _gis_opengl_end(GIS_OPENGL(_self));
 }
 
+static void gis_opengl_add(GisViewer *_self, GisObject *object)
+{
+       g_assert(GIS_IS_OPENGL(_self));
+       GisOpenGL *self = GIS_OPENGL(_self);
+       _load_object(self, object);
+       self->objects = g_list_prepend(self->objects, object);
+}
+
+static void gis_opengl_remove(GisViewer *_self, GisObject *object)
+{
+       g_assert(GIS_IS_OPENGL(_self));
+       GisOpenGL *self = GIS_OPENGL(_self);
+       _free_object(self, object);
+       self->objects = g_list_remove(self->objects, object);
+}
+
 /****************
  * GObject code *
  ****************/
@@ -450,14 +573,14 @@ static void gis_opengl_init(GisOpenGL *self)
        self->sm_source[1] = g_timeout_add_full(G_PRIORITY_HIGH_IDLE+10, 500, (GSourceFunc)on_idle, self, NULL);
 #endif
 
-       g_signal_connect(self, "realize",            G_CALLBACK(on_realize),      NULL);
-       g_signal_connect(self, "configure-event",    G_CALLBACK(on_configure),    NULL);
-       g_signal_connect(self, "expose-event",       G_CALLBACK(on_expose),       NULL);
+       g_signal_connect(self, "realize",          G_CALLBACK(on_realize),      NULL);
+       g_signal_connect(self, "configure-event",  G_CALLBACK(on_configure),    NULL);
+       g_signal_connect(self, "expose-event",     G_CALLBACK(on_expose),       NULL);
 
-       g_signal_connect(self, "key-press-event",    G_CALLBACK(on_key_press),    NULL);
+       g_signal_connect(self, "key-press-event",  G_CALLBACK(on_key_press),    NULL);
 
-       g_signal_connect(self, "location-changed",   G_CALLBACK(on_view_changed), NULL);
-       g_signal_connect(self, "rotation-changed",   G_CALLBACK(on_view_changed), NULL);
+       g_signal_connect(self, "location-changed", G_CALLBACK(on_view_changed), NULL);
+       g_signal_connect(self, "rotation-changed", G_CALLBACK(on_view_changed), NULL);
 }
 static void gis_opengl_dispose(GObject *_self)
 {
@@ -477,6 +600,12 @@ static void gis_opengl_dispose(GObject *_self)
        }
        G_OBJECT_CLASS(gis_opengl_parent_class)->dispose(_self);
 }
+static void gis_opengl_finalize(GObject *_self)
+{
+       g_debug("GisViewer: finalize");
+       GisOpenGL *self = GIS_OPENGL(_self);
+       G_OBJECT_CLASS(gis_opengl_parent_class)->finalize(_self);
+}
 static void gis_opengl_class_init(GisOpenGLClass *klass)
 {
        g_debug("GisOpenGL: class_init");
@@ -492,4 +621,6 @@ static void gis_opengl_class_init(GisOpenGLClass *klass)
        viewer_class->render_tiles      = gis_opengl_render_tiles;
        viewer_class->begin             = gis_opengl_begin;
        viewer_class->end               = gis_opengl_end;
+       viewer_class->add               = gis_opengl_add;
+       viewer_class->remove            = gis_opengl_remove;
 }