add oversampler
This commit is contained in:
713
oversampling/WDL/plush2/pl_putface.cpp
Normal file
713
oversampling/WDL/plush2/pl_putface.cpp
Normal file
@@ -0,0 +1,713 @@
|
||||
#include "plush.h"
|
||||
#include "../lice/lice_combine.h"
|
||||
|
||||
//#define PLUSH_NO_SOLIDFLAT // make non-texturemapped flat shading optimized engine
|
||||
//#define PLUSH_NO_SOLIDGOURAUD // disable non-texturemapped gouraud optimized engine
|
||||
//#define PLUSH_NO_TEXTURE // disable single-texture optimized engine
|
||||
//#define PLUSH_NO_MULTITEXTURE // disable multitexture (this can do any of em)
|
||||
#define XPOS_BITS 19 // allows 2^13 max screen width, or 8192px
|
||||
|
||||
#define SWAP(a,b,t) { t ____tmp=(a); (a)=(b); (b)=____tmp; }
|
||||
|
||||
#define PUTFACE_SORT() \
|
||||
int i0 = 0; int i1 = 1; int i2 = 2; int stat; \
|
||||
if (TriFace->Scry[0] > TriFace->Scry[1]) { i0 = 1; i1 = 0; } \
|
||||
if (TriFace->Scry[i0] > TriFace->Scry[2]) { SWAP(i0,i2,int); } \
|
||||
if (TriFace->Scry[i1] > TriFace->Scry[i2]) { SWAP(i1,i2,int); } \
|
||||
int Scrx[3] = {(int)(TriFace->Scrx[0]*(1<<XPOS_BITS)), (int)(TriFace->Scrx[1]*(1<<XPOS_BITS)),(int)(TriFace->Scrx[2]*(1<<XPOS_BITS))}; \
|
||||
int Scry[3] = {(int) (TriFace->Scry[0]+0.5), (int) (TriFace->Scry[1]+0.5), (int) (TriFace->Scry[2]+0.5)}; \
|
||||
|
||||
#define DO_STAT_XDELTAS \
|
||||
if (stat & 1) { \
|
||||
dX1 = (Scrx[i2]-(X1 = Scrx[i1]))/dY; \
|
||||
if (stat & 8) dX2 = (Scrx[i2]-(X2 = Scrx[i0]))/dY; \
|
||||
} \
|
||||
else if (stat & 2) { \
|
||||
dX2 = (Scrx[i2]-(X2 = Scrx[i1]))/dY; \
|
||||
if (stat & 4) dX1 = (Scrx[i2]-(X1 = Scrx[i0]))/dY; \
|
||||
}
|
||||
|
||||
|
||||
static inline void OverlayBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int usea)
|
||||
{
|
||||
int da=(256-usea)*128;
|
||||
int srcr = r*usea+da, srcg = g*usea+da, srcb = b*usea+da, srca = usea*a + da;
|
||||
red = ( red*( (red*(32768-srcr))/256 + srcr ) )/32768;
|
||||
green = ( green*( (green*(32768-srcg))/256 + srcg ) )/32768;
|
||||
blue = ( blue*( (blue*(32768-srcb))/256 + srcb ) )/32768;
|
||||
alpha = ( alpha*( (alpha*(32768-srca))/256 + srca ) )/32768;
|
||||
}
|
||||
|
||||
static inline void MulBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int ta)
|
||||
{
|
||||
int ta2=(256-ta)*256;
|
||||
red = (r*ta*red + red*ta2)/65536;
|
||||
green = (g*ta*green + green*ta2)/65536;
|
||||
blue = (b*ta*blue + blue*ta2)/65536;
|
||||
alpha = (a*ta*alpha + alpha*ta2)/65536;
|
||||
}
|
||||
|
||||
|
||||
static inline void AdjustHSV(int &red, int &green, int &blue, int r, int g, int b, int texalpha)
|
||||
{
|
||||
int h,s,v;
|
||||
__LICE_RGB2HSV(red,green,blue,&h,&s,&v);
|
||||
h+=(((r+r/2) - 192) * texalpha)/256;
|
||||
if (h<0)h+=384;
|
||||
else if (h>=384) h-=384;
|
||||
s+=((g-128)*texalpha)/256;
|
||||
if (s&~0xff)
|
||||
{
|
||||
if (s<0)s=0;
|
||||
else s=255;
|
||||
}
|
||||
v+=((b-128)*texalpha)/256;
|
||||
if (v&~0xff)
|
||||
{
|
||||
if (v<0)v=0;
|
||||
else v=255;
|
||||
}
|
||||
__LICE_HSV2RGB(h,s,v,&red,&green,&blue);
|
||||
}
|
||||
|
||||
static inline void DodgeBlend(int &red, int &green, int &blue, int &alpha, int r, int g, int b, int a, int ta)
|
||||
{
|
||||
int src_r = 256-r*ta/256;
|
||||
int src_g = 256-g*ta/256;
|
||||
int src_b = 256-b*ta/256;
|
||||
int src_a = 256-(a*ta)/256;
|
||||
|
||||
red = src_r > 1 ? 256*red / src_r : 256*red;
|
||||
green = src_g > 1 ? 256*green / src_g : 256*green;
|
||||
blue = src_b > 1 ? 256*blue / src_b : 256*blue;
|
||||
alpha = src_a > 1 ? 256*alpha / src_a : 256*alpha;
|
||||
}
|
||||
|
||||
|
||||
static void inline DoTextureCombine(int texcomb, int r, int g, int b, int a, int &red, int &green, int &blue, int &alpha, int texalpha, int texalpha2)
|
||||
{
|
||||
switch (texcomb)
|
||||
{
|
||||
case LICE_BLIT_MODE_COPY:
|
||||
red = (r*texalpha + red*texalpha2) >> 8;
|
||||
green = (g*texalpha + green*texalpha2) >> 8;
|
||||
blue = (b*texalpha + blue*texalpha2) >> 8;
|
||||
alpha = (a*texalpha + alpha*texalpha2) >> 8;
|
||||
break;
|
||||
case LICE_BLIT_MODE_ADD:
|
||||
red += (r*texalpha) >> 8;
|
||||
green += (g*texalpha) >> 8;
|
||||
blue += (b*texalpha) >> 8;
|
||||
alpha += (a*texalpha) >> 8;
|
||||
break;
|
||||
case LICE_BLIT_MODE_MUL:
|
||||
MulBlend(red,green,blue,alpha,r,g,b,a,texalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_DODGE:
|
||||
DodgeBlend(red,green,blue,alpha,r,g,b,a,texalpha);
|
||||
|
||||
break;
|
||||
case LICE_BLIT_MODE_OVERLAY:
|
||||
OverlayBlend(red,green,blue,alpha,r,g,b,a, texalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_HSVADJ:
|
||||
AdjustHSV(red,green,blue,r,g,b,texalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_COPY|LICE_BLIT_USE_ALPHA:
|
||||
{
|
||||
int ta=(texalpha*(a+1));
|
||||
int ta2=(65536-ta);
|
||||
red = (r*ta + red*ta2) >> 16;
|
||||
green = (g*ta + green*ta2) >> 16;
|
||||
blue = (b*ta + blue*ta2) >> 16;
|
||||
alpha = (a*ta + alpha*ta2) >> 16;
|
||||
}
|
||||
break;
|
||||
case LICE_BLIT_MODE_ADD|LICE_BLIT_USE_ALPHA:
|
||||
{
|
||||
int ta=(texalpha*(a+1));
|
||||
red += (r*ta) >> 16;
|
||||
green += (g*ta) >> 16;
|
||||
blue += (b*ta) >> 16;
|
||||
alpha += (a*ta) >> 16;
|
||||
}
|
||||
break;
|
||||
case LICE_BLIT_MODE_DODGE|LICE_BLIT_USE_ALPHA:
|
||||
{
|
||||
int ta=(texalpha*(a+1))/256;
|
||||
DodgeBlend(red,green,blue,alpha,r,g,b,a,ta);
|
||||
}
|
||||
break;
|
||||
case LICE_BLIT_MODE_MUL|LICE_BLIT_USE_ALPHA:
|
||||
MulBlend(red,green,blue,alpha,r,g,b,a,(texalpha*(a+1))/256);
|
||||
break;
|
||||
case LICE_BLIT_MODE_OVERLAY|LICE_BLIT_USE_ALPHA:
|
||||
OverlayBlend(red,green,blue,alpha,r,g,b,a, (texalpha*(a+1))/256);
|
||||
break;
|
||||
case LICE_BLIT_MODE_HSVADJ|LICE_BLIT_USE_ALPHA:
|
||||
AdjustHSV(red,green,blue,r,g,b,(texalpha*(a+1))/256);
|
||||
break;
|
||||
case -2:
|
||||
break;
|
||||
default:
|
||||
red=r; green=g; blue=b; alpha=a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void inline TextureMakePixelSolidCombine(int &red, int &green, int &blue, int &alpha,
|
||||
pl_sInt32 *CL, int solidcomb, int solidalpha,
|
||||
int solidalpha2,
|
||||
LICE_pixel_chan *gmemptr)
|
||||
{
|
||||
|
||||
switch (solidcomb)
|
||||
{
|
||||
case LICE_BLIT_MODE_COPY:
|
||||
red = ((CL[0]>>8)*solidalpha + gmemptr[LICE_PIXEL_R]*solidalpha2)>>16;
|
||||
green = ((CL[1]>>8)*solidalpha + gmemptr[LICE_PIXEL_G]*solidalpha2)>>16;
|
||||
blue = ((CL[2]>>8)*solidalpha + gmemptr[LICE_PIXEL_B]*solidalpha2)>>16;
|
||||
alpha = solidalpha;
|
||||
break;
|
||||
case LICE_BLIT_MODE_ADD:
|
||||
red = gmemptr[LICE_PIXEL_R] + (((CL[0]>>8)*solidalpha)>>16);
|
||||
green = gmemptr[LICE_PIXEL_G] + (((CL[1]>>8)*solidalpha)>>16);
|
||||
blue = gmemptr[LICE_PIXEL_B] + (((CL[2]>>8)*solidalpha)>>16);
|
||||
alpha = gmemptr[LICE_PIXEL_A] + solidalpha;
|
||||
break;
|
||||
case LICE_BLIT_MODE_DODGE:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
DodgeBlend(red,green,blue,alpha,CL[0]>>16,CL[1]>>16,CL[2]>>16,solidalpha,solidalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_MUL:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
MulBlend(red,green,blue,alpha,CL[0]>>16,CL[1]>>16,CL[2]>>16,solidalpha,solidalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_OVERLAY:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
OverlayBlend(red,green,blue,alpha,CL[0]>>16,CL[1]>>16,CL[2]>>16,solidalpha, solidalpha);
|
||||
break;
|
||||
case LICE_BLIT_MODE_HSVADJ:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
AdjustHSV(red,green,blue,CL[0]>>16,CL[1]>>16,CL[2]>>16,solidalpha);
|
||||
break;
|
||||
case -2:
|
||||
red=gmemptr[LICE_PIXEL_R];
|
||||
green=gmemptr[LICE_PIXEL_G];
|
||||
blue=gmemptr[LICE_PIXEL_B];
|
||||
alpha=gmemptr[LICE_PIXEL_A];
|
||||
break;
|
||||
default:
|
||||
red=CL[0]>>16;
|
||||
green=CL[1]>>16;
|
||||
blue=CL[2]>>16;
|
||||
alpha=solidalpha;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void inline TextureMakePixel2(LICE_pixel_chan *gmemptr,
|
||||
int solidcomb, int solidalpha, int solidalpha2,
|
||||
pl_sInt32 *CL,
|
||||
bool bilinear,
|
||||
pl_sInt32 iUL, pl_sInt32 iVL,
|
||||
pl_sInt32 texwidth, pl_sInt32 texheight,
|
||||
LICE_pixel *texture, int tex_rowspan,
|
||||
int texcomb,
|
||||
int texalpha,
|
||||
int texalpha2,
|
||||
bool bilinear2,
|
||||
pl_sInt32 iUL_2, pl_sInt32 iVL_2,
|
||||
pl_sInt32 texwidth_2, pl_sInt32 texheight_2,
|
||||
LICE_pixel *texture2, int tex_rowspan_2,
|
||||
int tex2comb,
|
||||
int tex2alpha,
|
||||
int tex2alpha2)
|
||||
{
|
||||
|
||||
int red,green,blue,alpha;
|
||||
|
||||
TextureMakePixelSolidCombine(red,green,blue,alpha,CL,solidcomb,solidalpha,solidalpha2,gmemptr);
|
||||
|
||||
int r,g,b,a;
|
||||
|
||||
#if defined(PLUSH_NO_TEXTURE)
|
||||
if (texture)
|
||||
#endif
|
||||
{
|
||||
const int xpos=(iUL>>14)&~3;
|
||||
const int ypos=iVL>>16;
|
||||
const LICE_pixel_chan *rd = ((LICE_pixel_chan*)texture) + xpos+ypos*tex_rowspan;
|
||||
|
||||
if (bilinear)
|
||||
{
|
||||
__LICE_BilinearFilterI_2(&r,&g,&b,&a,rd,
|
||||
ypos < texheight - 1 ? rd+tex_rowspan : ((LICE_pixel_chan *)texture)+xpos,
|
||||
xpos < texwidth - 4 ? 4 : 4-texwidth,
|
||||
iUL&65535,iVL&65535);
|
||||
}
|
||||
else
|
||||
{
|
||||
r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A];
|
||||
}
|
||||
|
||||
DoTextureCombine(texcomb, r,g,b,a, red,green,blue,alpha,texalpha,texalpha2);
|
||||
}
|
||||
|
||||
#ifdef PLUSH_NO_TEXTURE
|
||||
if (texture2)
|
||||
#endif
|
||||
{
|
||||
const int xpos=(iUL_2>>14)&~3;
|
||||
const int ypos=iVL_2>>16;
|
||||
const LICE_pixel_chan *rd = ((LICE_pixel_chan*)texture2) + xpos+ypos*tex_rowspan_2;
|
||||
|
||||
if (bilinear2)
|
||||
{
|
||||
__LICE_BilinearFilterI_2(&r,&g,&b,&a,rd,
|
||||
ypos < texheight_2 - 1 ? rd+tex_rowspan_2 : ((LICE_pixel_chan *)texture2)+xpos,
|
||||
xpos < texwidth_2 - 4 ? 4 : 4-texwidth_2,
|
||||
iUL_2&65535,iVL_2&65535);
|
||||
}
|
||||
else
|
||||
{
|
||||
r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A];
|
||||
}
|
||||
|
||||
DoTextureCombine(tex2comb, r,g,b,a, red,green,blue,alpha,tex2alpha,tex2alpha2);
|
||||
}
|
||||
|
||||
_LICE_MakePixelClamp(gmemptr, red,green,blue,alpha);
|
||||
}
|
||||
|
||||
static void inline TextureMakePixel(LICE_pixel_chan *gmemptr,
|
||||
int solidcomb, int solidalpha, int solidalpha2,
|
||||
pl_sInt32 *CL,
|
||||
bool bilinear,
|
||||
pl_sInt32 iUL, pl_sInt32 iVL,
|
||||
pl_sInt32 texwidth, pl_sInt32 texheight,
|
||||
LICE_pixel *texture, int tex_rowspan,
|
||||
int texcomb,
|
||||
int texalpha,
|
||||
int texalpha2)
|
||||
{
|
||||
|
||||
int red,green,blue,alpha;
|
||||
|
||||
if (
|
||||
#ifdef PLUSH_NO_SOLIDGOURAUD
|
||||
!texture||
|
||||
#endif
|
||||
texcomb!=-1)
|
||||
TextureMakePixelSolidCombine(red,green,blue,alpha,CL,solidcomb,solidalpha,solidalpha2,gmemptr);
|
||||
|
||||
|
||||
|
||||
#ifdef PLUSH_NO_SOLIDGOURAUD
|
||||
if (texture)
|
||||
#endif
|
||||
{
|
||||
int r,g,b,a;
|
||||
const int xpos=(iUL>>14)&~3;
|
||||
const int ypos=iVL>>16;
|
||||
const LICE_pixel_chan *rd = ((LICE_pixel_chan*)texture) + xpos+ypos*tex_rowspan;
|
||||
|
||||
if (bilinear)
|
||||
{
|
||||
|
||||
__LICE_BilinearFilterI_2(&r,&g,&b,&a,rd,
|
||||
ypos < texheight - 1 ? rd+tex_rowspan : ((LICE_pixel_chan *)texture)+xpos,
|
||||
xpos < texwidth - 4 ? 4 : 4-texwidth,
|
||||
iUL&65535,iVL&65535);
|
||||
}
|
||||
else
|
||||
{
|
||||
r=rd[LICE_PIXEL_R]; g=rd[LICE_PIXEL_G]; b=rd[LICE_PIXEL_B]; a=rd[LICE_PIXEL_A];
|
||||
}
|
||||
|
||||
DoTextureCombine(texcomb, r,g,b,a, red,green,blue,alpha,texalpha,texalpha2);
|
||||
}
|
||||
|
||||
_LICE_MakePixelClamp(gmemptr, red,green,blue,alpha);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef PLUSH_NO_TEXTURE
|
||||
#include "pl_pf_tex.h"
|
||||
#endif
|
||||
|
||||
#ifndef PLUSH_NO_MULTITEXTURE
|
||||
#define PL_PF_MULTITEX
|
||||
#include "pl_pf_tex.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
template<class Comb> class PLSolidPutFace
|
||||
{
|
||||
public:
|
||||
#ifndef PLUSH_NO_SOLIDGOURAUD
|
||||
static void SolidGouraud(LICE_pixel *gmem, int swidth, pl_Face *TriFace, int alpha, pl_ZBuffer *zbuf, int zfb_width, bool zb_update)
|
||||
{
|
||||
pl_Float dZL=0, dZ1=0, dZ2=0;
|
||||
pl_sInt32 dX1=0, dX2=0, C1[3], C2[3], dC1[3]={0}, dC2[3]={0}, dCL[3]={0}, C3[3];
|
||||
|
||||
PUTFACE_SORT();
|
||||
|
||||
|
||||
int a;
|
||||
for(a=0;a<3;a++)
|
||||
{
|
||||
C1[a] = (pl_sInt32) (TriFace->Shades[i0][a]*(1<<24));
|
||||
C2[a] = (pl_sInt32) (TriFace->Shades[i1][a]*(1<<24));
|
||||
C3[a] = (pl_sInt32) (TriFace->Shades[i2][a]*(1<<24));
|
||||
}
|
||||
pl_sInt32 X2,X1;
|
||||
X2 = X1 = Scrx[i0];
|
||||
pl_Float Z1 = TriFace->Scrz[i0];
|
||||
pl_Float Z2 = TriFace->Scrz[i1];
|
||||
pl_Float Z3 = TriFace->Scrz[i2];
|
||||
|
||||
pl_sInt32 Y0 = Scry[i0];
|
||||
pl_sInt32 Y1 = Scry[i1];
|
||||
pl_sInt32 Y2 = Scry[i2];
|
||||
|
||||
{
|
||||
pl_sInt32 dY = Y2 - Y0;
|
||||
if (dY) {
|
||||
dX2 = (Scrx[i2] - X1) / dY;
|
||||
for(a=0;a<3;a++) dC2[a] = (C3[a] - C1[a]) / dY;
|
||||
dZ2 = (Z3 - Z1) / dY;
|
||||
}
|
||||
dY = Y1 - Y0;
|
||||
if (dY) {
|
||||
dX1 = (Scrx[i1] - X1) / dY;
|
||||
for(a=0;a<3;a++)
|
||||
dC1[a] = (C2[a] - C1[a]) / dY;
|
||||
dZ1 = (Z2 - Z1) / dY;
|
||||
if (dX2 < dX1) {
|
||||
SWAP(dX2,dX1,pl_sInt32);
|
||||
for(a=0;a<3;a++) SWAP(dC1[a],dC2[a],pl_sInt32);
|
||||
SWAP(dZ1,dZ2,pl_Float);
|
||||
stat = 2;
|
||||
} else stat = 1;
|
||||
Z2 = Z1;
|
||||
C2[0] = C1[0];
|
||||
C2[1] = C1[1];
|
||||
C2[2] = C1[2];
|
||||
} else {
|
||||
if (Scrx[i1] > X1) {
|
||||
X2 = Scrx[i1];
|
||||
stat = 2|4;
|
||||
} else {
|
||||
for(a=0;a<3;a++) SWAP(C1[a],C2[a],pl_sInt32);
|
||||
SWAP(Z1,Z2,pl_Float);
|
||||
X1 = Scrx[i1];
|
||||
stat = 1|8;
|
||||
}
|
||||
}
|
||||
|
||||
pl_sInt32 tmp = (dX1-dX2)*dY;
|
||||
if (tmp) {
|
||||
double v=(1<<XPOS_BITS)/(double)tmp;
|
||||
for(a=0;a<3;a++)
|
||||
dCL[a] = (pl_sInt32) (((dC1[a]-dC2[a])*dY)*v);
|
||||
dZL = ((dZ1-dZ2)*dY)*v;
|
||||
} else {
|
||||
tmp = X2-X1;
|
||||
if (tmp) {
|
||||
double v=(1<<XPOS_BITS)/(double)tmp;
|
||||
for(a=0;a<3;a++)
|
||||
dCL[a] = (pl_sInt32) ((C2[a]-C1[a])*v);
|
||||
dZL = (Z2-Z1)*v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gmem += (Y0 * swidth);
|
||||
zbuf += (Y0 * zfb_width);
|
||||
|
||||
while (Y0 < Y2) {
|
||||
if (Y0 == Y1) {
|
||||
pl_sInt32 dY = Y2 - Scry[i1];
|
||||
if (dY) {
|
||||
double v=1.0/dY;
|
||||
dZ1 = (Z3-Z1)*v;
|
||||
dC1[0] = (pl_sInt32) ((C3[0]-C1[0])*v);
|
||||
dC1[1] = (pl_sInt32) ((C3[1]-C1[1])*v);
|
||||
dC1[2] = (pl_sInt32) ((C3[2]-C1[2])*v);
|
||||
|
||||
DO_STAT_XDELTAS
|
||||
|
||||
}
|
||||
}
|
||||
pl_sInt32 XL1 = (X1+(1<<(XPOS_BITS-1)))>>XPOS_BITS;
|
||||
pl_sInt32 XL2 = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1;
|
||||
if (XL2 > 0) {
|
||||
gmem += XL1;
|
||||
XL1 += XL2;
|
||||
pl_sInt32 CL[3] = {C1[0],C1[1],C1[2]};
|
||||
if (zbuf)
|
||||
{
|
||||
pl_Float ZL = Z1;
|
||||
zbuf += XL1-XL2;
|
||||
do {
|
||||
if (*zbuf < ZL) {
|
||||
if (zb_update) *zbuf = (pl_ZBuffer) ZL;
|
||||
|
||||
Comb::doPix((LICE_pixel_chan *)gmem,CL[0]>>16,CL[1]>>16,CL[2]>>16,255,alpha);
|
||||
}
|
||||
gmem++;
|
||||
zbuf++;
|
||||
ZL += dZL;
|
||||
CL[0] += dCL[0];
|
||||
CL[1] += dCL[1];
|
||||
CL[2] += dCL[2];
|
||||
} while (--XL2);
|
||||
zbuf -= XL1;
|
||||
}
|
||||
else do {
|
||||
Comb::doPix((LICE_pixel_chan *)gmem,CL[0]>>16,CL[1]>>16,CL[2]>>16,255,alpha);
|
||||
gmem++;
|
||||
CL[0] += dCL[0];
|
||||
CL[1] += dCL[1];
|
||||
CL[2] += dCL[2];
|
||||
} while (--XL2);
|
||||
gmem -= XL1;
|
||||
}
|
||||
gmem += swidth;
|
||||
zbuf += zfb_width;
|
||||
X1 += dX1;
|
||||
X2 += dX2;
|
||||
C1[0] += dC1[0];
|
||||
C1[1] += dC1[1];
|
||||
C1[2] += dC1[2];
|
||||
Z1 += dZ1;
|
||||
Y0++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PLUSH_NO_SOLIDFLAT
|
||||
static void Solid(LICE_pixel *gmem, int swidth, pl_Face *TriFace, int alpha, pl_ZBuffer *zbuf, int zfb_width, bool zb_update)
|
||||
{
|
||||
pl_sInt32 dX1=0, dX2=0;
|
||||
pl_Float dZL=0, dZ1=0, dZ2=0;
|
||||
|
||||
PUTFACE_SORT();
|
||||
|
||||
int col0 = (int) (TriFace->Shades[0][0]*255.0);
|
||||
int col1 = (int) (TriFace->Shades[0][1]*255.0);
|
||||
int col2 = (int) (TriFace->Shades[0][2]*255.0);
|
||||
|
||||
pl_sInt32 X1,X2;
|
||||
X2 = X1 = Scrx[i0];
|
||||
pl_sInt32 Y0 = Scry[i0];
|
||||
pl_sInt32 Y1 = Scry[i1];
|
||||
pl_sInt32 Y2 = Scry[i2];
|
||||
|
||||
pl_Float Z1 = TriFace->Scrz[i0];
|
||||
pl_Float Z2 = TriFace->Scrz[i1];
|
||||
pl_Float Z3 = TriFace->Scrz[i2];
|
||||
|
||||
{
|
||||
pl_sInt32 dY = Y2-Y0;
|
||||
if (dY) {
|
||||
dX2 = (Scrx[i2] - X1) / dY;
|
||||
dZ2 = (Z3 - Z1) / dY;
|
||||
}
|
||||
dY = Y1-Y0;
|
||||
if (dY) {
|
||||
dX1 = (Scrx[i1] - X1) / dY;
|
||||
dZ1 = (Z2 - Z1) / dY;
|
||||
if (dX2 < dX1) {
|
||||
SWAP(dX1,dX2,pl_sInt32);
|
||||
SWAP(dZ1,dZ2,pl_Float);
|
||||
stat = 2;
|
||||
} else stat = 1;
|
||||
Z2 = Z1;
|
||||
} else {
|
||||
if (Scrx[i1] > X1) {
|
||||
X2 = Scrx[i1];
|
||||
stat = 2|4;
|
||||
} else {
|
||||
X1 = Scrx[i1];
|
||||
SWAP(Z1,Z2,pl_Float);
|
||||
stat = 1|8;
|
||||
}
|
||||
}
|
||||
|
||||
if (zbuf)
|
||||
{
|
||||
pl_sInt32 tmp=(dX1-dX2)*dY;
|
||||
if (tmp) dZL = ((dZ1-dZ2)*dY)*(double)(1<<XPOS_BITS)/(double)tmp;
|
||||
else {
|
||||
tmp = X2-X1;
|
||||
if (tmp) dZL = (Z2-Z1)*(double)(1<<XPOS_BITS)/tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gmem += (Y0 * swidth);
|
||||
zbuf += (Y0 * zfb_width);
|
||||
|
||||
while (Y0 < Y2) {
|
||||
if (Y0 == Y1) {
|
||||
pl_sInt32 dY = Y2 - Scry[i1];
|
||||
if (dY) {
|
||||
DO_STAT_XDELTAS
|
||||
dZ1 = (Z3-Z1)/dY;
|
||||
}
|
||||
}
|
||||
pl_sInt32 XL1 = (X1+(1<<(XPOS_BITS-1)))>>XPOS_BITS;
|
||||
pl_sInt32 XL2 = ((X2+(1<<(XPOS_BITS-1)))>>XPOS_BITS) - XL1;
|
||||
if (XL2 > 0) {
|
||||
gmem += XL1;
|
||||
XL1 += XL2;
|
||||
if (zbuf)
|
||||
{
|
||||
pl_Float ZL = Z1;
|
||||
zbuf += XL1-XL2;
|
||||
do {
|
||||
if (*zbuf < ZL) {
|
||||
if (zb_update) *zbuf = (pl_ZBuffer) ZL;
|
||||
Comb::doPix((LICE_pixel_chan *)gmem,col0,col1,col2,255,alpha);
|
||||
}
|
||||
gmem++;
|
||||
zbuf++;
|
||||
ZL += dZL;
|
||||
} while (--XL2);
|
||||
zbuf -= XL1;
|
||||
}
|
||||
else
|
||||
{
|
||||
do {
|
||||
Comb::doPix((LICE_pixel_chan *)gmem,col0,col1,col2,255,alpha);
|
||||
gmem++;
|
||||
} while (--XL2);
|
||||
}
|
||||
gmem -= XL1;
|
||||
|
||||
}
|
||||
gmem += swidth;
|
||||
zbuf += zfb_width;
|
||||
Z1 += dZ1;
|
||||
X1 += dX1;
|
||||
X2 += dX2;
|
||||
Y0++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
void pl_Cam::PutFace(pl_Face *TriFace)
|
||||
{
|
||||
LICE_pixel *gmem = m_fBuffer.m_buf;
|
||||
if (WDL_NOT_NORMALLY(!gmem)) return;
|
||||
|
||||
int zfb_width = 0;
|
||||
int zBufferable = TriFace->Material->zBufferable;
|
||||
pl_ZBuffer *zb = NULL;
|
||||
if (zBufferable &&
|
||||
zBuffer.GetSize() &&
|
||||
WDL_NORMALLY(zBuffer.GetSize() >= m_fBuffer.m_w*m_fBuffer.m_h)
|
||||
)
|
||||
{
|
||||
zfb_width = m_fBuffer.m_w;
|
||||
zb = zBuffer.Get();
|
||||
}
|
||||
|
||||
int swidth = m_fBuffer.m_span;
|
||||
if (m_fBuffer.m_flipped)
|
||||
{
|
||||
gmem += swidth*(m_fBuffer.m_h-1);
|
||||
swidth=-swidth;
|
||||
}
|
||||
|
||||
pl_Mat *mat=TriFace->Material;
|
||||
|
||||
#ifndef PLUSH_NO_MULTITEXTURE
|
||||
|
||||
#ifndef PLUSH_NO_TEXTURE
|
||||
if (mat->Texture&&mat->Texture2)
|
||||
#else
|
||||
#ifndef PLUSH_NO_SOLIDGOURAUD
|
||||
if (mat->Texture||mat->Texture2)
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
pl_Float texsc[4];
|
||||
memcpy(texsc,mat->TexScaling,sizeof(mat->TexScaling));
|
||||
memcpy(texsc+2,mat->Tex2Scaling,sizeof(mat->Tex2Scaling));
|
||||
int tidx = mat->TexMapIdx;
|
||||
if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1;
|
||||
int tidx2 = mat->Tex2MapIdx;
|
||||
if (tidx2<0 || tidx2>=PLUSH_MAX_MAPCOORDS)tidx2=PLUSH_MAX_MAPCOORDS-1;
|
||||
|
||||
PLMTexTri(gmem,swidth,TriFace,zb,zfb_width,zBufferable!=2,(int) (mat->SolidOpacity*256.0),mat->SolidCombineMode,
|
||||
mat->Texture,texsc,(int) (mat->TexOpacity*256.0),mat->TexCombineMode,tidx,
|
||||
mat->Texture2,(int) (mat->Tex2Opacity*256.0),mat->Tex2CombineMode,tidx2
|
||||
);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef PLUSH_NO_TEXTURE
|
||||
#ifndef PLUSH_NO_SOLIDGOURAUD
|
||||
if (mat->Texture||mat->Texture2)
|
||||
#endif
|
||||
{
|
||||
LICE_IBitmap *tex=mat->Texture ? mat->Texture : mat->Texture2;
|
||||
int talpha = (int) (mat->Texture ? mat->TexOpacity*256.0 : mat->Tex2Opacity*256.0);
|
||||
int tcomb = (int) (mat->Texture ? mat->TexCombineMode : mat->Tex2CombineMode);
|
||||
int tidx = (mat->Texture ? mat->TexMapIdx: mat->Tex2MapIdx);
|
||||
if (tidx<0 || tidx>=PLUSH_MAX_MAPCOORDS)tidx=PLUSH_MAX_MAPCOORDS-1;
|
||||
pl_Float texsc[2];
|
||||
memcpy(texsc,mat->Texture ? mat->TexScaling : mat->Tex2Scaling,sizeof(texsc));
|
||||
PLTexTri(gmem,swidth,TriFace,zb,zfb_width,zBufferable!=2,(int) (mat->SolidOpacity*256.0),mat->SolidCombineMode,tex,texsc,talpha,tcomb,tidx);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
int alpha=(int) (mat->SolidOpacity*256.0);
|
||||
if (!alpha) return;
|
||||
|
||||
#ifndef PLUSH_NO_SOLIDGOURAUD
|
||||
#ifndef PLUSH_NO_SOLIDFLAT
|
||||
if (mat->Smoothing)
|
||||
#endif
|
||||
{
|
||||
#define __LICE__ACTION(comb) PLSolidPutFace<comb>::SolidGouraud(gmem,swidth,TriFace,alpha,zb,zfb_width, zBufferable!=2);
|
||||
__LICE_ACTION_CONSTANTALPHA(mat->SolidCombineMode,alpha,true);
|
||||
#undef __LICE__ACTION
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef PLUSH_NO_SOLIDFLAT
|
||||
|
||||
#define __LICE__ACTION(comb) PLSolidPutFace<comb>::Solid(gmem,swidth,TriFace,alpha,zb,zfb_width, zBufferable!=2);
|
||||
__LICE_ACTION_CONSTANTALPHA(mat->SolidCombineMode,alpha,true);
|
||||
#undef __LICE__ACTION
|
||||
|
||||
#endif // PLUSH_NO_SOLIDFLAT
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user