X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=src%2Fgis-opengl.c;h=866eac8c15f67e6dc7ec89a557c11ee8e645ff27;hb=6ed798102c4b8c630188f1683e040e5d25128370;hp=4d3b7e4b98b212552f1a151dba83ed399e78d42f;hpb=f510823bdc5b77fa0c5336ad608f13f251a0ada5;p=grits diff --git a/src/gis-opengl.c b/src/gis-opengl.c index 4d3b7e4..866eac8 100644 --- a/src/gis-opengl.c +++ b/src/gis-opengl.c @@ -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);