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