From 177e54d84b7dce9d842deb22bae83f2bcf3f2907 Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Thu, 13 Mar 2008 15:52:46 +0200 Subject: [PATCH] Start to add gtkglext support. Make buffer pixmap private to map.c and access it using a function. --- src/map-poi.c | 10 +++--- src/map.c | 99 +++++++++++++++++++++++++++++++++++---------------- src/map.h | 6 ++-- 3 files changed, 77 insertions(+), 38 deletions(-) diff --git a/src/map-poi.c b/src/map-poi.c index cf5c68a..dded357 100644 --- a/src/map-poi.c +++ b/src/map-poi.c @@ -85,7 +85,8 @@ gint w,h; pango_layout_set_text(layout, title, -1); pango_layout_get_pixel_size(layout, &w, &h); -gdk_draw_layout(_map_pixmap, gc, x-(w>>1), y-h-_draw_width, layout); + +gdk_draw_layout(map_pixmap_get(), gc, x-(w>>1), y-h-_draw_width, layout); } /** @@ -255,17 +256,18 @@ while (valid) { if (!pixbuf) { /* No icon for POI or for category - draw default. */ - gdk_draw_arc(_map_pixmap, gc, FALSE, poix - _draw_width, poiy - _draw_width, + gdk_draw_arc(map_pixmap_get(), gc, FALSE, poix - _draw_width, poiy - _draw_width, (MAX_ZOOM-_zoom)/6 * _draw_width, (MAX_ZOOM-_zoom)/6 * _draw_width, 0, 360 * 64); } else { guint w,h; + w=gdk_pixbuf_get_width(pixbuf); h=gdk_pixbuf_get_height(pixbuf); - gdk_draw_pixbuf(_map_pixmap, gc, pixbuf, 0, 0, poix-w/2, poiy-h/2, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); + gdk_draw_pixbuf(map_pixmap_get(), gc, pixbuf, 0, 0, poix-w/2, poiy-h/2, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); #if 0 /* Draw rectangle around icon. Not really need with the square icons */ if (_zoom<2) - gdk_draw_rectangle(_map_pixmap, gc, FALSE, poix-w/2-1, poiy-h/2-1, w+1, h+1); + gdk_draw_rectangle(map_pixmap_get(), gc, FALSE, poix-w/2-1, poiy-h/2-1, w+1, h+1); #endif } diff --git a/src/map.c b/src/map.c index e9b6092..91b9e40 100644 --- a/src/map.c +++ b/src/map.c @@ -75,6 +75,20 @@ static guint buf_height_tiles=BUF_HEIGHT_TILES; static guint buf_width_pixels=BUF_WIDTH_PIXELS; static guint buf_height_pixels=BUF_HEIGHT_PIXELS; +#ifdef WITH_GL +#include +#include +GdkGLConfig* map_gl_config=NULL; +#endif +gboolean map_gl=FALSE; + +#ifdef WITH_CAIRO +cairo_t *ct_pixmap; +#endif + +/** The backing pixmap of map_widget. */ +static GdkPixmap *map_pixmap; + /** The "base tile" is the upper-left tile in the pixmap. */ guint _base_tilex = -5; guint _base_tiley = -5; @@ -84,7 +98,8 @@ guint _zoom = 3; /* zoom level, from 0 to MAX_ZOOM. */ Point _min_center = { -1, -1 }; Point _max_center = { -1, -1 }; Point _focus = { -1, -1 }; -Point _center = { -1, -1 }; /* current center location, X. */ +/* current center location, X. */ +Point _center = { -1, -1 }; CenterMode _center_mode = CENTER_LEAD; @@ -115,10 +130,6 @@ static PangoContext *speed_context; static PangoLayout *speed_layout; static PangoFontDescription *speed_fontdesc; -#ifdef WITH_CAIRO -cairo_t *ct_pixmap; -#endif - static gint zoom_timeout_sid=0; static gint map_mode=0; static gboolean map_data_needs_refresh=FALSE; @@ -152,11 +163,23 @@ map_new(void) { GtkWidget *map_widget; -g_debug("MAP: new"); map_widget=gtk_drawing_area_new(); +map_timer=g_timer_new(); + +#ifdef WITH_GL +map_gl_config=gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH); +if (map_gl_config) { + g_print("OpenGL version: %s\n", glGetString (GL_VERSION)); + g_print("OpenGL vendor: %s\n", glGetString (GL_VENDOR)); + g_print("OpenGL renderer: %s\n", glGetString (GL_RENDERER)); + gtk_widget_set_gl_capability(map_widget, map_gl_config, NULL, TRUE, GDK_GL_RGBA_TYPE); + map_gl=TRUE; +} +#endif + g_signal_connect_after(G_OBJECT(map_widget), "realize", G_CALLBACK(map_cb_after_realize), NULL); g_signal_connect(G_OBJECT(map_widget), "configure_event", G_CALLBACK(map_cb_configure), NULL); -map_timer=g_timer_new(); + return map_widget; } @@ -173,17 +196,20 @@ scale_font=pango_font_description_new(); pango_font_description_set_size(scale_font, 12 * PANGO_SCALE); pango_layout_set_font_description(scale_layout, scale_font); -/* Speed limit */ +/* Speed limit, over limit color */ speed_gc1=gdk_gc_new(map_widget->window); color.red=0xffff; color.green=0; color.blue=0; gdk_gc_set_rgb_fg_color(speed_gc1, &color); + +/* Speed limit, under limit color */ +speed_gc2=gdk_gc_new(map_widget->window); color.red=0; -color.green=0; +color.green=0x1000; color.blue=0; -speed_gc2=gdk_gc_new(map_widget->window); gdk_gc_set_rgb_fg_color(speed_gc2, &color); + speed_context=gtk_widget_get_pango_context(map_widget); speed_layout=pango_layout_new(speed_context); speed_fontdesc=pango_font_description_new(); @@ -215,15 +241,20 @@ th=TILE_SIZE_PIXELS*((widget->allocation.height/TILE_SIZE_PIXELS)+2); g_debug("MAP: configure %d %d -> (%d,%d)", widget->allocation.width, widget->allocation.height, tw, th); -if (_map_pixmap==NULL) { +if (map_pixmap==NULL) { g_debug("Initial buffer pixmap"); - _map_pixmap=gdk_pixmap_new(widget->window, tw, th, -1); + map_pixmap=gdk_pixmap_new(widget->window, tw, th, -1); } else { if (tw>buf_width_pixels || th>buf_height_pixels) { - g_debug("Resize buffer pixmap"); - g_object_unref(_map_pixmap); - _map_pixmap=gdk_pixmap_new(widget->window, tw, th, -1); - map_force_redraw(); + g_debug("MC: Large buffer"); + g_object_unref(map_pixmap); + map_pixmap=gdk_pixmap_new(widget->window, tw, th, -1); + } else if (twwindow, tw, th, -1); + } else { + g_debug("MC: No change ?"); } } @@ -249,6 +280,7 @@ _min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight)); _max_center.unitx = WORLD_SIZE_UNITS - grid2unit(_screen_grids_halfwidth) - 1; _max_center.unity = WORLD_SIZE_UNITS - grid2unit(_screen_grids_halfheight) - 1; +map_force_redraw(); return TRUE; } @@ -358,6 +390,13 @@ g_object_unref(pixbuf); return mpixbuf; } +GdkPixmap * +map_pixmap_get(void) +{ +return map_pixmap; +} + + static GdkPixbuf * map_tile_load(guint tilex, guint tiley, gint zoff, gboolean download) { @@ -433,11 +472,11 @@ if (tilex<_world_size_tiles && tiley<_world_size_tiles) { } if (pixbuf) { - gdk_draw_pixbuf(_map_pixmap, _gc[COLORABLE_MARK], pixbuf, 0, 0, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS, GDK_RGB_DITHER_NONE, 0, 0); + gdk_draw_pixbuf(map_pixmap, _gc[COLORABLE_MARK], pixbuf, 0, 0, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS, GDK_RGB_DITHER_NONE, 0, 0); g_object_unref(pixbuf); return TRUE; } -gdk_draw_rectangle(_map_pixmap, _map_widget->style->black_gc, TRUE, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS); +gdk_draw_rectangle(map_pixmap, _map_widget->style->black_gc, TRUE, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS); return TRUE; } @@ -457,7 +496,7 @@ if(_show_tracks>0) } /** - * Force a redraw of the entire _map_pixmap, including fetching the + * Force a redraw of the entire map_pixmap, including fetching the * background maps from disk and redrawing the tracks on top of them. */ void @@ -584,9 +623,9 @@ if (new_base_tilex != _base_tilex || new_base_tiley != _base_tiley) { /* Can we get this grid block from the old buffer?. */ if (old_x >= 0 && old_x < buf_width_tiles && old_y >= 0 && old_y < buf_height_tiles) { /* Copy from old buffer to new buffer. */ - gdk_draw_drawable(_map_pixmap, + gdk_draw_drawable(map_pixmap, _gc[COLORABLE_MARK], - _map_pixmap, + map_pixmap, old_x * TILE_SIZE_PIXELS, old_y * TILE_SIZE_PIXELS, new_x * TILE_SIZE_PIXELS, @@ -711,7 +750,7 @@ gint x,y; x = unit2bufx(unitx); y = unit2bufy(unity); -gdk_draw_pixbuf(_map_pixmap, _gc[COLORABLE_POI], +gdk_draw_pixbuf(map_pixmap, _gc[COLORABLE_POI], p, 0, 0, x - gdk_pixbuf_get_width(p) / 2, y - gdk_pixbuf_get_height(p) / 2, @@ -771,7 +810,7 @@ if (_center_mode>0) } /** - * Render a single track line to _map_pixmap. If either point on the line + * Render a single track line to map_pixmap. If either point on the line * is a break (defined as unity == 0), a circle is drawn at the other point. * IT IS AN ERROR FOR BOTH POINTS TO INDICATE A BREAK. */ @@ -785,7 +824,7 @@ if (!unity1) { y2 = unit2bufy(unity2); /* Make sure this circle will be visible. */ if ((x2 < buf_width_pixels) && (y2 < buf_height_pixels)) - gdk_draw_arc(_map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */ + gdk_draw_arc(map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */ x2 - _draw_width, y2 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */ 360 * 64); } else if (!unity2) { @@ -795,7 +834,7 @@ if (!unity1) { y1 = unit2bufy(unity1); /* Make sure this circle will be visible. */ if ((x1 < buf_width_pixels) && ((unsigned)y1 < buf_height_pixels)) - gdk_draw_arc(_map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */ + gdk_draw_arc(map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */ x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */ 360 * 64); } else { @@ -810,7 +849,7 @@ if (!unity1) { || (x1 < 0 && x2 < 0) || (y1 > buf_height_pixels && y2 > buf_height_pixels) || (y1 < 0 && y2 < 0))) - gdk_draw_line(_map_pixmap, gc_norm, x1, y1, x2, y2); + gdk_draw_line(map_pixmap, gc_norm, x1, y1, x2, y2); } } @@ -819,11 +858,11 @@ map_render_waypoint(guint x1, guint y1, GdkGC *gc) { if ((x1 > buf_width_pixels) || (y1 > buf_height_pixels)) return; -gdk_draw_arc(_map_pixmap, gc, FALSE, x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, 360 * 64); +gdk_draw_arc(map_pixmap, gc, FALSE, x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, 360 * 64); } /** - * Render all track data onto the _map_pixmap. Note that this does not + * Render all track data onto the map_pixmap. Note that this does not * clear the pixmap of previous track data (use map_force_redraw() for * that), and also note that this method does not queue any redraws, so it * is up to the caller to decide which part of the track really needs to be @@ -868,7 +907,7 @@ if ((_show_tracks & ROUTES_MASK) && _route.head != _route.tail) { if ((x1 < buf_width_pixels) && (y1 < buf_height_pixels)) { /* Draw the next waypoint as a break. */ - gdk_draw_arc(_map_pixmap, _gc[COLORABLE_ROUTE_BREAK], FALSE, /* FALSE: not filled. */ + gdk_draw_arc(map_pixmap, _gc[COLORABLE_ROUTE_BREAK], FALSE, /* FALSE: not filled. */ x1 - _draw_width, y1 - _draw_width, 4 * _draw_width, 4 * _draw_width, 0, /* start at 0 degrees. */ 360 * 64); } @@ -1046,7 +1085,7 @@ map_cb_expose(GtkWidget * widget, GdkEventExpose * event) { gdk_draw_drawable(GDK_DRAWABLE(_map_widget->window), _gc[COLORABLE_MARK], - _map_pixmap, + map_pixmap, event->area.x + _offsetx, event->area.y + _offsety, event->area.x, event->area.y, event->area.width, event->area.height); diff --git a/src/map.h b/src/map.h index 047c0fe..c2cc8ad 100644 --- a/src/map.h +++ b/src/map.h @@ -185,10 +185,6 @@ CenterMode _center_mode; /** The widget that provides the visual display of the map. */ GtkWidget *_map_widget; - -/** The backing pixmap of _map_widget. */ -GdkPixmap *_map_pixmap; - GtkWidget *map_new(void); gboolean map_key_zoom_timeout(); @@ -206,6 +202,8 @@ gboolean map_render_tile(guint tilex, guint tiley, guint destx, guint desty, gbo void map_render_waypoint(guint x1, guint y1, GdkGC *gc); +GdkPixmap *map_pixmap_get(void); + void map_center_unit(guint new_center_unitx, guint new_center_unity); void map_center_latlon(gdouble lat, gdouble lon); -- 2.39.5