From a29b3442b18244050308606dd69265cd3fd7fdb7 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Fri, 8 May 2009 05:46:47 +0000 Subject: [PATCH] switching to glade --- Makefile.am | 2 +- configure.ac | 3 +- src/Makefile.am | 10 +- src/aweather.c | 72 ++++----------- src/plugin-radar.c | 221 +++++++++++++++++++++++++++++++++++++++++++++ src/site.c | 6 ++ src/site.h | 6 ++ 7 files changed, 261 insertions(+), 59 deletions(-) create mode 100644 src/plugin-radar.c create mode 100644 src/site.c create mode 100644 src/site.h diff --git a/Makefile.am b/Makefile.am index bc1d29c..39555ef 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = src +SUBDIRS = data src test: all LD_LIBRARY_PATH=/usr/local/trmm/GVBOX/lib/ \ diff --git a/configure.ac b/configure.ac index 9dbac1e..73b7685 100644 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,7 @@ AC_PROG_CC PKG_PROG_PKG_CONFIG # Check for required packages -PKG_CHECK_MODULES(GTK, gtk+-2.0 gtkglext-1.0) +PKG_CHECK_MODULES(GTK, gtk+-2.0 gmodule-export-2.0 gtkglext-1.0) PKG_CHECK_MODULES(CURL, libcurl) # Define odd RSL install location @@ -18,6 +18,7 @@ AC_SUBST(RSL_LIBS, "-L/usr/local/trmm/GVBOX/lib/ -lrsl") # Output AC_CONFIG_FILES([ Makefile + data/Makefile src/Makefile ]) AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am index 4fecc97..ac91542 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,16 +1,18 @@ -AM_CPPFLAGS = $(RSL_CFLAGS) $(GTK_CFLAGS) $(CURL_CFLAGS) -AM_CFLAGS = -O3 -Wall -Werror --std=gnu99 - +AM_CPPFLAGS = -DDATADIR="\"$(datadir)\"" $(RSL_CFLAGS) $(GTK_CFLAGS) $(CURL_CFLAGS) +AM_CFLAGS = -O3 -Wall -Werror --std=gnu99 +AM_LDFLAGS = -Wl,--export-dynamic bin_PROGRAMS = aweather -aweather_SOURCES = \ +aweather_SOURCES = \ aweather.c aweather.h \ + site.c site.h \ opengl.c opengl.h \ plugin-radar.c plugin-radar.h \ plugin-ridge.c plugin-ridge.h \ plugin-example.c plugin-example.h aweather_LDADD = $(RSL_LIBS) $(GTK_LIBS) $(CURL_LIBS) + test: all LD_LIBRARY_PATH=/usr/local/trmm/GVBOX/lib/ \ ./aweather diff --git a/src/aweather.c b/src/aweather.c index 098102c..a732eb2 100644 --- a/src/aweather.c +++ b/src/aweather.c @@ -8,21 +8,10 @@ #include "plugin-ridge.h" #include "plugin-example.h" -static void destroy(GtkWidget *widget, gpointer data) -{ - gtk_main_quit(); -} - -static gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) -{ - destroy(widget, data); - return FALSE; -} - -static gboolean key_press(GtkWidget *widget, GdkEventKey *event, gpointer data) +gboolean on_window_key_press_event(GtkWidget *widget, GdkEventKey *event, gpointer data) { if (event->keyval == GDK_q) - destroy(widget, data); + gtk_main_quit(); return TRUE; } @@ -32,56 +21,33 @@ int main(int argc, char *argv[]) gtk_init(&argc, &argv); gtk_gl_init(&argc, &argv); - /* Set up window */ - GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); - g_signal_connect(G_OBJECT(window), "delete-event", G_CALLBACK(delete_event), NULL); - g_signal_connect(G_OBJECT(window), "key-press-event", G_CALLBACK(key_press), NULL); + GError *error = NULL; + GtkBuilder *builder = gtk_builder_new(); + if (!gtk_builder_add_from_file(builder, DATADIR "/aweather/aweather.xml", &error)) + g_error("Failed to create gtk builder: %s", error->message); + gtk_builder_connect_signals(builder, NULL); - /* Set up layout */ - GtkWidget *vbox = gtk_vbox_new(FALSE, 0); - gtk_container_add(GTK_CONTAINER(window), vbox); - GtkWidget *paned = gtk_vpaned_new(); - gtk_box_pack_end(GTK_BOX(vbox), paned, TRUE, TRUE, 0); - - /* Set up menu bar */ - GtkWidget *menu = gtk_menu_bar_new(); - GtkWidget *menu_file = gtk_menu_item_new_with_label("File"); - GtkWidget *menu_file_menu = gtk_menu_new(); - GtkWidget *menu_file_menu_quit = gtk_menu_item_new_with_label("Quit"); - gtk_box_pack_start(GTK_BOX(vbox), menu, FALSE, FALSE, 0); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_file); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_file), menu_file_menu); - gtk_menu_shell_append(GTK_MENU_SHELL(menu_file_menu), menu_file_menu_quit); - g_signal_connect(G_OBJECT(menu_file_menu_quit), "activate", G_CALLBACK(destroy), NULL); + GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "window")); + GtkWidget *drawing = GTK_WIDGET(gtk_builder_get_object(builder, "drawing")); + GtkWidget *tabs = GTK_WIDGET(gtk_builder_get_object(builder, "tabs")); + if (window == NULL) g_error("window is null"); + if (drawing == NULL) g_error("drawing is null"); + if (tabs == NULL) g_error("tabs is null"); /* Set up darwing area */ - GtkWidget *drawing = gtk_drawing_area_new(); - gtk_paned_pack1(GTK_PANED(paned), drawing, TRUE, FALSE); - //gtk_box_pack_end(GTK_BOX(vbox), drawing, TRUE, TRUE, 0); GdkGLConfig *glconfig = gdk_gl_config_new_by_mode( - GDK_GL_MODE_RGBA | - GDK_GL_MODE_DEPTH | - GDK_GL_MODE_DOUBLE | - GDK_GL_MODE_ALPHA); + GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | + GDK_GL_MODE_DOUBLE | GDK_GL_MODE_ALPHA); if (!glconfig) g_assert_not_reached(); if (!gtk_widget_set_gl_capability(drawing, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE)) g_assert_not_reached(); - /* Set up tab area */ - GtkWidget *tab_area = gtk_notebook_new(); - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(tab_area), GTK_POS_BOTTOM); - gtk_paned_pack2(GTK_PANED(paned), tab_area, FALSE, FALSE); - //GtkWidget *label = gtk_label_new("Hello"); - //GtkWidget *contents = gtk_label_new("World"); - //gtk_notebook_append_page(GTK_NOTEBOOK(tab_area), contents, label); - /* Load plugins */ - opengl_init (GTK_DRAWING_AREA(drawing), GTK_NOTEBOOK(tab_area)); - radar_init (GTK_DRAWING_AREA(drawing), GTK_NOTEBOOK(tab_area)); - ridge_init (GTK_DRAWING_AREA(drawing), GTK_NOTEBOOK(tab_area)); - example_init(GTK_DRAWING_AREA(drawing), GTK_NOTEBOOK(tab_area)); + opengl_init (GTK_DRAWING_AREA(drawing), GTK_NOTEBOOK(tabs)); + radar_init (GTK_DRAWING_AREA(drawing), GTK_NOTEBOOK(tabs)); + ridge_init (GTK_DRAWING_AREA(drawing), GTK_NOTEBOOK(tabs)); + example_init(GTK_DRAWING_AREA(drawing), GTK_NOTEBOOK(tabs)); gtk_widget_show_all(window); gtk_main(); diff --git a/src/plugin-radar.c b/src/plugin-radar.c new file mode 100644 index 0000000..317cea5 --- /dev/null +++ b/src/plugin-radar.c @@ -0,0 +1,221 @@ +#include +#include +#include +#include + +#include "rsl.h" + +#include "plugin-radar.h" + +GtkWidget *drawing; +static Sweep *cur_sweep = NULL; // make this not global +static int nred, ngreen, nblue; +static char red[256], green[256], blue[256]; +static guint sweep_tex = 0; + +static guint8 get_alpha(guint8 db) +{ + if (db == BADVAL) return 0; + if (db == RFVAL ) return 0; + if (db == APFLAG) return 0; + if (db == NOECHO) return 0; + if (db == 0 ) return 0; + //if (db > 60) return 0; + //else if (db < 10) return 0; + //else if (db < 25) return (db-10)*(255.0/15); + else return 255; +} + +//#ifdef USE_TWO_BYTE_PRECISION +//#define F_FACTOR 100.0 +//#define F_DR_FACTOR 1000.0 +//#define F_DZ_RANGE_OFFSET 50 +//#else +//#define F_FACTOR 2.0 +//#define F_DR_FACTOR 10.0 +//#define F_DZ_RANGE_OFFSET 32 +//#endif +//#define F_OFFSET 4 +//static float dz_f(Range x) +//{ +// if (x >= F_OFFSET) +// return (((float)x-F_OFFSET)/F_FACTOR - F_DZ_RANGE_OFFSET); +// if (x == 0) return BADVAL; +// if (x == 1) return RFVAL; +// if (x == 2) return APFLAG; +// if (x == 3) return NOECHO; +// return BADVAL; +//} + +/* Convert a sweep to an 2d array of data points */ +static void bscan_sweep(Sweep *sweep, guint8 **data, int *width, int *height) +{ + /* Calculate max number of bins */ + int i, max_bins = 0; + for (i = 0; i < sweep->h.nrays; i++) + max_bins = MAX(max_bins, sweep->ray[i]->h.nbins); + + /* Allocate buffer using max number of bins for each ray */ + guint8 *buf = g_malloc0(sweep->h.nrays * max_bins * 4); + + /* Fill the data */ + int ri, bi; + for (ri = 0; ri < sweep->h.nrays; ri++) { + Ray *ray = sweep->ray[ri]; + for (bi = 0; bi < ray->h.nbins; bi++) { + /* copy RGBA into buffer */ + //guint val = dz_f(ray->range[bi]); + guint val = ray->h.f(ray->range[bi]); + guint buf_i = (ri*max_bins+bi)*4; + buf[buf_i+0] = red[val]; + buf[buf_i+1] = green[val]; + buf[buf_i+2] = blue[val]; + buf[buf_i+3] = get_alpha(val); + } + } + + /* set output */ + *width = max_bins; + *height = sweep->h.nrays; + *data = buf; +} + +/* Load a sweep as the active texture */ +static void load_sweep(Sweep *sweep) +{ + cur_sweep = sweep; + int height, width; + guint8 *data; + bscan_sweep(sweep, &data, &width, &height); + glGenTextures(1, &sweep_tex); + glBindTexture(GL_TEXTURE_2D, sweep_tex); + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + g_free(data); + gdk_window_invalidate_rect(drawing->window, &drawing->allocation, FALSE); + gdk_window_process_updates(drawing->window, FALSE); +} + +/* Load the default sweep */ +static gboolean configure(GtkWidget *da, GdkEventConfigure *event, gpointer user_data) +{ + Sweep *first = (Sweep*)user_data; + if (cur_sweep == NULL) + load_sweep(first); + return FALSE; +} + +static gboolean expose(GtkWidget *da, GdkEventExpose *event, gpointer user_data) +{ + g_message("radar:expose"); + Sweep *sweep = cur_sweep; + + /* Draw the rays */ + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glBindTexture(GL_TEXTURE_2D, sweep_tex); + glEnable(GL_TEXTURE_2D); + glColor4f(1,1,1,1); + glBegin(GL_QUAD_STRIP); + for (int ri = 0; ri <= sweep->h.nrays+1; ri++) { + /* Do the first sweep twice to complete the last Quad */ + Ray *ray = sweep->ray[ri % sweep->h.nrays]; + + /* right and left looking out from radar */ + double left = ((ray->h.azimuth - ((double)ray->h.beam_width/2.))*M_PI)/180.0; + //double right = ((ray->h.azimuth + ((double)ray->h.beam_width/2.))*M_PI)/180.0; + + double lx = sin(left); + double ly = cos(left); + + double near_dist = ray->h.range_bin1; + double far_dist = ray->h.nbins*ray->h.gate_size + ray->h.range_bin1; + + /* (find middle of bin) / scale for opengl */ + // near left + glTexCoord2f(0.0, (double)ri/sweep->h.nrays); + glVertex3f(lx*near_dist, ly*near_dist, 2.0); + + // far left + glTexCoord2f(1.0, (double)ri/sweep->h.nrays); + glVertex3f(lx*far_dist, ly*far_dist, 2.0); + } + //g_print("ri=%d, nr=%d, bw=%f\n", _ri, sweep->h.nrays, sweep->h.beam_width); + glEnd(); + glPopMatrix(); + + /* Texture debug */ + //glBegin(GL_QUADS); + //glTexCoord2d( 0., 0.); glVertex3f(-1., 0., 0.); // bot left + //glTexCoord2d( 0., 1.); glVertex3f(-1., 1., 0.); // top left + //glTexCoord2d( 1., 1.); glVertex3f( 0., 1., 0.); // top right + //glTexCoord2d( 1., 0.); glVertex3f( 0., 0., 0.); // bot right + //glEnd(); + + /* Print the color table */ + //glDisable(GL_TEXTURE_2D); + //glMatrixMode(GL_MODELVIEW ); glPushMatrix(); glLoadIdentity(); + //glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); + //glBegin(GL_QUADS); + //int i; + //for (i = 0; i < nred; i++) { + // glColor4ub(red[i], green[i], blue[i], get_alpha(i)); + // glVertex3f(-1.0, (float)((i ) - nred/2)/(nred/2), 0.0); // bot left + // glVertex3f(-1.0, (float)((i+1) - nred/2)/(nred/2), 0.0); // top left + // glVertex3f(-0.9, (float)((i+1) - nred/2)/(nred/2), 0.0); // top right + // glVertex3f(-0.9, (float)((i ) - nred/2)/(nred/2), 0.0); // bot right + //} + //glEnd(); + //glMatrixMode(GL_PROJECTION); glPopMatrix(); + //glMatrixMode(GL_MODELVIEW ); glPopMatrix(); + + return FALSE; +} + +gboolean radar_init(GtkDrawingArea *_drawing, GtkNotebook *config) +{ + drawing = GTK_WIDGET(_drawing); + + /* Parse hard coded file.. */ + RSL_read_these_sweeps("all", NULL); + //RSL_read_these_sweeps("all", NULL); + Radar *radar = RSL_wsr88d_to_radar("/scratch/aweather/data/level2/KNQA_20090501_1925.raw", "KNQA"); + RSL_load_refl_color_table(); + RSL_get_color_table(RSL_RED_TABLE, red, &nred); + RSL_get_color_table(RSL_GREEN_TABLE, green, &ngreen); + RSL_get_color_table(RSL_BLUE_TABLE, blue, &nblue); + if (radar->h.nvolumes < 1 || radar->v[0]->h.nsweeps < 1) + g_print("No sweeps found\n"); + + /* Add configuration tab */ + GtkWidget *hbox = gtk_hbox_new(TRUE, 0); + GtkWidget *button = NULL; + int vi = 0, si = 0; + for (vi = 0; vi < radar->h.nvolumes; vi++) { + Volume *vol = radar->v[vi]; + if (vol == NULL) continue; + GtkWidget *vbox = gtk_vbox_new(TRUE, 0); + gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); + for (si = 0; si < vol->h.nsweeps; si++) { + Sweep *sweep = vol->sweep[si]; + if (sweep == NULL) continue; + char *label = g_strdup_printf("Tilt: %.2f (%s)", sweep->h.elev, vol->h.type_str); + button = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(button), label); + g_signal_connect_swapped(button, "clicked", G_CALLBACK(load_sweep), sweep); + gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0); + g_free(label); + } + } + GtkWidget *label = gtk_label_new("Radar"); + gtk_notebook_append_page(GTK_NOTEBOOK(config), hbox, label); + + /* Set up OpenGL Stuff */ + g_signal_connect(drawing, "expose-event", G_CALLBACK(expose), NULL); + g_signal_connect(drawing, "configure-event", G_CALLBACK(configure), radar->v[0]->sweep[0]); + + return TRUE; +} diff --git a/src/site.c b/src/site.c new file mode 100644 index 0000000..99d1fed --- /dev/null +++ b/src/site.c @@ -0,0 +1,6 @@ +#include +#include + +void setup_panel() +{ +} diff --git a/src/site.h b/src/site.h new file mode 100644 index 0000000..bc37546 --- /dev/null +++ b/src/site.h @@ -0,0 +1,6 @@ +#ifndef SITE_H +#define SITE_H + +void setup_sidebar(); + +#endif -- 2.41.0