TinyGL 0.4.1 for MinGW
ztriangle.h
Go to the documentation of this file.
1/*
2 * We draw a triangle with various interpolations
3 */
4
5{
6 ZBufferPoint *t,*pr1,*pr2,*l1,*l2;
7 float fdx1, fdx2, fdy1, fdy2, fz, d1, d2;
8 unsigned short *pz1;
11
13
16/* warning: x2 is multiplied by 2^16 */
17 int x2,dx2dy2;
18
19#ifdef INTERP_Z
20 int z1,dzdx,dzdy,dzdl_min,dzdl_max;
21#endif
22#ifdef INTERP_RGB
23 int r1,drdx,drdy,drdl_min,drdl_max;
24 int g1,dgdx,dgdy,dgdl_min,dgdl_max;
25 int b1,dbdx,dbdy,dbdl_min,dbdl_max;
26#endif
27#ifdef INTERP_ST
28 int s1,dsdx,dsdy,dsdl_min,dsdl_max;
29 int t1,dtdx,dtdy,dtdl_min,dtdl_max;
30#endif
31#ifdef INTERP_STZ
32 float sz1,dszdx,dszdy,dszdl_min,dszdl_max;
33 float tz1,dtzdx,dtzdy,dtzdl_min,dtzdl_max;
34#endif
35
36 /* we sort the vertex with increasing y */
37 if (p1->y < p0->y) {
38 t = p0;
39 p0 = p1;
40 p1 = t;
41 }
42 if (p2->y < p0->y) {
43 t = p2;
44 p2 = p1;
45 p1 = p0;
46 p0 = t;
47 } else if (p2->y < p1->y) {
48 t = p1;
49 p1 = p2;
50 p2 = t;
51 }
52
53 /* we compute dXdx and dXdy for all interpolated values */
54
55 fdx1 = p1->x - p0->x;
56 fdy1 = p1->y - p0->y;
57
58 fdx2 = p2->x - p0->x;
59 fdy2 = p2->y - p0->y;
60
61 fz = fdx1 * fdy2 - fdx2 * fdy1;
62 if (fz == 0)
63 return;
64 fz = 1.0 / fz;
65
66 fdx1 *= fz;
67 fdy1 *= fz;
68 fdx2 *= fz;
69 fdy2 *= fz;
70
71#ifdef INTERP_Z
72 d1 = p1->z - p0->z;
73 d2 = p2->z - p0->z;
74 dzdx = (int) (fdy2 * d1 - fdy1 * d2);
75 dzdy = (int) (fdx1 * d2 - fdx2 * d1);
76#endif
77
78#ifdef INTERP_RGB
79 d1 = p1->r - p0->r;
80 d2 = p2->r - p0->r;
81 drdx = (int) (fdy2 * d1 - fdy1 * d2);
82 drdy = (int) (fdx1 * d2 - fdx2 * d1);
83
84 d1 = p1->g - p0->g;
85 d2 = p2->g - p0->g;
86 dgdx = (int) (fdy2 * d1 - fdy1 * d2);
87 dgdy = (int) (fdx1 * d2 - fdx2 * d1);
88
89 d1 = p1->b - p0->b;
90 d2 = p2->b - p0->b;
91 dbdx = (int) (fdy2 * d1 - fdy1 * d2);
92 dbdy = (int) (fdx1 * d2 - fdx2 * d1);
93
94#endif
95
96#ifdef INTERP_ST
97 d1 = p1->s - p0->s;
98 d2 = p2->s - p0->s;
99 dsdx = (int) (fdy2 * d1 - fdy1 * d2);
100 dsdy = (int) (fdx1 * d2 - fdx2 * d1);
101
102 d1 = p1->t - p0->t;
103 d2 = p2->t - p0->t;
104 dtdx = (int) (fdy2 * d1 - fdy1 * d2);
105 dtdy = (int) (fdx1 * d2 - fdx2 * d1);
106#endif
107
108#ifdef INTERP_STZ
109 {
110 float zz;
111 zz=(float) p0->z;
112 p0->sz= (float) p0->s * zz;
113 p0->tz= (float) p0->t * zz;
114 zz=(float) p1->z;
115 p1->sz= (float) p1->s * zz;
116 p1->tz= (float) p1->t * zz;
117 zz=(float) p2->z;
118 p2->sz= (float) p2->s * zz;
119 p2->tz= (float) p2->t * zz;
120
121 d1 = p1->sz - p0->sz;
122 d2 = p2->sz - p0->sz;
123 dszdx = (fdy2 * d1 - fdy1 * d2);
124 dszdy = (fdx1 * d2 - fdx2 * d1);
125
126 d1 = p1->tz - p0->tz;
127 d2 = p2->tz - p0->tz;
128 dtzdx = (fdy2 * d1 - fdy1 * d2);
129 dtzdy = (fdx1 * d2 - fdx2 * d1);
130 }
131#endif
132
133 /* screen coordinates */
134
135 pp1 = (PIXEL *) ((char *) zb->pbuf + zb->linesize * p0->y);
136 pz1 = zb->zbuf + p0->y * zb->xsize;
137
139
140 for(part=0;part<2;part++) {
141 if (part == 0) {
142 if (fz > 0) {
143 update_left=1;
144 update_right=1;
145 l1=p0;
146 l2=p2;
147 pr1=p0;
148 pr2=p1;
149 } else {
150 update_left=1;
151 update_right=1;
152 l1=p0;
153 l2=p1;
154 pr1=p0;
155 pr2=p2;
156 }
157 nb_lines = p1->y - p0->y;
158 } else {
159 /* second part */
160 if (fz > 0) {
161 update_left=0;
162 update_right=1;
163 pr1=p1;
164 pr2=p2;
165 } else {
166 update_left=1;
167 update_right=0;
168 l1=p1;
169 l2=p2;
170 }
171 nb_lines = p2->y - p1->y + 1;
172 }
173
174 /* compute the values for the left edge */
175
176 if (update_left) {
177 dy1 = l2->y - l1->y;
178 dx1 = l2->x - l1->x;
179 if (dy1 > 0)
180 tmp = (dx1 << 16) / dy1;
181 else
182 tmp = 0;
183 x1 = l1->x;
184 error = 0;
185 derror = tmp & 0x0000ffff;
186 dxdy_min = tmp >> 16;
187 dxdy_max = dxdy_min + 1;
188
189#ifdef INTERP_Z
190 z1=l1->z;
191 dzdl_min=(dzdy + dzdx * dxdy_min);
192 dzdl_max=dzdl_min + dzdx;
193#endif
194#ifdef INTERP_RGB
195 r1=l1->r;
196 drdl_min=(drdy + drdx * dxdy_min);
197 drdl_max=drdl_min + drdx;
198
199 g1=l1->g;
200 dgdl_min=(dgdy + dgdx * dxdy_min);
201 dgdl_max=dgdl_min + dgdx;
202
203 b1=l1->b;
204 dbdl_min=(dbdy + dbdx * dxdy_min);
205 dbdl_max=dbdl_min + dbdx;
206#endif
207#ifdef INTERP_ST
208 s1=l1->s;
209 dsdl_min=(dsdy + dsdx * dxdy_min);
210 dsdl_max=dsdl_min + dsdx;
211
212 t1=l1->t;
213 dtdl_min=(dtdy + dtdx * dxdy_min);
214 dtdl_max=dtdl_min + dtdx;
215#endif
216#ifdef INTERP_STZ
217 sz1=l1->sz;
218 dszdl_min=(dszdy + dszdx * dxdy_min);
219 dszdl_max=dszdl_min + dszdx;
220
221 tz1=l1->tz;
222 dtzdl_min=(dtzdy + dtzdx * dxdy_min);
223 dtzdl_max=dtzdl_min + dtzdx;
224#endif
225 }
226
227 /* compute values for the right edge */
228
229 if (update_right) {
230 dx2 = (pr2->x - pr1->x);
231 dy2 = (pr2->y - pr1->y);
232 if (dy2>0)
233 dx2dy2 = ( dx2 << 16) / dy2;
234 else
235 dx2dy2 = 0;
236 x2 = pr1->x << 16;
237 }
238
239 /* we draw all the scan line of the part */
240
241 while (nb_lines>0) {
242 nb_lines--;
243#ifndef DRAW_LINE
244 /* generic draw line */
245 {
246 register PIXEL *pp;
247 register int n;
248#ifdef INTERP_Z
249 register unsigned short *pz;
250 register unsigned int z,zz;
251#endif
252#ifdef INTERP_RGB
253 register unsigned int or1,og1,ob1;
254#endif
255#ifdef INTERP_ST
256 register unsigned int s,t;
257#endif
258#ifdef INTERP_STZ
259 float sz,tz;
260#endif
261
262 n=(x2 >> 16) - x1;
263 pp=(PIXEL *)((char *)pp1 + x1 * PSZB);
264#ifdef INTERP_Z
265 pz=pz1+x1;
266 z=z1;
267#endif
268#ifdef INTERP_RGB
269 or1 = r1;
270 og1 = g1;
271 ob1 = b1;
272#endif
273#ifdef INTERP_ST
274 s=s1;
275 t=t1;
276#endif
277#ifdef INTERP_STZ
278 sz=sz1;
279 tz=tz1;
280#endif
281 while (n>=3) {
282 PUT_PIXEL(0);
283 PUT_PIXEL(1);
284 PUT_PIXEL(2);
285 PUT_PIXEL(3);
286#ifdef INTERP_Z
287 pz+=4;
288#endif
289 pp=(PIXEL *)((char *)pp + 4 * PSZB);
290 n-=4;
291 }
292 while (n>=0) {
293 PUT_PIXEL(0);
294#ifdef INTERP_Z
295 pz+=1;
296#endif
297 pp=(PIXEL *)((char *)pp + PSZB);
298 n-=1;
299 }
300 }
301#else
302 DRAW_LINE();
303#endif
304
305 /* left edge */
306 error+=derror;
307 if (error > 0) {
308 error-=0x10000;
309 x1+=dxdy_max;
310#ifdef INTERP_Z
311 z1+=dzdl_max;
312#endif
313#ifdef INTERP_RGB
314 r1+=drdl_max;
315 g1+=dgdl_max;
316 b1+=dbdl_max;
317#endif
318#ifdef INTERP_ST
319 s1+=dsdl_max;
320 t1+=dtdl_max;
321#endif
322#ifdef INTERP_STZ
323 sz1+=dszdl_max;
324 tz1+=dtzdl_max;
325#endif
326 } else {
327 x1+=dxdy_min;
328#ifdef INTERP_Z
329 z1+=dzdl_min;
330#endif
331#ifdef INTERP_RGB
332 r1+=drdl_min;
333 g1+=dgdl_min;
334 b1+=dbdl_min;
335#endif
336#ifdef INTERP_ST
337 s1+=dsdl_min;
338 t1+=dtdl_min;
339#endif
340#ifdef INTERP_STZ
341 sz1+=dszdl_min;
342 tz1+=dtzdl_min;
343#endif
344 }
345
346 /* right edge */
347 x2+=dx2dy2;
348
349 /* screen coordinates */
350 pp1=(PIXEL *)((char *)pp1 + zb->linesize);
351 pz1+=zb->xsize;
352 }
353 }
354}
355
356#undef INTERP_Z
357#undef INTERP_RGB
358#undef INTERP_ST
359#undef INTERP_STZ
360
361#undef DRAW_INIT
362#undef DRAW_LINE
363#undef PUT_PIXEL
float sz
Definition: zbuffer.h:94
float tz
Definition: zbuffer.h:94
#define PSZB
Definition: zbuffer.h:49
unsigned short PIXEL
Definition: zbuffer.h:48
register PIXEL * pp
Definition: zline.h:4
#define PUT_PIXEL(_a)
#define DRAW_LINE()
int dx1
Definition: ztriangle.h:12
int error
Definition: ztriangle.h:14
int dy1
Definition: ztriangle.h:12
DRAW_INIT()
float d1
Definition: ztriangle.h:7
int derror
Definition: ztriangle.h:14
int part
Definition: ztriangle.h:10
int nb_lines
Definition: ztriangle.h:12
int dxdy_max
Definition: ztriangle.h:15
int update_left
Definition: ztriangle.h:10
int update_right
Definition: ztriangle.h:10
int tmp
Definition: ztriangle.h:12
int dx2
Definition: ztriangle.h:12
unsigned short * pz1
Definition: ztriangle.h:8
int x1
Definition: ztriangle.h:15
float fdx1
Definition: ztriangle.h:5
int dy2
Definition: ztriangle.h:12
float d2
Definition: ztriangle.h:7
float fdy2
Definition: ztriangle.h:7
float fz
Definition: ztriangle.h:7
int dxdy_min
Definition: ztriangle.h:15
int x2
Definition: ztriangle.h:17
int dx2dy2
Definition: ztriangle.h:17
float fdx2
Definition: ztriangle.h:7
PIXEL * pp1
Definition: ztriangle.h:9
float fdy1
Definition: ztriangle.h:7