]> Pileus Git - grits/blobdiff - src/gis-opengl.c
Fix various win32 runtime issues
[grits] / src / gis-opengl.c
index 4d3b7e4b98b212552f1a151dba83ed399e78d42f..866eac8c15f67e6dc7ec89a557c11ee8e645ff27 100644 (file)
@@ -85,6 +85,7 @@ static void set_visuals(GisOpenGL *self)
        gdouble rg   = MAX(0, 1-(elev/20000));
        gdouble blue = MAX(0, 1-(elev/50000));
        glClearColor(MIN(0.65,rg), MIN(0.65,rg), MIN(1,blue), 1.0f);
+       glColor4f(1, 1, 1, 1);
 
        glDisable(GL_ALPHA_TEST);
 
@@ -195,6 +196,7 @@ static gboolean on_key_press(GisOpenGL *self, GdkEventKey *event, gpointer _)
        gis_view_get_location(self->view, &lat, &lon, &elev);
        pan = MIN(elev/(EARTH_R/2), 30);
        guint kv = event->keyval;
+       gdk_threads_leave();
        if      (kv == GDK_Left  || kv == GDK_h) gis_view_pan(self->view,  0,  -pan, 0);
        else if (kv == GDK_Down  || kv == GDK_j) gis_view_pan(self->view, -pan, 0,   0);
        else if (kv == GDK_Up    || kv == GDK_k) gis_view_pan(self->view,  pan, 0,   0);
@@ -213,32 +215,45 @@ static gboolean on_key_press(GisOpenGL *self, GdkEventKey *event, gpointer _)
        else if (kv == GDK_p) roam_sphere_merge_one(self->sphere);
        else if (kv == GDK_r) roam_sphere_split_merge(self->sphere);
        else if (kv == GDK_u) roam_sphere_update_errors(self->sphere);
+       gdk_threads_enter();
        gtk_widget_queue_draw(GTK_WIDGET(self));
+#else
+       gdk_threads_enter();
 #endif
 
        return TRUE;
 }
 
+static gboolean _update_errors_cb(gpointer sphere)
+{
+       roam_sphere_update_errors(sphere);
+       return FALSE;
+}
 static void on_view_changed(GisView *view,
                gdouble _1, gdouble _2, gdouble _3, GisOpenGL *self)
 {
        g_debug("GisOpenGL: on_view_changed");
+       gdk_threads_enter();
        gis_opengl_begin(self);
        set_visuals(self);
 #ifndef ROAM_DEBUG
-       roam_sphere_update_errors(self->sphere);
+       g_idle_add_full(G_PRIORITY_HIGH_IDLE+30, _update_errors_cb, self->sphere, NULL);
+       //roam_sphere_update_errors(self->sphere);
 #endif
        gis_opengl_redraw(self);
        gis_opengl_end(self);
+       gdk_threads_leave();
 }
 
 static gboolean on_idle(GisOpenGL *self)
 {
        //g_debug("GisOpenGL: on_idle");
+       gdk_threads_enter();
        gis_opengl_begin(self);
        if (roam_sphere_split_merge(self->sphere))
                gis_opengl_redraw(self);
        gis_opengl_end(self);
+       gdk_threads_leave();
        return TRUE;
 }
 
@@ -335,6 +350,46 @@ void gis_opengl_render_tiles(GisOpenGL *opengl, GisTile *tile)
                /* No children, render this tile */
                gis_opengl_render_tile(opengl, tile);
 }
+
+void gis_opengl_set_height_func(GisOpenGL *self, GisTile *tile,
+               RoamHeightFunc height_func, gpointer user_data, gboolean update)
+{
+       if (!tile)
+               return;
+       /* TODO: get points? */
+       GList *triangles = roam_sphere_get_intersect(self->sphere,
+                       tile->edge.n, tile->edge.s, tile->edge.e, tile->edge.w);
+       for (GList *cur = triangles; cur; cur = cur->next) {
+               RoamTriangle *tri = cur->data;
+               RoamPoint *points[] = {tri->p.l, tri->p.m, tri->p.r, tri->split};
+               for (int i = 0; i < G_N_ELEMENTS(points); i++) {
+                       points[i]->height_func = height_func;
+                       points[i]->height_data = user_data;
+                       roam_point_update_height(points[i]);
+               }
+       }
+       g_list_free(triangles);
+}
+
+static void _gis_opengl_clear_height_func_rec(RoamTriangle *root)
+{
+       if (!root)
+               return;
+       RoamPoint *points[] = {root->p.l, root->p.m, root->p.r, root->split};
+       for (int i = 0; i < G_N_ELEMENTS(points); i++) {
+               points[i]->height_func = NULL;
+               points[i]->height_data = NULL;
+               roam_point_update_height(points[i]);
+       }
+       _gis_opengl_clear_height_func_rec(root->kids[0]);
+       _gis_opengl_clear_height_func_rec(root->kids[1]);
+}
+void gis_opengl_clear_height_func(GisOpenGL *self)
+{
+       for (int i = 0; i < G_N_ELEMENTS(self->sphere->roots); i++)
+               _gis_opengl_clear_height_func_rec(self->sphere->roots[i]);
+}
+
 void gis_opengl_redraw(GisOpenGL *self)
 {
        g_debug("GisOpenGL: redraw");
@@ -344,6 +399,8 @@ void gis_opengl_begin(GisOpenGL *self)
 {
        g_assert(GIS_IS_OPENGL(self));
 
+       gdk_threads_enter();
+
        GdkGLContext   *glcontext  = gtk_widget_get_gl_context(GTK_WIDGET(self));
        GdkGLDrawable  *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self));
 
@@ -355,6 +412,7 @@ 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);
+       gdk_threads_leave();
 }
 void gis_opengl_flush(GisOpenGL *self)
 {
@@ -394,7 +452,8 @@ static void gis_opengl_init(GisOpenGL *self)
        g_object_set(self, "can-focus", TRUE, NULL);
 
 #ifndef ROAM_DEBUG
-       self->sm_source = g_timeout_add(10, (GSourceFunc)on_idle, self);
+       self->sm_source[0] = g_timeout_add_full(G_PRIORITY_HIGH_IDLE+30, 33,  (GSourceFunc)on_idle, self, NULL);
+       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);
@@ -416,9 +475,13 @@ static void gis_opengl_dispose(GObject *_self)
 {
        g_debug("GisOpenGL: dispose");
        GisOpenGL *self = GIS_OPENGL(_self);
-       if (self->sm_source) {
-               g_source_remove(self->sm_source);
-               self->sm_source = 0;
+       if (self->sm_source[0]) {
+               g_source_remove(self->sm_source[0]);
+               self->sm_source[0] = 0;
+       }
+       if (self->sm_source[1]) {
+               g_source_remove(self->sm_source[1]);
+               self->sm_source[1] = 0;
        }
        if (self->sphere) {
                roam_sphere_free(self->sphere);