static void grits_poly_tess(gdouble (**points)[3])
{
//g_debug("GritsPoly: tess");
-
- /* Tesselate */
GLUtesselator *tess = gluNewTess();
gluTessCallback(tess, GLU_TESS_BEGIN, (_GLUfuncptr)glBegin);
gluTessCallback(tess, GLU_TESS_VERTEX, (_GLUfuncptr)glVertex3dv);
}
gluTessEndPolygon(tess);
gluDeleteTess(tess);
+}
- /* Outline */
+static void grits_poly_outline(gdouble (**points)[3])
+{
+ //g_debug("GritsPoly: outline");
for (int pi = 0; points[pi]; pi++) {
- glColor4d(1,1,1,0.2);
glBegin(GL_LINE_LOOP);
- for (int ci = 0; points[pi][ci][0]; ci++)
+ for (int ci = 0; points[pi][ci][0] &&
+ points[pi][ci][1] &&
+ points[pi][ci][2]; ci++)
+ glVertex3dv(points[pi][ci]);
+ glEnd();
+ glBegin(GL_POINTS);
+ for (int ci = 0; points[pi][ci][0] &&
+ points[pi][ci][1] &&
+ points[pi][ci][2]; ci++)
glVertex3dv(points[pi][ci]);
glEnd();
}
{
//g_debug("GritsPoly: genlist");
GritsPoly *poly = GRITS_POLY(_poly);
- guint list = glGenLists(1);
- glNewList(list, GL_COMPILE);
+ guint list = glGenLists(2);
+ glNewList(list+0, GL_COMPILE);
grits_poly_tess(poly->points);
glEndList();
+ glNewList(list+1, GL_COMPILE);
+ grits_poly_outline(poly->points);
+ glEndList();
poly->list = list;
return FALSE;
}
glDisable(GL_ALPHA_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_LIGHTING);
- glColor4dv(poly->color);
- glCallList(poly->list);
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(1, 1);
+ if (poly->color[3]) {
+ glColor4dv(poly->color);
+ glCallList(poly->list+0);
+ }
+ if (poly->border[3]) {
+ glPointSize(poly->width);
+ glLineWidth(poly->width);
+ glColor4dv(poly->border);
+ glCallList(poly->list+1);
+ }
+ glPopAttrib();
+}
+
+static void grits_poly_pick(GritsObject *_poly, GritsOpenGL *opengl)
+{
+ //g_debug("GritsPoly: pick");
+ GritsPoly *poly = GRITS_POLY(_poly);
+ if (!poly->list)
+ return;
+ glPushAttrib(GL_ENABLE_BIT);
+ glDisable(GL_CULL_FACE);
+ glCallList(poly->list+0);
glPopAttrib();
}
return poly;
}
+GritsPoly *grits_poly_parse(const gchar *str,
+ const gchar *poly_sep, const gchar *point_sep, const gchar *coord_sep)
+{
+ /* Split and count polygons */
+ gchar **spolys = g_strsplit(str, poly_sep, -1);
+ int npolys = g_strv_length(spolys);
+
+ GritsBounds bounds = {-90, 90, -180, 180};
+ gdouble (**polys)[3] = (gpointer)g_new0(double*, npolys+1);
+ for (int pi = 0; pi < npolys; pi++) {
+ /* Split and count coordinates */
+ gchar **scoords = g_strsplit(spolys[pi], point_sep, -1);
+ int ncoords = g_strv_length(scoords);
+
+ /* Create binary coords */
+ gdouble (*coords)[3] = (gpointer)g_new0(gdouble, 3*(ncoords+1));
+ for (int ci = 0; ci < ncoords; ci++) {
+ gdouble lat, lon;
+ sscanf(scoords[ci], "%lf,%lf", &lat, &lon);
+ if (lat > bounds.n) bounds.n = lat;
+ if (lat < bounds.s) bounds.s = lat;
+ if (lon > bounds.e) bounds.e = lon;
+ if (lon < bounds.w) bounds.w = lon;
+ lle2xyz(lat, lon, 0,
+ &coords[ci][0],
+ &coords[ci][1],
+ &coords[ci][2]);
+ }
+
+ /* Insert coords into poly array */
+ polys[pi] = coords;
+ g_strfreev(scoords);
+ }
+
+ /* Create GritsPoly */
+ GritsPoly *poly = grits_poly_new(polys);
+ GRITS_OBJECT(poly)->center.lat = (bounds.n + bounds.s)/2;
+ GRITS_OBJECT(poly)->center.lon = lon_avg(bounds.e, bounds.w);
+ GRITS_OBJECT(poly)->center.elev = 0;
+ GRITS_OBJECT(poly)->skip = GRITS_SKIP_CENTER;
+ return poly;
+}
+
/* GObject code */
G_DEFINE_TYPE(GritsPoly, grits_poly, GRITS_TYPE_OBJECT);
static void grits_poly_init(GritsPoly *poly)
{
+ poly->border[0] = 1;
+ poly->border[1] = 1;
+ poly->border[2] = 1;
+ poly->border[3] = 0.2;
+ poly->width = 1;
}
static void grits_poly_finalize(GObject *_poly)
GritsObjectClass *object_class = GRITS_OBJECT_CLASS(klass);
object_class->draw = grits_poly_draw;
+ object_class->pick = grits_poly_pick;
}