2 * Copyright (C) 2010-2011 Andy Spencer <andy753421@gmail.com>
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * @short_description: Single point polys
22 * Each #GritsPoly represents a 3 dimentional polygon.
27 #include "grits-poly.h"
30 static void grits_poly_tess(gdouble (**points)[3])
32 //g_debug("GritsPoly: tess");
33 GLUtesselator *tess = gluNewTess();
34 gluTessCallback(tess, GLU_TESS_BEGIN, (void*)glBegin);
35 gluTessCallback(tess, GLU_TESS_VERTEX, (void*)glVertex3dv);
36 gluTessCallback(tess, GLU_TESS_END, (void*)glEnd);
37 for (int pi = 0; points[pi]; pi++) {
38 gluTessBeginPolygon(tess, NULL);
39 gluTessBeginContour(tess);
40 for (int ci = 0; points[pi][ci][0]; ci++) {
45 gluTessEndContour(tess);
46 gluTessEndPolygon(tess);
51 static void grits_poly_outline(gdouble (**points)[3])
53 //g_debug("GritsPoly: outline");
54 for (int pi = 0; points[pi]; pi++) {
56 for (int ci = 0; points[pi][ci][0] &&
58 points[pi][ci][2]; ci++)
59 glVertex3dv(points[pi][ci]);
64 static gboolean grits_poly_runlist(GritsPoly *poly, int i,
65 void (*render)(gdouble(**)[3]))
67 //g_debug("GritsPoly: genlist");
69 glCallList(poly->list[i]);
71 guint list = glGenLists(1);
72 glNewList(list, GL_COMPILE_AND_EXECUTE);
80 static void grits_poly_draw(GritsObject *_poly, GritsOpenGL *opengl)
82 //g_debug("GritsPoly: draw");
83 GritsPoly *poly = GRITS_POLY(_poly);
85 glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_CURRENT_BIT |
86 GL_POINT_BIT | GL_LINE_BIT | GL_POLYGON_BIT);
87 glDisable(GL_TEXTURE_2D);
88 glDisable(GL_ALPHA_TEST);
89 glDisable(GL_CULL_FACE);
90 glDisable(GL_LIGHTING);
92 glEnable(GL_POLYGON_OFFSET_FILL);
93 glEnable(GL_POLYGON_OFFSET_LINE);
94 glEnable(GL_POLYGON_OFFSET_POINT);
97 /* Draw background farthest back */
98 glPolygonOffset(3, 3);
99 glColor4dv(poly->color);
100 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
101 grits_poly_runlist(poly, 0, grits_poly_tess);
104 glEnable(GL_POLYGON_SMOOTH);
105 glEnable(GL_LINE_SMOOTH);
106 glEnable(GL_POINT_SMOOTH);
108 if (!poly->color[3] && poly->border[3] && poly->width > 1) {
109 /* Draw line border in the middle */
112 glPointSize(poly->width*2);
113 glLineWidth(poly->width*2);
115 glPolygonOffset(2, 2);
117 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
118 grits_poly_runlist(poly, 1, grits_poly_outline);
119 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
120 grits_poly_runlist(poly, 1, grits_poly_outline);
123 if (poly->border[3]) {
124 /* Draw border front-most */
125 glColor4dv(poly->border);
127 glPointSize(poly->width);
128 glLineWidth(poly->width);
130 glPolygonOffset(1, 1);
131 if (poly->width > 1) {
132 glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
133 grits_poly_runlist(poly, 1, grits_poly_outline);
135 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
136 grits_poly_runlist(poly, 1, grits_poly_outline);
139 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
143 static void grits_poly_pick(GritsObject *_poly, GritsOpenGL *opengl)
145 //g_debug("GritsPoly: pick");
146 GritsPoly *poly = GRITS_POLY(_poly);
147 glPushAttrib(GL_ENABLE_BIT);
148 glDisable(GL_CULL_FACE);
149 grits_poly_runlist(poly, 0, grits_poly_tess);
153 static gboolean grits_poly_delete(gpointer list)
155 glDeleteLists((guintptr)list, 1);
164 * Create a new GritsPoly which TODO.
166 * Returns: the new #GritsPoly.
168 GritsPoly *grits_poly_new(gdouble (**points)[3])
170 //g_debug("GritsPoly: new - %p", points);
171 GritsPoly *poly = g_object_new(GRITS_TYPE_POLY, NULL);
172 poly->points = points;
176 GritsPoly *grits_poly_parse(const gchar *str,
177 const gchar *poly_sep, const gchar *point_sep, const gchar *coord_sep)
180 gdouble (**polys)[3] = parse_points(str,
181 poly_sep, point_sep, coord_sep, NULL, ¢er);
183 GritsPoly *poly = grits_poly_new(polys);
184 GRITS_OBJECT(poly)->center = center;
185 GRITS_OBJECT(poly)->skip = GRITS_SKIP_CENTER;
186 g_object_weak_ref(G_OBJECT(poly), (GWeakNotify)free_points, polys);
191 G_DEFINE_TYPE(GritsPoly, grits_poly, GRITS_TYPE_OBJECT);
192 static void grits_poly_init(GritsPoly *poly)
197 poly->border[3] = 0.2;
199 GRITS_OBJECT(poly)->skip = GRITS_SKIP_STATE;
202 static void grits_poly_finalize(GObject *_poly)
204 //g_debug("GritsPoly: finalize");
205 GritsPoly *poly = GRITS_POLY(_poly);
206 if (poly->list[0]) g_idle_add(grits_poly_delete, (gpointer)(guintptr)poly->list[0]);
207 if (poly->list[1]) g_idle_add(grits_poly_delete, (gpointer)(guintptr)poly->list[1]);
210 static void grits_poly_class_init(GritsPolyClass *klass)
212 g_debug("GritsPoly: class_init");
213 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
214 gobject_class->finalize = grits_poly_finalize;
216 GritsObjectClass *object_class = GRITS_OBJECT_CLASS(klass);
217 object_class->draw = grits_poly_draw;
218 object_class->pick = grits_poly_pick;