scummvm/tinygl/ztriangle.cpp

252 lines
5.9 KiB
C++
Raw Normal View History

#include <stdlib.h>
2005-01-12 15:26:45 +00:00
#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<<n))
#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; \
} \
}
#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<<n))
#define DRAW_INIT() \
{ \
texture=zb->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); \
2005-08-10 21:11:24 +00:00
PIXEL pixel = *(PIXEL *)((char *)texture+ \
(((t & 0x3FC00000) | (s & 0x003FC000)) >> (17 - PSZSH)));\
2005-08-11 13:34:53 +00:00
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; \
2005-08-10 21:09:32 +00:00
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;\
2005-01-13 00:15:15 +00:00
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;\
2005-01-13 00:15:15 +00:00
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"
}