source: trunk/sys/TinyGL/src/ztriangle.h @ 233

Last change on this file since 233 was 1, checked in by alain, 7 years ago

First import

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