]> Pileus Git - grits/blobdiff - src/gis-opengl.c
Fix compiler warnings
[grits] / src / gis-opengl.c
index a70c6a8ebb3e251fda82c3a24ab2b711a514d5af..ecbf47a4c140fa457de449051e88eb39696ceb00 100644 (file)
@@ -115,7 +115,9 @@ static void _set_visuals(GisOpenGL *opengl)
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        //glShadeModel(GL_FLAT);
 
+       g_mutex_lock(opengl->sphere_lock);
        roam_sphere_update_view(opengl->sphere);
+       g_mutex_unlock(opengl->sphere_lock);
 }
 
 
@@ -131,6 +133,17 @@ static void _draw_tile(GisOpenGL *opengl, GisTile *tile, GList *triangles)
                        tile->edge.n, tile->edge.s, tile->edge.e, tile->edge.w);
        //g_message("drawing %4d triangles for tile edges=%7.2f,%7.2f,%7.2f,%7.2f",
        //              g_list_length(triangles), tile->edge.n, tile->edge.s, tile->edge.e, tile->edge.w);
+       gdouble n = tile->edge.n;
+       gdouble s = tile->edge.s;
+       gdouble e = tile->edge.e;
+       gdouble w = tile->edge.w;
+
+       gdouble londist = e - w;
+       gdouble latdist = n - s;
+
+       gdouble xscale = tile->coords.e - tile->coords.w;
+       gdouble yscale = tile->coords.s - tile->coords.n;
+
        for (GList *cur = triangles; cur; cur = cur->next) {
                RoamTriangle *tri = cur->data;
 
@@ -143,14 +156,6 @@ static void _draw_tile(GisOpenGL *opengl, GisTile *tile, GList *triangles)
                        if (lon[2] > 90) lon[2] -= 360;
                }
 
-               gdouble n = tile->edge.n;
-               gdouble s = tile->edge.s;
-               gdouble e = tile->edge.e;
-               gdouble w = tile->edge.w;
-
-               gdouble londist = e - w;
-               gdouble latdist = n - s;
-
                gdouble xy[3][2] = {
                        {(lon[0]-w)/londist, 1-(lat[0]-s)/latdist},
                        {(lon[1]-w)/londist, 1-(lat[1]-s)/latdist},
@@ -175,15 +180,22 @@ static void _draw_tile(GisOpenGL *opengl, GisTile *tile, GList *triangles)
                if (lat[1] == 90 || lat[1] == -90) xy[1][0] = 0.5;
                if (lat[2] == 90 || lat[2] == -90) xy[2][0] = 0.5;
 
+               /* Scale to tile coords */
+               for (int i = 0; i < 3; i++) {
+                       xy[i][0] = tile->coords.w + xy[i][0]*xscale;
+                       xy[i][1] = tile->coords.n + xy[i][1]*yscale;
+               }
+
                glEnable(GL_TEXTURE_2D);
+               glEnable(GL_POLYGON_OFFSET_FILL);
                glBindTexture(GL_TEXTURE_2D, *(guint*)tile->data);
+               glPolygonOffset(0, -tile->zindex);
                glBegin(GL_TRIANGLES);
                glNormal3dv(tri->p.r->norm); glTexCoord2dv(xy[0]); glVertex3dv((double*)tri->p.r);
                glNormal3dv(tri->p.m->norm); glTexCoord2dv(xy[1]); glVertex3dv((double*)tri->p.m);
                glNormal3dv(tri->p.l->norm); glTexCoord2dv(xy[2]); glVertex3dv((double*)tri->p.l);
                glEnd();
        }
-       g_list_free(triangles);
 }
 
 static void _draw_tiles(GisOpenGL *opengl, GisTile *tile)
@@ -214,7 +226,8 @@ static void _draw_tiles(GisOpenGL *opengl, GisTile *tile)
                                const gdouble s = tile->edge.n-(lat_step*(row+1));
                                const gdouble e = tile->edge.w+(lon_step*(col+1));
                                const gdouble w = tile->edge.w+(lon_step*(col+0));
