+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);
+}
+
+/* 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;
+}