forked from KolibriOS/kolibrios
cd74d1af33
git-svn-id: svn://kolibrios.org@5098 a494cfbc-eb01-0410-851d-a64ba20cac60
395 lines
7.8 KiB
C
395 lines
7.8 KiB
C
#include <stdlib.h>
|
|
#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<<n))
|
|
|
|
#if TGL_FEATURE_RENDER_BITS == 24
|
|
|
|
#define DRAW_INIT() \
|
|
{ \
|
|
}
|
|
|
|
#define PUT_PIXEL(_a) \
|
|
{ \
|
|
zz=z >> 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
|