-                               GList *these = roam_sphere_get_intersect(opengl->sphere, FALSE, n, s, e, w);
+                               GList *these = roam_sphere_get_intersect(opengl->sphere,
+                                               FALSE, n, s, e, w);
                                triangles = g_list_concat(triangles, these);
                        }
                }
@@ -224,6 +237,7 @@ static void _draw_tiles(GisOpenGL *opengl, GisTile *tile)
        }
        if (triangles)
                _draw_tile(opengl, tile, triangles);
+       g_list_free(triangles);
 }
 
 static void _draw_marker(GisOpenGL *opengl, GisMarker *marker)
@@ -274,6 +288,10 @@ static void _draw_callback(GisOpenGL *opengl, GisCallback *callback)
 static void _draw_object(GisOpenGL *opengl, GisObject *object)
 {
        //g_debug("GisOpenGL: draw_object");
+       /* Skip hidden objects */
+       if (object->hidden)
+               return;
+
        /* Skip out of range objects */
        if (object->lod > 0) {
                /* LOD test */
@@ -306,7 +324,9 @@ static void _draw_object(GisOpenGL *opengl, GisObject *object)
        } else if (GIS_IS_TILE(object)) {
                glEnable(GL_DEPTH_TEST);
                glDepthFunc(GL_LESS);
+               g_mutex_lock(opengl->sphere_lock);
                _draw_tiles(opengl, GIS_TILE(object));
+               g_mutex_unlock(opengl->sphere_lock);
        }
        glPopAttrib();
        glMatrixMode(GL_PROJECTION); glPopMatrix();
@@ -315,7 +335,7 @@ static void _draw_object(GisOpenGL *opengl, GisObject *object)
 
 static void _load_object(GisOpenGL *opengl, GisObject *object)
 {
-       g_debug("GisOpenGL: load_object");
+       //g_debug("GisOpenGL: load_object");
        if (GIS_IS_MARKER(object)) {
                GisMarker *marker = GIS_MARKER(object);
                cairo_surface_t *surface = cairo_get_target(marker->cairo);
@@ -332,13 +352,13 @@ static void _load_object(GisOpenGL *opengl, GisObject *object)
                                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);
+               //g_debug("load_texture: %d", marker->tex);
        }
 }
 
 static void _unload_object(GisOpenGL *opengl, GisObject *object)
 {
-       g_debug("GisOpenGL: unload_object");
+       //g_debug("GisOpenGL: unload_object");
        if (GIS_IS_MARKER(object)) {
                GisMarker *marker = GIS_MARKER(object);
                glDeleteTextures(1, &marker->tex);
@@ -369,7 +389,7 @@ static gboolean on_configure(GisOpenGL *opengl, GdkEventConfigure *event, gpoint
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        double ang = atan(height/FOV_DIST);
-       gluPerspective(rad2deg(ang)*2, width/height, 1, 10*EARTH_R);
+       gluPerspective(rad2deg(ang)*2, width/height, 1000, 10*EARTH_R);
 
 #ifndef ROAM_DEBUG
        g_mutex_lock(opengl->sphere_lock);
@@ -435,7 +455,9 @@ static gboolean on_expose(GisOpenGL *opengl, GdkEventExpose *event, gpointer _)
        roam_sphere_draw(opengl->sphere);
        //roam_sphere_draw_normals(opengl->sphere);
 #else
+       g_mutex_lock(opengl->objects_lock);
        g_tree_foreach(opengl->objects, _draw_level, opengl);
+       g_mutex_unlock(opengl->objects_lock);
        if (opengl->wireframe) {
                glClear(GL_DEPTH_BUFFER_BIT);
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -456,7 +478,6 @@ static gboolean on_key_press(GisOpenGL *opengl, GdkEventKey *event, gpointer _)
                        event->keyval, event->state, GDK_plus);
 
        guint kv = event->keyval;
-       gdk_threads_leave();
        /* Testing */
        if (kv == GDK_w) {
                opengl->wireframe = !opengl->wireframe;
@@ -467,10 +488,7 @@ static gboolean on_key_press(GisOpenGL *opengl, GdkEventKey *event, gpointer _)
        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);
-       gdk_threads_enter();
        gtk_widget_queue_draw(GTK_WIDGET(opengl));
-#else
-       gdk_threads_enter();
 #endif
        return FALSE;
 }
@@ -478,7 +496,9 @@ static gboolean on_key_press(GisOpenGL *opengl, GdkEventKey *event, gpointer _)
 static gboolean _update_errors_cb(gpointer _opengl)
 {
        GisOpenGL *opengl = _opengl;
+       g_mutex_lock(opengl->sphere_lock);
        roam_sphere_update_errors(opengl->sphere);
+       g_mutex_unlock(opengl->sphere_lock);
        opengl->ue_source = 0;
        return FALSE;
 }
@@ -498,12 +518,10 @@ static void on_view_changed(GisOpenGL *opengl,
 static gboolean on_idle(GisOpenGL *opengl)
 {
        //g_debug("GisOpenGL: on_idle");
-       gdk_threads_enter();
        g_mutex_lock(opengl->sphere_lock);
        if (roam_sphere_split_merge(opengl->sphere))
                gtk_widget_queue_draw(GTK_WIDGET(opengl));
        g_mutex_unlock(opengl->sphere_lock);
-       gdk_threads_leave();
        return TRUE;
 }
 
@@ -530,7 +548,6 @@ GisViewer *gis_opengl_new(GisPlugins *plugins, GisPrefs *prefs)
 
 static void gis_opengl_center_position(GisViewer *_opengl, gdouble lat, gdouble lon, gdouble elev)
 {
-       GisOpenGL *opengl = GIS_OPENGL(_opengl);
        glRotatef(lon, 0, 1, 0);
        glRotatef(-lat, 1, 0, 0);
        glTranslatef(0, 0, elev2rad(elev));
@@ -602,6 +619,7 @@ static gpointer gis_opengl_add(GisViewer *_opengl, GisObject *object,
 {
        g_assert(GIS_IS_OPENGL(_opengl));
        GisOpenGL *opengl = GIS_OPENGL(_opengl);
+       g_mutex_lock(opengl->objects_lock);
        _load_object(opengl, object);
        struct RenderLevel *level = g_tree_lookup(opengl->objects, (gpointer)key);
        if (!level) {
@@ -610,18 +628,22 @@ static gpointer gis_opengl_add(GisViewer *_opengl, GisObject *object,
        }
        GList *list = sort ? &level->sorted : &level->unsorted;
        /* 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;
+       GList *link = g_new0(GList, 1);
+       link->data = object;
+       link->prev = list;
+       link->next = list->next;
+       if (list->next)
+               list->next->prev = link;
+       list->next = link;
+       g_mutex_unlock(opengl->objects_lock);
+       return link;
 }
 
 static GisObject *gis_opengl_remove(GisViewer *_opengl, gpointer _link)
 {
        g_assert(GIS_IS_OPENGL(_opengl));
        GisOpenGL *opengl = GIS_OPENGL(_opengl);
+       g_mutex_lock(opengl->objects_lock);
        GList *link = _link;
        GisObject *object = link->data;
        _unload_object(opengl, object);
@@ -631,6 +653,7 @@ static GisObject *gis_opengl_remove(GisViewer *_opengl, gpointer _link)
                link->next->prev = link->prev;
        g_free(link);
        g_object_unref(object);
+       g_mutex_unlock(opengl->objects_lock);
        return object;
 }
 
@@ -669,6 +692,7 @@ static void gis_opengl_init(GisOpenGL *opengl)
        g_object_unref(glconfig);
 
        opengl->objects = g_tree_new_full(_objects_cmp, NULL, NULL, _objects_free);
+       opengl->objects_lock = g_mutex_new();
        opengl->sphere = roam_sphere_new(opengl);
        opengl->sphere_lock = g_mutex_new();
 
@@ -711,6 +735,7 @@ static void gis_opengl_finalize(GObject *_opengl)
        GisOpenGL *opengl = GIS_OPENGL(_opengl);
        roam_sphere_free(opengl->sphere);
        g_tree_destroy(opengl->objects);
+       g_mutex_free(opengl->objects_lock);
        g_mutex_free(opengl->sphere_lock);
        G_OBJECT_CLASS(gis_opengl_parent_class)->finalize(_opengl);
 }