#include #include "tinygl/zbuffer.h" #define ZCMP(z,zpix) ((z) >= (zpix)) void ZB_fillTriangleFlat(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { int color; #define INTERP_Z #define DRAW_INIT() \ { \ color=RGB_TO_PIXEL(p2->r,p2->g,p2->b); \ } #define PUT_PIXEL(_a) \ { \ zz=z >> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ pp[_a]=color; \ pz[_a]=zz; \ } \ z+=dzdx; \ } #include "ztriangle.h" } /* * Smooth filled triangle. * The code below is very tricky :) */ void ZB_fillTriangleSmooth(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { int _drgbdx; #define INTERP_Z #define INTERP_RGB #define SAR_RND_TO_ZERO(v,n) (v / (1<> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ tmp=rgb & 0xF81F07E0; \ pp[_a]=tmp | (tmp >> 16); \ pz[_a]=zz; \ } \ z+=dzdx; \ rgb=(rgb+drgbdx) & ( ~ 0x00200800); \ } #define DRAW_LINE() \ { \ register unsigned short *pz; \ register PIXEL *pp; \ register unsigned int tmp,z,zz,rgb,drgbdx; \ register int n; \ n=(x2 >> 16) - x1; \ pp=pp1+x1; \ pz=pz1+x1; \ z=z1; \ rgb=(r1 << 16) & 0xFFC00000; \ rgb|=(g1 >> 5) & 0x000007FF; \ rgb|=(b1 << 5) & 0x001FF000; \ drgbdx=_drgbdx; \ while (n>=3) { \ PUT_PIXEL(0); \ PUT_PIXEL(1); \ PUT_PIXEL(2); \ PUT_PIXEL(3); \ pz+=4; \ pp+=4; \ n-=4; \ } \ while (n>=0) { \ PUT_PIXEL(0); \ pz+=1; \ pp+=1; \ n-=1; \ } \ } #include "ztriangle.h" } void ZB_setTexture(ZBuffer *zb,PIXEL *texture) { zb->current_texture=texture; } void ZB_fillTriangleMapping(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { PIXEL *texture; #define INTERP_Z #define INTERP_ST #define DRAW_INIT() \ { \ texture=zb->current_texture; \ } #define PUT_PIXEL(_a) \ { \ zz=z >> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ pp[_a]=texture[((t & 0x3FC00000) | s) >> 14]; \ pz[_a]=zz; \ } \ z+=dzdx; \ s+=dsdx; \ t+=dtdx; \ } #include "ztriangle.h" } void ZB_fillTriangleMappingPerspective(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { PIXEL *texture; float fdzdx,fndzdx,ndszdx,ndtzdx; int _drgbdx; #define INTERP_Z #define INTERP_RGB #define INTERP_STZ #define NB_INTERP 8 #define SAR_RND_TO_ZERO(v,n) (v / (1<current_texture;\ fdzdx=(float)dzdx;\ fndzdx=NB_INTERP * fdzdx;\ ndszdx=NB_INTERP * dszdx;\ ndtzdx=NB_INTERP * dtzdx;\ _drgbdx=(SAR_RND_TO_ZERO(drdx,6) << 22) & 0xFFC00000; \ _drgbdx|=SAR_RND_TO_ZERO(dgdx,5) & 0x000007FF; \ _drgbdx|=(SAR_RND_TO_ZERO(dbdx,7) << 12) & 0x001FF000; \ } #define PUT_PIXEL(_a) \ { \ zz=z >> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ tmp=rgb & 0xF81F07E0; \ unsigned int light = tmp | (tmp >> 16); \ PIXEL pixel = *(PIXEL *)((char *)texture+ \ (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)));\ unsigned int c_r = (pixel & 0xF800) >> 8; \ unsigned int c_g = (pixel & 0x07E0) >> 3; \ unsigned int c_b = (pixel & 0x001F) << 3; \ unsigned int l_r = (light & 0xF800) >> 8; \ unsigned int l_g = (light & 0x07E0) >> 3; \ unsigned int l_b = (light & 0x001F) << 3; \ c_r = (c_r * l_r) / 256; \ c_g = (c_g * l_g) / 256; \ c_b = (c_b * l_b) / 256; \ pixel = ((c_r & 0xF8) << 8) | ((c_g & 0xFC) << 3) | (c_b >> 3); \ pp[_a]=pixel; \ pz[_a]=zz; \ } \ z+=dzdx; \ s+=dsdx; \ t+=dtdx; \ rgb=(rgb+drgbdx) & ( ~ 0x00200800); \ } #define DRAW_LINE() \ { \ register unsigned short *pz; \ register PIXEL *pp; \ register unsigned int s,t,z,zz,rgb,drgbdx; \ register int n,dsdx,dtdx; \ float sz,tz,fz,zinv; \ n=(x2>>16)-x1; \ fz=(float)z1;\ zinv=(float)(1.0 / fz);\ pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \ pz=pz1+x1; \ z=z1; \ sz=sz1;\ tz=tz1;\ rgb=(r1 << 16) & 0xFFC00000; \ rgb|=(g1 >> 5) & 0x000007FF; \ rgb|=(b1 << 5) & 0x001FF000; \ drgbdx=_drgbdx; \ while (n>=(NB_INTERP-1)) { \ {\ float ss,tt;\ ss=(sz * zinv);\ tt=(tz * zinv);\ s=(int) ss;\ t=(int) tt;\ dsdx= (int)( (dszdx - ss*fdzdx)*zinv );\ dtdx= (int)( (dtzdx - tt*fdzdx)*zinv );\ fz+=fndzdx;\ zinv=(float)(1.0 / fz);\ }\ PUT_PIXEL(0); \ PUT_PIXEL(1); \ PUT_PIXEL(2); \ PUT_PIXEL(3); \ PUT_PIXEL(4); \ PUT_PIXEL(5); \ PUT_PIXEL(6); \ PUT_PIXEL(7); \ pz+=NB_INTERP; \ pp=(PIXEL *)((char *)pp + NB_INTERP * PSZB);\ n-=NB_INTERP; \ sz+=ndszdx;\ tz+=ndtzdx;\ } \ {\ float ss,tt;\ ss=(sz * zinv);\ tt=(tz * zinv);\ s=(int) ss;\ t=(int) tt;\ dsdx= (int)( (dszdx - ss*fdzdx)*zinv );\ dtdx= (int)( (dtzdx - tt*fdzdx)*zinv );\ }\ while (n>=0) { \ PUT_PIXEL(0); \ pz+=1; \ pp=(PIXEL *)((char *)pp + PSZB);\ n-=1; \ } \ } #include "ztriangle.h" }