version 2.8
ztriangle.c
1 #include <stdlib.h>
2 #include "zbuffer.h"
3 
4 #define ZCMP(z,zpix) ((z) >= (zpix))
5 
6 void ZB_fillTriangleFlat(ZBuffer *zb,
7  ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
8 {
9 #if TGL_FEATURE_RENDER_BITS == 24
10  unsigned char colorR, colorG, colorB;
11 #else
12  int color;
13 #endif
14 
15 #define INTERP_Z
16 
17 #if TGL_FEATURE_RENDER_BITS == 24
18 
19 #define DRAW_INIT() \
20 { \
21  colorR=p2->r>>8; \
22  colorG=p2->g>>8; \
23  colorB=p2->b>>8; \
24 }
25 
26 #define PUT_PIXEL(_a) \
27 { \
28  zz=z >> ZB_POINT_Z_FRAC_BITS; \
29  if (ZCMP(zz,pz[_a])) { \
30  pp[3 * _a]=colorR;\
31  pp[3 * _a + 1]=colorG;\
32  pp[3 * _a + 2]=colorB;\
33  pz[_a]=zz; \
34  }\
35  z+=dzdx; \
36 }
37 
38 #else
39 
40 #define DRAW_INIT() \
41 { \
42  color=RGB_TO_PIXEL(p2->r,p2->g,p2->b); \
43 }
44 
45 #define PUT_PIXEL(_a) \
46 { \
47  zz=z >> ZB_POINT_Z_FRAC_BITS; \
48  if (ZCMP(zz,pz[_a])) { \
49  pp[_a]=color; \
50  pz[_a]=zz; \
51  } \
52  z+=dzdx; \
53 }
54 #endif /* TGL_FEATURE_RENDER_BITS == 24 */
55 
56 #include "ztriangle.h"
57 }
58 
59 /*
60  * Smooth filled triangle.
61  * The code below is very tricky :)
62  */
63 
64 void ZB_fillTriangleSmooth(ZBuffer *zb,
65  ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
66 {
67 #if TGL_FEATURE_RENDER_BITS == 16
68  int _drgbdx;
69 #endif
70 
71 #define INTERP_Z
72 #define INTERP_RGB
73 
74 #define SAR_RND_TO_ZERO(v,n) (v / (1<<n))
75 
76 #if TGL_FEATURE_RENDER_BITS == 24
77 
78 #define DRAW_INIT() \
79 { \
80 }
81 
82 #define PUT_PIXEL(_a) \
83 { \
84  zz=z >> ZB_POINT_Z_FRAC_BITS; \
85  if (ZCMP(zz,pz[_a])) { \
86  pp[3 * _a]=or1 >> 8;\
87  pp[3 * _a + 1]=og1 >> 8;\
88  pp[3 * _a + 2]=ob1 >> 8;\
89  pz[_a]=zz; \
90  }\
91  z+=dzdx; \
92  og1+=dgdx; \
93  or1+=drdx; \
94  ob1+=dbdx; \
95 }
96 
97 #elif TGL_FEATURE_RENDER_BITS == 16
98 
99 #define DRAW_INIT() \
100 { \
101  _drgbdx=(SAR_RND_TO_ZERO(drdx,6) << 22) & 0xFFC00000; \
102  _drgbdx|=SAR_RND_TO_ZERO(dgdx,5) & 0x000007FF; \
103  _drgbdx|=(SAR_RND_TO_ZERO(dbdx,7) << 12) & 0x001FF000; \
104 }
105 
106 
107 #define PUT_PIXEL(_a) \
108 { \
109  zz=z >> ZB_POINT_Z_FRAC_BITS; \
110  if (ZCMP(zz,pz[_a])) { \
111  tmp=rgb & 0xF81F07E0; \
112  pp[_a]=tmp | (tmp >> 16); \
113  pz[_a]=zz; \
114  } \
115  z+=dzdx; \
116  rgb=(rgb+drgbdx) & ( ~ 0x00200800); \
117 }
118 
119 #define DRAW_LINE() \
120 { \
121  register unsigned short *pz; \
122  register PIXEL *pp; \
123  register unsigned int tmp,z,zz,rgb,drgbdx; \
124  register int n; \
125  n=(x2 >> 16) - x1; \
126  pp=pp1+x1; \
127  pz=pz1+x1; \
128  z=z1; \
129  rgb=(r1 << 16) & 0xFFC00000; \
130  rgb|=(g1 >> 5) & 0x000007FF; \
131  rgb|=(b1 << 5) & 0x001FF000; \
132  drgbdx=_drgbdx; \
133  while (n>=3) { \
134  PUT_PIXEL(0); \
135  PUT_PIXEL(1); \
136  PUT_PIXEL(2); \
137  PUT_PIXEL(3); \
138  pz+=4; \
139  pp+=4; \
140  n-=4; \
141  } \
142  while (n>=0) { \
143  PUT_PIXEL(0); \
144  pz+=1; \
145  pp+=1; \
146  n-=1; \
147  } \
148 }
149 
150 #else
151 
152 #define DRAW_INIT() \
153 { \
154 }
155 
156 #define PUT_PIXEL(_a) \
157 { \
158  zz=z >> ZB_POINT_Z_FRAC_BITS; \
159  if (ZCMP(zz,pz[_a])) { \
160  pp[_a] = RGB_TO_PIXEL(or1, og1, ob1);\
161  pz[_a]=zz; \
162  }\
163  z+=dzdx; \
164  og1+=dgdx; \
165  or1+=drdx; \
166  ob1+=dbdx; \
167 }
168 
169 #endif /* TGL_FEATURE_RENDER_BITS */
170 
171 #include "ztriangle.h"
172 }
173 
174 void ZB_setTexture(ZBuffer *zb,PIXEL *texture)
175 {
176  zb->current_texture=texture;
177 }
178 
179 void ZB_fillTriangleMapping(ZBuffer *zb,
180  ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
181 {
182  PIXEL *texture;
183 
184 #define INTERP_Z
185 #define INTERP_ST
186 
187 #define DRAW_INIT() \
188 { \
189  texture=zb->current_texture; \
190 }
191 
192 #if TGL_FEATURE_RENDER_BITS == 24
193 
194 #define PUT_PIXEL(_a) \
195 { \
196  unsigned char *ptr;\
197  zz=z >> ZB_POINT_Z_FRAC_BITS; \
198  if (ZCMP(zz,pz[_a])) { \
199  ptr = texture + (((t & 0x3FC00000) | s) >> 14) * 3; \
200  pp[3 * _a]= ptr[0];\
201  pp[3 * _a + 1]= ptr[1];\
202  pp[3 * _a + 2]= ptr[2];\
203  pz[_a]=zz; \
204  } \
205  z+=dzdx; \
206  s+=dsdx; \
207  t+=dtdx; \
208 }
209 
210 #else
211 
212 #define PUT_PIXEL(_a) \
213 { \
214  zz=z >> ZB_POINT_Z_FRAC_BITS; \
215  if (ZCMP(zz,pz[_a])) { \
216  pp[_a]=texture[((t & 0x3FC00000) | s) >> 14]; \
217  pz[_a]=zz; \
218  } \
219  z+=dzdx; \
220  s+=dsdx; \
221  t+=dtdx; \
222 }
223 
224 #endif
225 
226 #include "ztriangle.h"
227 }
228 
229 /*
230  * Texture mapping with perspective correction.
231  * We use the gradient method to make less divisions.
232  * TODO: pipeline the division
233  */
234 #if 1
235 
236 void ZB_fillTriangleMappingPerspective(ZBuffer *zb,
237  ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
238 {
239  PIXEL *texture;
240  float fdzdx,fndzdx,ndszdx,ndtzdx;
241 
242 #define INTERP_Z
243 #define INTERP_STZ
244 
245 #define NB_INTERP 8
246 
247 #define DRAW_INIT() \
248 { \
249  texture=zb->current_texture;\
250  fdzdx=(float)dzdx;\
251  fndzdx=NB_INTERP * fdzdx;\
252  ndszdx=NB_INTERP * dszdx;\
253  ndtzdx=NB_INTERP * dtzdx;\
254 }
255 
256 
257 #if TGL_FEATURE_RENDER_BITS == 24
258 
259 #define PUT_PIXEL(_a) \
260 { \
261  unsigned char *ptr;\
262  zz=z >> ZB_POINT_Z_FRAC_BITS; \
263  if (ZCMP(zz,pz[_a])) { \
264  ptr = texture + (((t & 0x3FC00000) | (s & 0x003FC000)) >> 14) * 3;\
265  pp[3 * _a]= ptr[0];\
266  pp[3 * _a + 1]= ptr[1];\
267  pp[3 * _a + 2]= ptr[2];\
268  pz[_a]=zz; \
269  } \
270  z+=dzdx; \
271  s+=dsdx; \
272  t+=dtdx; \
273 }
274 
275 #else
276 
277 #define PUT_PIXEL(_a) \
278 { \
279  zz=z >> ZB_POINT_Z_FRAC_BITS; \
280  if (ZCMP(zz,pz[_a])) { \
281  pp[_a]=*(PIXEL *)((char *)texture+ \
282  (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)));\
283  pz[_a]=zz; \
284  } \
285  z+=dzdx; \
286  s+=dsdx; \
287  t+=dtdx; \
288 }
289 
290 #endif
291 
292 #define DRAW_LINE() \
293 { \
294  register unsigned short *pz; \
295  register PIXEL *pp; \
296  register unsigned int s,t,z,zz; \
297  register int n,dsdx,dtdx; \
298  float sz,tz,fz,zinv; \
299  n=(x2>>16)-x1; \
300  fz=(float)z1;\
301  zinv=1.0 / fz;\
302  pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \
303  pz=pz1+x1; \
304  z=z1; \
305  sz=sz1;\
306  tz=tz1;\
307  while (n>=(NB_INTERP-1)) { \
308  {\
309  float ss,tt;\
310  ss=(sz * zinv);\
311  tt=(tz * zinv);\
312  s=(int) ss;\
313  t=(int) tt;\
314  dsdx= (int)( (dszdx - ss*fdzdx)*zinv );\
315  dtdx= (int)( (dtzdx - tt*fdzdx)*zinv );\
316  fz+=fndzdx;\
317  zinv=1.0 / fz;\
318  }\
319  PUT_PIXEL(0); \
320  PUT_PIXEL(1); \
321  PUT_PIXEL(2); \
322  PUT_PIXEL(3); \
323  PUT_PIXEL(4); \
324  PUT_PIXEL(5); \
325  PUT_PIXEL(6); \
326  PUT_PIXEL(7); \
327  pz+=NB_INTERP; \
328  pp=(PIXEL *)((char *)pp + NB_INTERP * PSZB);\
329  n-=NB_INTERP; \
330  sz+=ndszdx;\
331  tz+=ndtzdx;\
332  } \
333  {\
334  float ss,tt;\
335  ss=(sz * zinv);\
336  tt=(tz * zinv);\
337  s=(int) ss;\
338  t=(int) tt;\
339  dsdx= (int)( (dszdx - ss*fdzdx)*zinv );\
340  dtdx= (int)( (dtzdx - tt*fdzdx)*zinv );\
341  }\
342  while (n>=0) { \
343  PUT_PIXEL(0); \
344  pz+=1; \
345  pp=(PIXEL *)((char *)pp + PSZB);\
346  n-=1; \
347  } \
348 }
349 
350 #include "ztriangle.h"
351 }
352 
353 #endif
354 
355 #if 0
356 
357 /* slow but exact version (only there for reference, incorrect for 24
358  bits) */
359 
360 void ZB_fillTriangleMappingPerspective(ZBuffer *zb,
361  ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
362 {
363  PIXEL *texture;
364 
365 #define INTERP_Z
366 #define INTERP_STZ
367 
368 #define DRAW_INIT() \
369 { \
370  texture=zb->current_texture; \
371 }
372 
373 #define PUT_PIXEL(_a) \
374 { \
375  float zinv; \
376  int s,t; \
377  zz=z >> ZB_POINT_Z_FRAC_BITS; \
378  if (ZCMP(zz,pz[_a])) { \
379  zinv= 1.0 / (float) z; \
380  s= (int) (sz * zinv); \
381  t= (int) (tz * zinv); \
382  pp[_a]=texture[((t & 0x3FC00000) | s) >> 14]; \
383  pz[_a]=zz; \
384  } \
385  z+=dzdx; \
386  sz+=dszdx; \
387  tz+=dtzdx; \
388 }
389 
390 #include "ztriangle.h"
391 }
392 
393 
394 #endif