1 /*
2
3 3DKIT version 1.3
4 High speed 3D graphics and rendering library for Linux.
5
6 Copyright (C) 1996, 1997 Paul Sheer psheer@icon.co.za
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public
19 License along with this library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21 MA 02111-1307, USA
22
23 */
24
25
26 #ifdef WRAP
27 #ifdef INTERP
gl_wtriangle(int x0,int y0,int xd0,int yd0,int z0,int x1,int y1,int xd1,int yd1,int z1,int x2,int y2,int xd2,int yd2,int z2,TD_tridata * tri)28 void gl_wtriangle (int x0, int y0, int xd0, int yd0, int z0,
29 int x1, int y1, int xd1, int yd1, int z1,
30 int x2, int y2, int xd2, int yd2, int z2,
31 TD_tridata * tri)
32 #else
33 void gl_swtriangle (int x0, int y0, int xd0, int yd0,
34 int x1, int y1, int xd1, int yd1,
35 int x2, int y2, int xd2, int yd2, int z0,
36 TD_tridata * tri)
37 #endif
38 #else
39 #ifdef INTERP
40 void gl_triangle (int x0, int y0, int z0,
41 int x1, int y1, int z1,
42 int x2, int y2, int z2, int bf)
43 #else
44 void gl_striangle (int x0, int y0,
45 int x1, int y1,
46 int x2, int y2, int z0, int bf)
47 #endif
48 #endif
49 {
50 void (*colhline_pos) (void);
51 void (*colhline_neg) (void);
52
53 int dir;
54 long X;
55
56 long nz;
57 long g0, g1h = 0, g1l = 0;
58 #ifdef INTERP
59 long c0;
60 long c_y;
61 #endif
62 #ifdef WRAP
63 long X0, Y0;
64 int bf = tri->bf;
65 long xd_y, yd_y;
66 #endif
67
68 dir = 1;
69
70 /*Max triangle size in the order of (2^31) >> SHLB)^(.5) : */
71
72 if ((nz = (x0 - x1) * (y0 - y2) - (y0 - y1) * (x0 - x2)) == 0)
73 return; /*the points are collinear. */
74
75 #ifdef INTERP
76 c_x = -(((y0 - y1) * (z0 - z2) - (z0 - z1) * (y0 - y2)) << SHLB) / nz;
77 c_y = -(((z0 - z1) * (x0 - x2) - (x0 - x1) * (z0 - z2)) << SHLB) / nz;
78 #endif
79
80 #ifdef WRAP
81 xd_x = -(((y0 - y1) * (xd0 - xd2) - (xd0 - xd1) * (y0 - y2)) << SHLB) / nz;
82 xd_y = -(((xd0 - xd1) * (x0 - x2) - (x0 - x1) * (xd0 - xd2)) << SHLB) / nz;
83
84 yd_x = -(((y0 - y1) * (yd0 - yd2) - (yd0 - yd1) * (y0 - y2)) << SHLB) / nz;
85 yd_y = -(((yd0 - yd1) * (x0 - x2) - (x0 - x1) * (yd0 - yd2)) << SHLB) / nz;
86 #endif
87
88 #ifdef INTERP
89 if ((abs (c_x) > (6 << SHLB)) || (abs (c_y) > (6 << SHLB))) {
90 int tz0, tz1;
91
92 /*so that high colour gradients don't screw up at the edges. */
93 /*4 is the maximum gradient per pixel. */
94
95 c_x >>= 2;
96 c_y >>= 2;
97 tz0 = ((2 * z0 + z1 + z2) << SHLB) / 4;
98 tz1 = ((z0 + 2 * z1 + z2) << SHLB) / 4;
99 z2 = ((z0 + z1 + 2 * z2) << SHLB) / 4;
100 z0 = tz0;
101 z1 = tz1;
102 } else {
103 z0 <<= SHLB;
104 z1 <<= SHLB;
105 z2 <<= SHLB;
106 }
107 #endif
108
109 /************** BOOLEAN LOGIC HERE ************/
110 /* The following allows a triangle to have a different picture on either side */
111 /* To print triangles that don't appear when viewed from behind use bf = 0|1 */
112 /* To print triangles that appear with a different picture when viewed from */
113 /* behind use bf = 2|3 */
114
115 #ifdef WRAP
116 dat = tri->bitmap1;
117 if (nz > 0) { /* nz is the cross product of the vectors of the two sides
118 it indicates whether the points were ordered clockwise
119 or anti-clockwise (you can find out which way by testing) */
120 if (bf == 1)
121 return;
122 if (bf == 3)
123 dat = tri->bitmap1;
124 dir++;
125 } else {
126 if (!bf)
127 return;
128 if (bf == 2)
129 dat = tri->bitmap2;
130 }
131 #else
132 if (nz > 0) {
133 if (bf == 1)
134 return;
135 dir++;
136 } else {
137 if (!bf)
138 return;
139 }
140 #endif
141
142 #define Xchg(a,b) {X=(a);(a)=(b);(b)=X;}
143
144 if (y1 < y0) {
145 Xchg (y0, y1);
146 Xchg (x0, x1);
147 #ifdef INTERP
148 Xchg (z0, z1);
149 #endif
150 #ifdef WRAP
151 Xchg (xd0, xd1);
152 Xchg (yd0, yd1);
153 #endif
154 dir++;
155 }
156 if (y2 < y1) {
157 Xchg (y2, y1);
158 Xchg (x2, x1);
159 #ifdef INTERP
160 Xchg (z2, z1);
161 #endif
162 #ifdef WRAP
163 Xchg (xd2, xd1);
164 Xchg (yd2, yd1);
165 #endif
166
167 dir++;
168 }
169 if (y1 < y0) {
170 Xchg (y0, y1);
171 Xchg (x0, x1);
172 #ifdef INTERP
173 Xchg (z0, z1);
174 #endif
175 #ifdef WRAP
176 Xchg (xd0, xd1);
177 Xchg (yd0, yd1);
178 #endif
179 dir++;
180 }
181 _color_lookup = color_lookup;
182 #ifdef INTERP
183 c0 = z0;
184 #else
185 if(BYTESPERPIXEL == 1) {
186 c = z0;
187 } else {
188 c = _color_lookup[z0];
189 }
190 #endif
191
192 #ifdef WRAP
193 X0 = xd0 << SHLB;
194 Y0 = yd0 << SHLB;
195 #endif
196
197 if (y2 == y0)
198 return;
199 g0 = ((long) (x2 - x0) << SHLB) / (y2 - y0);
200 if (y1 != y0)
201 g1h = ((long) (x1 - x0) << SHLB) / (y1 - y0);
202 if (y2 != y1)
203 g1l = ((long) (x2 - x1) << SHLB) / (y2 - y1);
204
205 dir = dir & 1;
206
207
208 /* Very large triangles (larger than the screen) sometimes become a problem,
209 if so: */
210 if (__clip) {
211 if (((abs (x0 - x1) + abs (x1 - x2) + abs (x0 - x2)) >
212 ((__clipx2 - __clipx1) * 2)) || ((y2 - y0) > (__clipy2 - __clipy1)))
213 return;
214 if (y2 < __clipy1 || y0 > __clipy2 ||
215 (x0 < __clipx1 && x1 < __clipx1 && x2 < __clipx1) ||
216 (x0 > __clipx2 && x1 > __clipx2 && x2 > __clipx2))
217 return;
218 }
219 dx0 = x0;
220 dy0 = y0;
221
222 if(tri_drawpoint) {
223 _tri_drawpoint = tri_drawpoint;
224 colhline_pos = linefuncs[(7 * 2) + (BYTESPERPIXEL - 1) * 16];
225 colhline_neg = linefuncs[(7 * 2) + (BYTESPERPIXEL - 1) * 16 + 1];
226 } else {
227 _tri_drawpoint = gl_setpixel;
228 colhline_pos = linefuncs[(MODETYPE * 2) + (BYTESPERPIXEL - 1) * 16];
229 colhline_neg = linefuncs[(MODETYPE * 2) + (BYTESPERPIXEL - 1) * 16 + 1];
230 }
231
232 #ifdef tri_set_color
233 #undef tri_set_color
234 #endif
235
236
237
238 #ifdef WRAP
239 #ifdef INTERP
240 #define tri_set_color \
241 xd = X0 + xd_x * px1 + xd_y * py; \
242 yd = Y0 + yd_x * px1 + yd_y * py; \
243 c = c0 + c_x * px1 + c_y * py;
244 #else
245 #define tri_set_color \
246 xd = X0 + xd_x * px1 + xd_y * py; \
247 yd = Y0 + yd_x * px1 + yd_y * py;
248 #endif
249 #else
250 #ifdef INTERP
251 #define tri_set_color \
252 c = c0 + c_x * px1 + c_y * py;
253 #else
254 #define tri_set_color
255 #endif
256 #endif
257
258 if (dir == 1) {
259 if (y1 != y0) {
260 py = 0;
261 if (x1 < x0) {
262 px1 = 0;
263 px2 = -((abs (g1h) >> 1)) >> SHLB;
264 } else {
265 px1 = ((abs (g0) >> 1)) >> SHLB;
266 px2 = 0;
267 }
268 tri_set_color;
269
270 colhline_neg ();
271 if ((py = 1) < y1 - y0)
272 for (; py < y1 - y0; py++) {
273 px1 = ((g0 * py) + (abs (g0) >> 1)) >> SHLB;
274 px2 = ((g1h * py) - (abs (g1h) >> 1)) >> SHLB;
275 tri_set_color;
276
277 colhline_neg ();
278 }
279 px1 = min (((g0 * py) + (abs (g0) >> 1)) >> SHLB, max (x2, x0) - x0);
280 px2 = x1 - x0;
281 tri_set_color;
282 colhline_neg ();
283 } else {
284 py = 0;
285 px1 = 0;
286 px2 = x1 - x0;
287 tri_set_color;
288
289 colhline_neg ();
290 }
291 if (y1 != y2) {
292 if ((py = y1 - y0 + 1) < y2 - y0)
293 for (; py < y2 - y0; py++) {
294 px1 = ((g0 * py) + (abs (g0) >> 1)) >> SHLB;
295 px2 = (((g1l * (py - y1 + y0)) - (abs (g1l) >> 1)) >> SHLB) + x1 - x0;
296 tri_set_color;
297
298 colhline_neg ();
299 }
300 if (x1 < x2) {
301 px1 = x2 - x0;
302 px2 = x2 - x0 - ((abs (g1l) >> 1) >> SHLB);
303 } else {
304 px1 = x2 - x0 + ((abs (g0) >> 1) >> SHLB);
305 px2 = x2 - x0;
306 }
307 tri_set_color;
308
309 colhline_neg ();
310 }
311 } else {
312 if (y1 != y0) {
313 py = 0;
314 if (x1 > x0) {
315 px1 = 0;
316 px2 = ((abs (g1h) >> 1)) >> SHLB;
317 } else {
318 px1 = -((abs (g0) >> 1)) >> SHLB;
319 px2 = 0;
320 }
321 tri_set_color;
322
323 colhline_pos ();
324 if ((py = 1) < y1 - y0)
325 for (; py < y1 - y0; py++) {
326 px1 = ((g0 * py) - (abs (g0) >> 1)) >> SHLB;
327 px2 = ((g1h * py) + (abs (g1h) >> 1)) >> SHLB;
328 tri_set_color;
329
330 colhline_pos ();
331 }
332 px1 = max (((g0 * py) - (abs (g0) >> 1)) >> SHLB, min (x2, x0) - x0);
333 px2 = x1 - x0;
334 tri_set_color;
335 colhline_pos ();
336 } else {
337 py = 0;
338 px1 = 0;
339 px2 = x1 - x0;
340 tri_set_color;
341 colhline_pos ();
342 }
343 if (y1 != y2) {
344 if ((py = y1 - y0 + 1) < y2 - y0)
345 for (; py < y2 - y0; py++) {
346 px1 = ((g0 * py) - (abs (g0) >> 1)) >> SHLB;
347 px2 = (((g1l * (py - y1 + y0)) + (abs (g1l) >> 1)) >> SHLB) + x1 - x0;
348 tri_set_color;
349
350 colhline_pos ();
351 }
352 if (x1 > x2) {
353 px1 = x2 - x0;
354 px2 = x2 - x0 + ((abs (g1l) >> 1) >> SHLB);
355 } else {
356 px1 = x2 - x0 - ((abs (g0) >> 1) >> SHLB);
357 px2 = x2 - x0;
358 }
359
360 tri_set_color;
361
362 colhline_pos ();
363 }
364 }
365 }
366