Merge branch 'master' of ssh://repo.or.cz/srv/git/tgl
[tgl.git] / src / ztriangle.c
blob83c246c32d28281b78e5011d362a10599c69f42d
1 #include <stdlib.h>
2 #include "zbuffer.h"
4 #define ZCMP(z,zpix) ((z) >= (zpix))
6 void ZB_fillTriangleFlat(ZBuffer *zb,
7 ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
9 #if TGL_FEATURE_RENDER_BITS == 24
10 unsigned char colorR, colorG, colorB;
11 #else
12 int color;
13 #endif
15 #define INTERP_Z
17 #if TGL_FEATURE_RENDER_BITS == 24
19 #define DRAW_INIT() \
20 { \
21 colorR=p2->r>>8; \
22 colorG=p2->g>>8; \
23 colorB=p2->b>>8; \
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; \
35 z+=dzdx; \
38 #else
40 #define DRAW_INIT() \
41 { \
42 color=RGB_TO_PIXEL(p2->r,p2->g,p2->b); \
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; \
54 #endif /* TGL_FEATURE_RENDER_BITS == 24 */
56 #include "ztriangle.h"
60 * Smooth filled triangle.
61 * The code below is very tricky :)
64 void ZB_fillTriangleSmooth(ZBuffer *zb,
65 ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
67 #if TGL_FEATURE_RENDER_BITS == 16
68 int _drgbdx;
69 #endif
71 #define INTERP_Z
72 #define INTERP_RGB
74 #define SAR_RND_TO_ZERO(v,n) (v / (1<<n))
76 #if TGL_FEATURE_RENDER_BITS == 24
78 #define DRAW_INIT() \
79 { \
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; \
91 z+=dzdx; \
92 og1+=dgdx; \
93 or1+=drdx; \
94 ob1+=dbdx; \
97 #elif TGL_FEATURE_RENDER_BITS == 16
99 #define DRAW_INIT() \
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; \
107 #define PUT_PIXEL(_a) \
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; \
115 z+=dzdx; \
116 rgb=(rgb+drgbdx) & ( ~ 0x00200800); \
119 #define DRAW_LINE() \
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; \
142 while (n>=0) { \
143 PUT_PIXEL(0); \
144 pz+=1; \
145 pp+=1; \
146 n-=1; \
150 #else
152 #define DRAW_INIT() \
156 #define PUT_PIXEL(_a) \
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; \
163 z+=dzdx; \
164 og1+=dgdx; \
165 or1+=drdx; \
166 ob1+=dbdx; \
169 #endif /* TGL_FEATURE_RENDER_BITS */
171 #include "ztriangle.h"
174 void ZB_setTexture(ZBuffer *zb,PIXEL *texture)
176 zb->current_texture=texture;
179 void ZB_fillTriangleMapping(ZBuffer *zb,
180 ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
182 PIXEL *texture;
184 #define INTERP_Z
185 #define INTERP_ST
187 #define DRAW_INIT() \
189 texture=zb->current_texture; \
192 #if TGL_FEATURE_RENDER_BITS == 24
194 #define PUT_PIXEL(_a) \
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; \
205 z+=dzdx; \
206 s+=dsdx; \
207 t+=dtdx; \
210 #else
212 #define PUT_PIXEL(_a) \
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; \
219 z+=dzdx; \
220 s+=dsdx; \
221 t+=dtdx; \
224 #endif
226 #include "ztriangle.h"
230 * Texture mapping with perspective correction.
231 * We use the gradient method to make less divisions.
232 * TODO: pipeline the division
234 #if 1
236 void ZB_fillTriangleMappingPerspective(ZBuffer *zb,
237 ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
239 PIXEL *texture;
240 float fdzdx,fndzdx,ndszdx,ndtzdx;
242 #define INTERP_Z
243 #define INTERP_STZ
245 #define NB_INTERP 8
247 #define DRAW_INIT() \
249 texture=zb->current_texture;\
250 fdzdx=(float)dzdx;\
251 fndzdx=NB_INTERP * fdzdx;\
252 ndszdx=NB_INTERP * dszdx;\
253 ndtzdx=NB_INTERP * dtzdx;\
257 #if TGL_FEATURE_RENDER_BITS == 24
259 #define PUT_PIXEL(_a) \
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; \
270 z+=dzdx; \
271 s+=dsdx; \
272 t+=dtdx; \
275 #else
277 #define PUT_PIXEL(_a) \
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; \
285 z+=dzdx; \
286 s+=dsdx; \
287 t+=dtdx; \
290 #endif
292 #define DRAW_LINE() \
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)) { \
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;\
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;\
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 );\
342 while (n>=0) { \
343 PUT_PIXEL(0); \
344 pz+=1; \
345 pp=(PIXEL *)((char *)pp + PSZB);\
346 n-=1; \
350 #include "ztriangle.h"
353 #endif
355 #if 0
357 /* slow but exact version (only there for reference, incorrect for 24
358 bits) */
360 void ZB_fillTriangleMappingPerspective(ZBuffer *zb,
361 ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2)
363 PIXEL *texture;
365 #define INTERP_Z
366 #define INTERP_STZ
368 #define DRAW_INIT() \
370 texture=zb->current_texture; \
373 #define PUT_PIXEL(_a) \
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; \
385 z+=dzdx; \
386 sz+=dszdx; \
387 tz+=dtzdx; \
390 #include "ztriangle.h"
394 #endif