Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5098 clevermous 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
  /* 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
 
138
  DRAW_INIT();
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