#define MPPX(dist) (4*dist/FOV_DIST)
// #define ROAM_DEBUG
-/******************
- * Object drawing *
- ******************/
-static void _gis_opengl_draw_triangle(GisOpenGL *self, GisTriangle *tri)
-{
-}
-static void _gis_opengl_draw_quad(GisOpenGL *self, GisQuad *quad)
+/***********
+ * Helpers *
+ ***********/
+static void _gis_opengl_begin(GisOpenGL *self)
{
+ g_assert(GIS_IS_OPENGL(self));
+
+ GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(self));
+ GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self));
+
+ if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
+ g_assert_not_reached();
}
-static void _gis_opengl_draw_callback(GisOpenGL *self, GisCallback *cb)
+static 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);
}
-static void _gis_opengl_draw_marker(GisOpenGL *self, GisMarker *marker)
+
+/********************
+ * Object handleing *
+ ********************/
+static void _draw_marker(GisOpenGL *self, GisMarker *marker)
{
GisProjection *proj = (GisProjection*)self->sphere->view;
GisPoint *point = gis_object_center(marker);
gis_point_project(point, proj);
- double width = GTK_WIDGET(self)->allocation.width;
- double height = GTK_WIDGET(self)->allocation.height;
+ g_debug("GisOpenGL: draw_marker - texture=%d", marker->tex);
- cairo_set_source_rgba(self->canvas, 1, 1, 1, 1);
- cairo_arc(self->canvas, point->px, height-point->py, 4, 0, 2*G_PI);
- cairo_fill(self->canvas);
- cairo_move_to(self->canvas, point->px+4, height-point->py-8);
- cairo_set_font_size(self->canvas, 10);
- cairo_show_text(self->canvas, marker->label);
-}
-
-static void gis_opengl_draw_object(GisOpenGL *self, GisObject *object)
-{
- g_debug("GisOpenGL: draw_object - Drawing object of type %d", object->type);
- switch (object->type) {
- case GIS_TYPE_TRIANGLE: _gis_opengl_draw_triangle(self, GIS_TRIANGLE(object)); break;
- case GIS_TYPE_QUAD : _gis_opengl_draw_quad (self, GIS_QUAD (object)); break;
- case GIS_TYPE_CALLBACK: _gis_opengl_draw_callback(self, GIS_CALLBACK(object)); break;
- case GIS_TYPE_MARKER : _gis_opengl_draw_marker (self, GIS_MARKER (object)); break;
- default: g_warning("GisOpenGL: draw_object - invalid type %d", object->type);
- }
-}
-static void gis_opengl_draw_objects(GisOpenGL *self)
-{
- g_debug("GisOpenGL: draw_objects");
+ 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);
- double width = GTK_WIDGET(self)->allocation.width;
- double height = GTK_WIDGET(self)->allocation.height;
- cairo_surface_t *surface = cairo_get_target(self->canvas);
- int stride = cairo_image_surface_get_stride(surface);
- guchar *data = cairo_image_surface_get_data(surface);
- memset(data, 0, height*stride);
+ glMatrixMode(GL_PROJECTION); glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW); glLoadIdentity();
+ glOrtho(0, GTK_WIDGET(self)->allocation.width,
+ 0, GTK_WIDGET(self)->allocation.height, -1, 1);
+ glTranslated(gis_object_center(marker)->px - marker->xoff,
+ gis_object_center(marker)->py - marker->yoff, 0);
- /* Draw objects */
- for (GList *cur = GIS_VIEWER(self)->objects; cur; cur = cur->next)
- gis_opengl_draw_object(self, cur->data);
-
- /* Copy canvas to opengl */
- glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity();
- glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity();
- glDisable(GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
+ glDisable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, self->canvas_tex);
- //glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, width,height,
- // GL_RGBA, GL_UNSIGNED_BYTE, data);
+ glBindTexture(GL_TEXTURE_2D, marker->tex);
+ g_debug("bind_texture: %d", marker->tex);
glBegin(GL_QUADS);
- glTexCoord2d(0, 0); glVertex3f(-1, 1, 1);
- glTexCoord2d(1, 0); glVertex3f( 1, 1, 1);
- glTexCoord2d(1, 1); glVertex3f( 1, -1, 1);
- glTexCoord2d(0, 1); glVertex3f(-1, -1, 1);
+ 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();
- glMatrixMode(GL_PROJECTION); glPopMatrix();
- glMatrixMode(GL_MODELVIEW); glPopMatrix();
}
-/***********
- * Helpers *
- ***********/
-static void _gis_opengl_begin(GisOpenGL *self)
+static void _draw_objects(GisOpenGL *self)
{
- g_assert(GIS_IS_OPENGL(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();
+ }
+}
- GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(self));
- GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self));
+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);
- if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext))
- g_assert_not_reached();
+ _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 _gis_opengl_end(GisOpenGL *self)
+static void _free_object(GisOpenGL *self, GisObject *object)
{
- g_assert(GIS_IS_OPENGL(self));
- GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self));
- gdk_gl_drawable_gl_end(gldrawable);
+ 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;
+ }
}
/*************
double ang = atan(height/FOV_DIST);
gluPerspective(rad2deg(ang)*2, width/height, 1, 20*EARTH_R);
- /* Recreate the canvas */
- if (self->canvas) {
- cairo_surface_destroy(cairo_get_target(self->canvas));
- cairo_destroy(self->canvas);
- glDeleteTextures(1, &self->canvas_tex);
- }
- g_message("creating %fx%f canvas", width, height);
- cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
- self->canvas = cairo_create(surface);
- glEnable(GL_TEXTURE_2D);
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glGenTextures(1, &self->canvas_tex);
- glBindTexture(GL_TEXTURE_2D, self->canvas_tex);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
- cairo_image_surface_get_data(cairo_get_target(self->canvas)));
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-
#ifndef ROAM_DEBUG
roam_sphere_update_errors(self->sphere);
#endif
#ifndef ROAM_DEBUG
gis_plugins_foreach(GIS_VIEWER(self)->plugins,
G_CALLBACK(_on_expose_plugin), self);
- gis_opengl_draw_objects(self);
+ _draw_objects(self);
if (self->wireframe) {
_set_visuals(self);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
_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 *
****************/
{
g_debug("GisViewer: finalize");
GisOpenGL *self = GIS_OPENGL(_self);
- if (self->canvas) {
- cairo_surface_destroy(cairo_get_target(self->canvas));
- cairo_destroy(self->canvas);
- self->canvas = NULL;
- }
G_OBJECT_CLASS(gis_opengl_parent_class)->finalize(_self);
}
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;
}