Files
tlib/oversampling/WDL/plush2/pl_putface.cpp
2024-05-24 13:28:31 +02:00

714 lines
20 KiB
C++

#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
}