1 /* Copyright (C) 1992-1998 The Geometry Center
2 * Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips
3 *
4 * This file is part of Geomview.
5 *
6 * Geomview is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * Geomview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with Geomview; see the file COPYING. If not, write
18 * to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
19 * USA, or visit http://www.gnu.org.
20 */
21
22 #if HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #if 0
27 static char copyright[] = "Copyright (C) 1992-1998 The Geometry Center\n\
28 Copyright (C) 1998-2000 Stuart Levy, Tamara Munzner, Mark Phillips";
29 #endif
30
31 #include <limits.h>
32 #include "mg.h"
33 #include "mgP.h"
34 #include "mgps.h"
35 #include "mgpsP.h"
36 #include "mgpstri.h"
37 #include "windowP.h"
38 #include "mgpswindows.h"
39
40 static mgps_sort *mgpssort = NULL;
41 static double curwidth = 1;
42
43 /*
44 Function: mgps_initpsdevice
45 Description: allocate space for the display list, initialize mgcontext
46 Author: Daeron Meyer
47 */
mgps_initpsdevice()48 int mgps_initpsdevice()
49 {
50
51 if (!mgpssort)
52 {
53 mgpssort = (mgps_sort *)malloc(sizeof(mgps_sort));
54 mgpssort->primnum = 1000;
55 VVINIT(mgpssort->primsort, int, mgpssort->primnum);
56 vvneeds(&(mgpssort->primsort), mgpssort->primnum);
57 VVINIT(mgpssort->prims, mgpsprim, mgpssort->primnum);
58 vvneeds(&(mgpssort->prims), mgpssort->primnum);
59
60 mgpssort->pvertnum = 2024;
61 VVINIT(mgpssort->pverts, CPoint3, mgpssort->pvertnum);
62 vvneeds(&(mgpssort->pverts), mgpssort->pvertnum);
63
64 }
65 _mgpsc->mysort = mgpssort;
66 return 1;
67 }
68
69 /*
70 Function: Xmg_newdisplaylist
71 Description: initialize display list
72 Author: Daeron Meyer
73 */
mgps_newdisplaylist(void)74 void mgps_newdisplaylist(void)
75 {
76 _mgpsc->mysort->cprim = 0;
77 _mgpsc->mysort->cvert = 0;
78 _mgpsc->mysort->maxverts = 0;
79 _mgpsc->znudgeby = 0.0;
80 }
81
82 /*
83 Function: mgps_add
84 Description: add a primitive (polygon, vertex, line) to the display list
85 Author: Daeron Meyer
86 */
mgps_add(int primtype,int numdata,void * data,void * cdata)87 void mgps_add(int primtype, int numdata, void *data, void *cdata)
88 {
89 HPoint3 *vt = (HPoint3 *)data;
90 ColorA *colarray = (ColorA *)cdata;
91 float *col = (float *)cdata;
92 CPoint3 *vts;
93 int i;
94
95 static mgpsprim *prim;
96 static ColorA color;
97 static float average_depth;
98 static int numverts;
99 static int ecolor[3];
100
101 switch (primtype)
102 {
103 case MGX_BGNLINE:
104 case MGX_BGNSLINE:
105 average_depth = 0.0;
106 prim =
107 &(VVEC(_mgpsc->mysort->prims, mgpsprim)[_mgpsc->mysort->cprim]);
108
109 if (primtype == MGX_BGNLINE)
110 prim->mykind = PRIM_LINE;
111 else
112 prim->mykind = PRIM_SLINE;
113
114 prim->index = _mgpsc->mysort->cvert;
115 prim->depth = -100000; /* very far behind the viewer */
116 numverts = 0;
117
118 prim->ecolor[0] = ecolor[0];
119 prim->ecolor[1] = ecolor[1];
120 prim->ecolor[2] = ecolor[2];
121 prim->ewidth = curwidth;
122
123 VVEC(_mgpsc->mysort->primsort, int)[_mgpsc->mysort->cprim] =
124 _mgpsc->mysort->cprim;
125
126 if (!(_mgc->has & HAS_S2O))
127 mg_findS2O();
128 mg_findO2S();
129 break;
130
131 case MGX_BGNPOLY:
132 case MGX_BGNSPOLY:
133 case MGX_BGNEPOLY:
134 case MGX_BGNSEPOLY:
135 average_depth = 0.0;
136 prim = &(VVEC(_mgpsc->mysort->prims, mgpsprim)
137 [_mgpsc->mysort->cprim]);
138
139 switch(primtype)
140 {
141 case MGX_BGNPOLY:
142 prim->mykind = PRIM_POLYGON;
143 break;
144 case MGX_BGNSPOLY:
145 prim->mykind = PRIM_SPOLYGON;
146 break;
147 case MGX_BGNEPOLY:
148 prim->mykind = PRIM_EPOLYGON;
149 break;
150 case MGX_BGNSEPOLY:
151 prim->mykind = PRIM_SEPOLYGON;
152 break;
153 }
154
155 prim->ewidth = curwidth;
156 prim->index = _mgpsc->mysort->cvert;
157 prim->depth = -100000; /* very far behind the viewer */
158 numverts = 0;
159
160 VVEC(_mgpsc->mysort->primsort, int)[_mgpsc->mysort->cprim] =
161 _mgpsc->mysort->cprim;
162
163 if (!(_mgc->has & HAS_S2O))
164 mg_findS2O();
165 mg_findO2S();
166 break;
167
168 case MGX_VERTEX:
169 for (i=0; i<numdata; i++)
170 {
171 vts = &(VVEC(_mgpsc->mysort->pverts, CPoint3)[_mgpsc->mysort->cvert]);
172 HPt3Transform(_mgc->O2S, &(vt[i]), (HPoint3 *) vts);
173 vts->drawnext = 1;
174
175 vts->vcol = color;
176 _mgpsc->mysort->cvert++; numverts++;
177
178 if (_mgpsc->mysort->cvert > _mgpsc->mysort->pvertnum)
179 {
180 _mgpsc->mysort->pvertnum*=2;
181 vvneeds(&(_mgpsc->mysort->pverts), _mgpsc->mysort->pvertnum);
182 }
183
184 if (vts->z > prim->depth)
185 prim->depth = vts->z;
186 average_depth += vts->z;
187 }
188 break;
189
190 case MGX_CVERTEX:
191 for (i=0; i<numdata; i++)
192 {
193 vts = &(VVEC(_mgpsc->mysort->pverts, CPoint3)[_mgpsc->mysort->cvert]);
194 HPt3Transform(_mgc->O2S, &(vt[i]), (HPoint3 *) vts);
195 vts->drawnext = 1;
196
197 vts->vcol = colarray[i];
198
199 _mgpsc->mysort->cvert++;
200 numverts++;
201 if (_mgpsc->mysort->cvert > _mgpsc->mysort->pvertnum)
202 {
203 _mgpsc->mysort->pvertnum*=2;
204 vvneeds(&(_mgpsc->mysort->pverts), _mgpsc->mysort->pvertnum);
205 }
206
207 if (vts->z > prim->depth)
208 prim->depth = vts->z;
209 average_depth += vts->z;
210 }
211 break;
212
213 case MGX_COLOR:
214 color = colarray[0];
215 break;
216
217 case MGX_ECOLOR:
218 ecolor[0] = (int)(255.0 * col[0]);
219 ecolor[1] = (int)(255.0 * col[1]);
220 ecolor[2] = (int)(255.0 * col[2]);
221 break;
222
223 case MGX_END:
224 prim->numvts = numverts;
225 if (numverts > _mgpsc->mysort->maxverts)
226 _mgpsc->mysort->maxverts = numverts;
227 average_depth += prim->depth;
228 average_depth /= (float)(numverts+1);
229 prim->depth = average_depth;
230
231 prim->color[0] = (int)(255.0 * color.r);
232 prim->color[1] = (int)(255.0 * color.g);
233 prim->color[2] = (int)(255.0 * color.b);
234
235 prim->ecolor[0] = ecolor[0];
236 prim->ecolor[1] = ecolor[1];
237 prim->ecolor[2] = ecolor[2];
238
239 if ((prim->mykind = mgps_primclip(prim)) == PRIM_INVIS)
240 _mgpsc->mysort->cvert = prim->index;
241 else
242 {
243 _mgpsc->mysort->cvert = prim->index + prim->numvts;
244 _mgpsc->mysort->cprim++;
245 }
246
247 if (_mgpsc->mysort->cprim > _mgpsc->mysort->primnum)
248 {
249 _mgpsc->mysort->primnum*=2;
250 vvneeds(&(_mgpsc->mysort->prims), _mgpsc->mysort->primnum);
251 vvneeds(&(_mgpsc->mysort->primsort), _mgpsc->mysort->primnum);
252 }
253 break;
254
255 default:
256 fprintf(stderr,"unknown type of primitive.\n");
257 break;
258 }
259 }
260
261 /*
262 Function: mgps_primcomp
263 Description: Depth sort by comparing two primitives in a call from qsort()
264 (painters algorithm, no subdiv of polygons)
265 Author: Daeron Meyer
266 */
mgps_primcomp(const void * a,const void * b)267 int mgps_primcomp(const void *a, const void *b)
268 {
269 mgpsprim *prim = VVEC(_mgpsc->mysort->prims, mgpsprim);
270
271 if (prim[*(int*)a].depth < prim[*(int*)b].depth)
272 return 1;
273 else
274 return -1;
275 }
276
277 /*
278 Function: mgps_sortdisplaylist
279 Description: Does depth sorting of primitives.
280 Author: Daeron Meyer
281 */
mgps_sortdisplaylist(void)282 void mgps_sortdisplaylist(void)
283 {
284 static int *primp;
285
286 primp = VVEC(_mgpsc->mysort->primsort, int);
287 qsort(primp, _mgpsc->mysort->cprim, sizeof(int), &mgps_primcomp);
288 }
289
290 /*
291 Function: mgps_showdisplaylist
292 Description: render display list to display
293 Author: Daeron Meyer, Tim Rowley
294 */
mgps_showdisplaylist(FILE * outf)295 void mgps_showdisplaylist(FILE *outf)
296 {
297 CPoint3 *vts;
298 int ref, *primp;
299 mgpsprim *prim, *prim2;
300 static int width;
301 static int height;
302
303 WnGet(_mgc->win, WN_XSIZE, &width);
304 WnGet(_mgc->win, WN_YSIZE, &height);
305
306 MGPS_startPS(outf, &(_mgc->background), width/(double)height,
307 width, height);
308
309 primp = VVEC(_mgpsc->mysort->primsort, int);
310 prim2 = VVEC(_mgpsc->mysort->prims, mgpsprim);
311 vts = VVEC(_mgpsc->mysort->pverts, CPoint3);
312
313 for (ref = 0; ref < _mgpsc->mysort->cprim; ref++)
314 {
315 prim = &(prim2[primp[ref]]);
316 switch (prim->mykind)
317 {
318 case PRIM_POLYGON:
319 MGPS_poly(vts+prim->index, prim->numvts, prim->color);
320 break;
321
322 case PRIM_SPOLYGON:
323 MGPS_spoly(vts+prim->index, prim->numvts);
324 break;
325
326 case PRIM_EPOLYGON:
327 MGPS_epoly(vts+prim->index, prim->numvts, prim->color,
328 prim->ewidth, prim->ecolor);
329 break;
330
331 case PRIM_SEPOLYGON:
332 MGPS_sepoly(vts+prim->index, prim->numvts,
333 prim->ewidth, prim->ecolor);
334 break;
335
336 case PRIM_SLINE:
337 MGPS_spolyline(vts+prim->index, prim->numvts, prim->ewidth);
338 break;
339
340 case PRIM_LINE:
341 MGPS_polyline(vts+prim->index, prim->numvts,
342 prim->ewidth, prim->ecolor);
343 break;
344
345 case PRIM_INVIS:
346 break;
347
348 default:
349 break;
350 }
351 }
352 MGPS_finishPS();
353 }
354
355 void
mgps_appearance(struct mgastk * ma,int mask)356 mgps_appearance( struct mgastk *ma, int mask )
357 {
358 Appearance *ap = &(ma->ap);
359
360 if (mask & APF_LINEWIDTH)
361 {
362 curwidth = ap->linewidth-1;
363 _mgc->has &= ~HAS_POINT;
364 }
365
366 if (mask & APF_SHADING)
367 {
368 if (IS_SHADED(ap->shading) && ma->shader != NULL) {
369 /* Use software shader if one exists and user wants lighting */
370 ma->flags |= MGASTK_SHADER;
371 } else {
372 /* No software shading, just use raw colors */
373 ma->flags &= ~MGASTK_SHADER;
374 }
375 }
376 }
377
378 /*
379 * Local Variables: ***
380 * mode: c ***
381 * c-basic-offset: 4 ***
382 * End: ***
383 */
384
385