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 #if defined(ZBUFFER)
22 #define ZCODE(x) x
23 #else
24 #define ZCODE(x)
25 #endif
26
27 #ifdef GOURAUD
28 #ifdef COLOR
29 #define GCODE(x)
30 #define CCODE(x) x
31 #else
32 #define GCODE(x) x
33 #define CCODE(x)
34 #endif
35 #define CGCODE(x) x
36 #else
37 #define CCODE(x)
38 #define GCODE(x)
39 #define CGCODE(x)
40 #endif
41
42 static void
WIDENAME(unsigned char * buf,float * zbuf,int zwidth,int width,int height,int x1,int y1,double z1,int r1,int g1,int b1,int x2,int y2,double z2,int r2,int g2,int b2,int lwidth,int * color)43 WIDENAME (unsigned char *buf, float *zbuf, int zwidth, int width, int height,
44 int x1, int y1,
45 #ifdef ZBUFFER
46 double z1,
47 #endif
48 #ifdef GOURAUD
49 int r1,
50 #ifdef COLOR
51 int g1, int b1,
52 #endif
53 #endif
54 int x2, int y2,
55 #ifdef ZBUFFER
56 double z2,
57 #endif
58 #ifdef GOURAUD
59 int r2,
60 #ifdef COLOR
61 int g2, int b2,
62 #endif
63 #endif
64 int lwidth, int *color)
65 {
66 int d, x, y, ax, ay, sx, dx, dy;
67 int i, end;
68 #ifdef ZBUFFER
69 double delta=0, z;
70 #endif
71 #ifdef GOURAUD
72 double r, rdelta;
73 #ifdef COLOR
74 double g, b, gdelta, bdelta;
75 #endif
76 #endif
77 #if defined(ZBUFFER) || defined(GOURAUD)
78 int total;
79 #endif
80 #ifdef PTR_INIT
81 PTR_TYPE *ptr = (PTR_TYPE *)buf;
82 int ptrIncr = PTR_INCR;
83 #endif
84 #ifdef VARIABLES
85 VARIABLES
86 #endif
87
88 dx = x2-x1;
89 dy = y2-y1;
90
91 ax = ABS(dx)<<1;
92 ay = ABS(dy)<<1;
93
94 sx = SGN(dx);
95
96 x = x1;
97 y = y1;
98 ZCODE(z = z1;)
99 CGCODE(r = r1;)
100 CCODE(g = g1; b = b1;)
101 #if defined(ZBUFFER) || defined(GOURAUD)
102 total = ABS(dx)+ABS(dy);
103 if(total == 0) total = 1;
104 #endif
105 ZCODE(delta = (z2-z1)/total;)
106 CGCODE(rdelta = (r2-r1)/(double)total;)
107 CCODE(gdelta = (g2-g1)/(double)total;
108 bdelta = (b2-b1)/(double)total;)
109 if (ax>ay)
110 { /* x dominant */
111 d = ay-(ax>>1);
112 for (;;)
113 {
114 for (i=MAX(0,y-lwidth/2), end=MIN(height,y-lwidth/2+lwidth); i<end; i++)
115 {
116 #ifdef ZBUFFER
117 if (z<zbuf[i*zwidth+x])
118 {
119 WIDEYDOPIXEL
120 zbuf[i*zwidth+x] = z;
121 }
122 #else
123 WIDEYDOPIXEL
124 #endif
125 }
126 if (x==x2) break;
127 if (d>=0)
128 {
129 y++;
130 ZCODE(z += delta;)
131 CGCODE(r += rdelta;)
132 CCODE(g += gdelta; b += bdelta;)
133 d -= ax;
134 }
135 x += sx;
136 ZCODE(z += delta;)
137 CGCODE(r += rdelta;)
138 CCODE(g += gdelta; b += bdelta;)
139 d += ay;
140 }
141 }
142 else
143 { /* y dominant */
144 d = ax-(ay>>1);
145 for (;;)
146 {
147 for (i=MAX(0,x-lwidth/2), end=MIN(zwidth,x-lwidth/2+lwidth); i<end; i++)
148 {
149 #ifdef ZBUFFER
150 if (z<zbuf[y*zwidth+i])
151 {
152 WIDEXDOPIXEL
153 zbuf[y*zwidth+i] = z;
154 }
155 #else
156 WIDEXDOPIXEL
157 #endif
158 }
159 if (y==y2) break;
160 if (d>=0)
161 {
162 x += sx;
163 ZCODE(z += delta;)
164 CGCODE(r += rdelta;)
165 CCODE(g += gdelta; b += bdelta;)
166 d -= ay;
167 }
168 y++;
169 ZCODE(z += delta;)
170 CGCODE(r += rdelta;)
171 CCODE(g += gdelta; b += bdelta;)
172 d += ax;
173 }
174 }
175 }
176
177 void
NAME(unsigned char * buf,float * zbuf,int zwidth,int width,int height,CPoint3 * p1,CPoint3 * p2,int lwidth,int * color)178 NAME (unsigned char *buf, float *zbuf, int zwidth,
179 int width, int height, CPoint3 *p1, CPoint3 *p2, int lwidth, int *color)
180 {
181 int d, x, y, ax, ay, sx, dx, dy;
182 int x1, y1, x2, y2;
183 #ifdef PTR_INIT
184 PTR_TYPE *ptr;
185 int ptrIncr = PTR_INCR;
186 #endif
187 #ifdef ZBUFFER
188 float *zptr;
189 double delta=0, z, z1, z2;
190 #endif
191 #ifdef GOURAUD
192 int r1, r2;
193 double r, rdelta;
194 #ifdef COLOR
195 int g1, g2, b1, b2;
196 double g, b, gdelta, bdelta;
197 #endif
198 #endif
199 #if defined(ZBUFFER) || defined(GOURAUD)
200 int total;
201 #endif
202 #ifdef VARIABLES
203 VARIABLES
204 #endif
205
206 if (p2->y<p1->y)
207 {
208 x1 = p2->x; y1 = p2->y;
209 x2 = p1->x; y2 = p1->y;
210 ZCODE(z1 = p2->z - _mgc->zfnudge; z2 = p1->z - _mgc->zfnudge;)
211 CGCODE(r1 = 255*p2->vcol.r; r2 = 255*p1->vcol.r;)
212 CCODE(g1 = 255*p2->vcol.g; b1 = 255*p2->vcol.b;
213 g2 = 255*p1->vcol.g; b2 = 255*p1->vcol.b;)
214 }
215 else
216 {
217 x1 = p1->x; y1 = p1->y;
218 x2 = p2->x; y2 = p2->y;
219 ZCODE(z1 = p1->z - _mgc->zfnudge; z2 = p2->z - _mgc->zfnudge;)
220 CGCODE(r1 = 255*p1->vcol.r; r2 = 255*p2->vcol.r;)
221 CCODE(g1 = 255*p1->vcol.g; b1 = 255*p1->vcol.b;
222 g2 = 255*p2->vcol.g; b2 = 255*p2->vcol.b;)
223 }
224
225 if (lwidth > 1)
226 {
227 WIDENAME (buf, zbuf, zwidth, width, height, x1, y1,
228 #ifdef ZBUFFER
229 z1,
230 #endif
231 #ifdef GOURAUD
232 r1,
233 #ifdef COLOR
234 g1, b1,
235 #endif
236 #endif
237 x2, y2,
238 #ifdef ZBUFFER
239 z2,
240 #endif
241 #ifdef GOURAUD
242 r2,
243 #ifdef COLOR
244 g2, b2,
245 #endif
246 #endif
247 lwidth, color);
248 return;
249 }
250 #ifdef PTR_INIT
251 ptr = PTR_INIT;
252 #endif
253 ZCODE(zptr = zbuf+y1*zwidth+x1;)
254
255 dx = x2-x1;
256 dy = y2-y1;
257
258 ax = ABS(dx)<<1;
259 ay = ABS(dy)<<1;
260
261 sx = SGN(dx);
262
263 x = x1;
264 y = y1;
265 ZCODE(z = z1;)
266 CGCODE(r = r1;)
267 CCODE(g = g1; b = b1;)
268 #if defined(ZBUFFER) || defined(GOURAUD)
269 total = ABS(dx)+ABS(dy);
270 if(total == 0) total = 1;
271 #endif
272 ZCODE(delta = (z2-z1)/total;)
273 CGCODE(rdelta = (r2-r1)/(double)total;)
274 CCODE(gdelta = (g2-g1)/(double)total;
275 bdelta = (b2-b1)/(double)total;)
276
277 if (ax>ay)
278 { /* x dominant */
279 d = ay-(ax>>1);
280 for (;;)
281 {
282 #ifdef ZBUFFER
283 if (z<*zptr)
284 {
285 DOPIXEL
286 *zptr = z;
287 }
288 #else
289 DOPIXEL
290 #endif
291 if (x==x2) break;
292 if (d>=0)
293 {
294 y++;
295 ZCODE(z += delta;)
296 CGCODE(r += rdelta;)
297 CCODE(g += gdelta; b += bdelta;)
298 #ifdef PTR_INIT
299 ptr += ptrIncr;
300 #endif
301 ZCODE(zptr += zwidth;)
302 d -= ax;
303 }
304 x += sx;
305 ZCODE(z += delta;)
306 CGCODE(r += rdelta;)
307 CCODE(g += gdelta; b += bdelta;)
308 #ifdef PTR_INIT
309 ptr += sx;
310 #endif
311 ZCODE(zptr += sx;)
312 d += ay;
313 }
314 }
315 else
316 { /* y dominant */
317 d = ax-(ay>>1);
318 for (;;)
319 {
320 #ifdef ZBUFFER
321 if (z<*zptr)
322 {
323 DOPIXEL
324 ZCODE(*zptr = z;)
325 }
326 #else
327 DOPIXEL
328 #endif
329 if (y==y2) break;
330 if (d>=0)
331 {
332 x += sx;
333 ZCODE(z += delta;)
334 CGCODE(r += rdelta;)
335 CCODE(g += gdelta; b += bdelta;)
336 #ifdef PTR_INIT
337 ptr += sx;
338 #endif
339 ZCODE(zptr += sx;)
340 d -= ay;
341 }
342 y++;
343 ZCODE(z += delta;)
344 CGCODE(r += rdelta;)
345 CCODE(g += gdelta; b += bdelta;)
346 #ifdef PTR_INIT
347 ptr += ptrIncr;
348 #endif
349 ZCODE(zptr += zwidth;)
350 d += ax;
351 }
352 }
353 }
354
355 #undef ZCODE
356 #undef CCODE
357 #undef GCODE
358 #undef CGCODE
359
360 #undef WIDENAME
361 #undef NAME
362 #undef ZBUFFER
363 #undef GOURAUD
364 #undef COLOR
365 #undef PTR_TYPE
366 #undef PTR_INIT
367 #undef PTR_INCR
368 #undef VARIABLES
369 #undef DOPIXEL
370 #undef WIDEXDOPIXEL
371 #undef WIDEYDOPIXEL
372