#include #include "zbuffer.h" #define ZCMP(z,zpix) ((z) >= (zpix)) void ZB_fillTriangleFlat(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { #if TGL_FEATURE_RENDER_BITS == 24 unsigned char colorR, colorG, colorB; #else int color; #endif #define INTERP_Z #if TGL_FEATURE_RENDER_BITS == 24 #define DRAW_INIT() \ { \ colorR=p2->r>>8; \ colorG=p2->g>>8; \ colorB=p2->b>>8; \ } #define PUT_PIXEL(_a) \ { \ zz=z >> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ pp[3 * _a]=colorR;\ pp[3 * _a + 1]=colorG;\ pp[3 * _a + 2]=colorB;\ pz[_a]=zz; \ }\ z+=dzdx; \ } #else #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; \ } #endif /* TGL_FEATURE_RENDER_BITS == 24 */ #include "ztriangle.h" } /* * Smooth filled triangle. * The code below is very tricky :) */ void ZB_fillTriangleSmooth(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { #if TGL_FEATURE_RENDER_BITS == 16 int _drgbdx; #endif #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])) { \ pp[3 * _a]=or1 >> 8;\ pp[3 * _a + 1]=og1 >> 8;\ pp[3 * _a + 2]=ob1 >> 8;\ pz[_a]=zz; \ }\ z+=dzdx; \ og1+=dgdx; \ or1+=drdx; \ ob1+=dbdx; \ } #elif TGL_FEATURE_RENDER_BITS == 16 #define DRAW_INIT() \ { \ _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; \ 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; \ } \ } #else #define DRAW_INIT() \ { \ } #define PUT_PIXEL(_a) \ { \ zz=z >> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ pp[_a] = RGB_TO_PIXEL(or1, og1, ob1);\ pz[_a]=zz; \ }\ z+=dzdx; \ og1+=dgdx; \ or1+=drdx; \ ob1+=dbdx; \ } #endif /* TGL_FEATURE_RENDER_BITS */ #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; \ } #if TGL_FEATURE_RENDER_BITS == 24 #define PUT_PIXEL(_a) \ { \ unsigned char *ptr;\ zz=z >> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ ptr = texture + (((t & 0x3FC00000) | s) >> 14) * 3; \ pp[3 * _a]= ptr[0];\ pp[3 * _a + 1]= ptr[1];\ pp[3 * _a + 2]= ptr[2];\ pz[_a]=zz; \ } \ z+=dzdx; \ s+=dsdx; \ t+=dtdx; \ } #else #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; \ } #endif #include "ztriangle.h" } /* * Texture mapping with perspective correction. * We use the gradient method to make less divisions. * TODO: pipeline the division */ #if 1 void ZB_fillTriangleMappingPerspective(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { PIXEL *texture; float fdzdx,fndzdx,ndszdx,ndtzdx; #define INTERP_Z #define INTERP_STZ #define NB_INTERP 8 #define DRAW_INIT() \ { \ texture=zb->current_texture;\ fdzdx=(float)dzdx;\ fndzdx=NB_INTERP * fdzdx;\ ndszdx=NB_INTERP * dszdx;\ ndtzdx=NB_INTERP * dtzdx;\ } #if TGL_FEATURE_RENDER_BITS == 24 #define PUT_PIXEL(_a) \ { \ unsigned char *ptr;\ zz=z >> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ ptr = texture + (((t & 0x3FC00000) | (s & 0x003FC000)) >> 14) * 3;\ pp[3 * _a]= ptr[0];\ pp[3 * _a + 1]= ptr[1];\ pp[3 * _a + 2]= ptr[2];\ pz[_a]=zz; \ } \ z+=dzdx; \ s+=dsdx; \ t+=dtdx; \ } #else #define PUT_PIXEL(_a) \ { \ zz=z >> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ pp[_a]=*(PIXEL *)((char *)texture+ \ (((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)));\ pz[_a]=zz; \ } \ z+=dzdx; \ s+=dsdx; \ t+=dtdx; \ } #endif #define DRAW_LINE() \ { \ register unsigned short *pz; \ register PIXEL *pp; \ register unsigned int s,t,z,zz; \ register int n,dsdx,dtdx; \ float sz,tz,fz,zinv; \ n=(x2>>16)-x1; \ fz=(float)z1;\ zinv=1.0 / fz;\ pp=(PIXEL *)((char *)pp1 + x1 * PSZB); \ pz=pz1+x1; \ z=z1; \ sz=sz1;\ tz=tz1;\ 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=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" } #endif #if 0 /* slow but exact version (only there for reference, incorrect for 24 bits) */ void ZB_fillTriangleMappingPerspective(ZBuffer *zb, ZBufferPoint *p0,ZBufferPoint *p1,ZBufferPoint *p2) { PIXEL *texture; #define INTERP_Z #define INTERP_STZ #define DRAW_INIT() \ { \ texture=zb->current_texture; \ } #define PUT_PIXEL(_a) \ { \ float zinv; \ int s,t; \ zz=z >> ZB_POINT_Z_FRAC_BITS; \ if (ZCMP(zz,pz[_a])) { \ zinv= 1.0 / (float) z; \ s= (int) (sz * zinv); \ t= (int) (tz * zinv); \ pp[_a]=texture[((t & 0x3FC00000) | s) >> 14]; \ pz[_a]=zz; \ } \ z+=dzdx; \ sz+=dszdx; \ tz+=dtzdx; \ } #include "ztriangle.h" } #endif