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);
}
if (lat[2] == 90 || lat[2] == -90) xy[2][0] = 0.5;
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);
gis_viewer_project(GIS_VIEWER(opengl),
point->lat, point->lon, point->elev,
&px, &py, &pz);
+
+ gint win_width = GTK_WIDGET(opengl)->allocation.width;
+ gint win_height = GTK_WIDGET(opengl)->allocation.height;
+ py = win_height - py;
if (pz > 1)
return;
glMatrixMode(GL_PROJECTION); glLoadIdentity();
glMatrixMode(GL_MODELVIEW); glLoadIdentity();
- glOrtho(0, GTK_WIDGET(opengl)->allocation.width,
- 0, GTK_WIDGET(opengl)->allocation.height, -1, 1);
+ glOrtho(0, win_width, win_height, 0, -1, 1);
glTranslated(px - marker->xoff,
py - marker->yoff, 0);
glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, marker->tex);
+ glDisable(GL_CULL_FACE);
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);
+ glTexCoord2f(1, 0); glVertex3f(width, 0 , 0);
+ glTexCoord2f(1, 1); glVertex3f(width, height, 0);
+ glTexCoord2f(0, 1); glVertex3f(0 , height, 0);
+ glTexCoord2f(0, 0); glVertex3f(0 , 0 , 0);
glEnd();
}
//g_debug("GisOpenGL: draw_object");
/* Skip out of range objects */
if (object->lod > 0) {
+ /* LOD test */
gdouble eye[3], obj[3];
gis_viewer_get_location(GIS_VIEWER(opengl), &eye[0], &eye[1], &eye[2]);
+ gdouble elev = eye[2];
lle2xyz(eye[0], eye[1], eye[2], &eye[0], &eye[1], &eye[2]);
lle2xyz(object->center.lat, object->center.lon, object->center.elev,
&obj[0], &obj[1], &obj[2]);
gdouble dist = distd(obj, eye);
if (object->lod < dist)
return;
+
+ /* Horizon testing */
+ gdouble c = EARTH_R+elev;
+ gdouble a = EARTH_R;
+ gdouble horizon = sqrt(c*c - a*a);
+ if (dist > horizon)
+ return;
}
/* Draw */
} 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();
GList sorted;
};
-static void on_realize(GisOpenGL *opengl, gpointer _)
-{
- g_debug("GisOpenGL: on_realize");
-
- GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(opengl));
- GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(opengl));
- if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
- g_assert_not_reached();
-
- _set_visuals(opengl);
- g_mutex_lock(opengl->sphere_lock);
- roam_sphere_update_errors(opengl->sphere);
- g_mutex_unlock(opengl->sphere_lock);
-}
-
static gboolean on_configure(GisOpenGL *opengl, GdkEventConfigure *event, gpointer _)
{
g_debug("GisOpenGL: on_configure");
return FALSE;
}
+static void on_realize(GisOpenGL *opengl, gpointer _)
+{
+ g_debug("GisOpenGL: on_realize");
+
+ GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(opengl));
+ GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(opengl));
+ if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
+ g_assert_not_reached();
+
+ _set_visuals(opengl);
+ on_configure(opengl, NULL, NULL);
+}
+
static gboolean _draw_level(gpointer key, gpointer value, gpointer user_data)
{
g_debug("GisOpenGL: _draw_level - level=%-4d", (int)key);
return FALSE;
}
-static gboolean _update_errors_cb(gpointer sphere)
+static gboolean _update_errors_cb(gpointer _opengl)
{
- roam_sphere_update_errors(sphere);
+ 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;
}
static void on_view_changed(GisOpenGL *opengl,
g_debug("GisOpenGL: on_view_changed");
_set_visuals(opengl);
#ifndef ROAM_DEBUG
- opengl->ue_source = g_idle_add_full(G_PRIORITY_HIGH_IDLE+30,
- _update_errors_cb, opengl->sphere, NULL);
+ if (!opengl->ue_source)
+ opengl->ue_source = g_idle_add_full(G_PRIORITY_HIGH_IDLE+30,
+ _update_errors_cb, opengl, NULL);
//roam_sphere_update_errors(opengl->sphere);
#endif
}
g_assert(GIS_IS_OPENGL(_opengl));
GisOpenGL *opengl = GIS_OPENGL(_opengl);
_load_object(opengl, object);
+ g_mutex_lock(opengl->objects_lock);
struct RenderLevel *level = g_tree_lookup(opengl->objects, (gpointer)key);
if (!level) {
level = g_new0(struct RenderLevel, 1);
next->prev = list;
next->next = list->next;
list->next = next;
+ g_mutex_unlock(opengl->objects_lock);
return next;
}
GList *link = _link;
GisObject *object = link->data;
_unload_object(opengl, object);
+ g_mutex_lock(opengl->objects_lock);
/* 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);
+ g_mutex_unlock(opengl->objects_lock);
return object;
}
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();
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);
}