mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-02 08:52:12 +00:00
- implement blend functions
This commit is contained in:
parent
f73470dcf4
commit
b17351cda4
2 changed files with 84 additions and 78 deletions
|
@ -168,72 +168,3 @@ private:
|
||||||
FVector3 mNormal;
|
FVector3 mNormal;
|
||||||
uint32_t mDynLightColor = 0;
|
uint32_t mDynLightColor = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
|
||||||
class RectDrawArgs
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void SetTexture(FSoftwareTexture *texture, FRenderStyle style);
|
|
||||||
void SetTexture(FSoftwareTexture *texture, uint32_t translationID, FRenderStyle style);
|
|
||||||
void SetLight(FSWColormap *basecolormap, uint32_t lightlevel);
|
|
||||||
void SetStyle(TriBlendMode blendmode, double alpha = 1.0) { mBlendMode = blendmode; mAlpha = (uint32_t)(alpha * 256.0 + 0.5); }
|
|
||||||
void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FSoftwareTexture *texture, bool fullbright);
|
|
||||||
void SetColor(uint32_t bgra, uint8_t palindex);
|
|
||||||
void Draw(PolyRenderThread *thread, double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1);
|
|
||||||
|
|
||||||
FSoftwareTexture *Texture() const { return mTexture; }
|
|
||||||
const uint8_t *TexturePixels() const { return mTexturePixels; }
|
|
||||||
int TextureWidth() const { return mTextureWidth; }
|
|
||||||
int TextureHeight() const { return mTextureHeight; }
|
|
||||||
const uint8_t *Translation() const { return mTranslation; }
|
|
||||||
|
|
||||||
TriBlendMode BlendMode() const { return mBlendMode; }
|
|
||||||
uint32_t Color() const { return mColor; }
|
|
||||||
uint32_t Alpha() const { return mAlpha; }
|
|
||||||
|
|
||||||
uint32_t Light() const { return mLight; }
|
|
||||||
const uint8_t *BaseColormap() const { return mColormaps; }
|
|
||||||
uint16_t ShadeLightAlpha() const { return mLightAlpha; }
|
|
||||||
uint16_t ShadeLightRed() const { return mLightRed; }
|
|
||||||
uint16_t ShadeLightGreen() const { return mLightGreen; }
|
|
||||||
uint16_t ShadeLightBlue() const { return mLightBlue; }
|
|
||||||
uint16_t ShadeFadeAlpha() const { return mFadeAlpha; }
|
|
||||||
uint16_t ShadeFadeRed() const { return mFadeRed; }
|
|
||||||
uint16_t ShadeFadeGreen() const { return mFadeGreen; }
|
|
||||||
uint16_t ShadeFadeBlue() const { return mFadeBlue; }
|
|
||||||
uint16_t ShadeDesaturate() const { return mDesaturate; }
|
|
||||||
bool SimpleShade() const { return mSimpleShade; }
|
|
||||||
|
|
||||||
float X0() const { return mX0; }
|
|
||||||
float X1() const { return mX1; }
|
|
||||||
float Y0() const { return mY0; }
|
|
||||||
float Y1() const { return mY1; }
|
|
||||||
float U0() const { return mU0; }
|
|
||||||
float U1() const { return mU1; }
|
|
||||||
float V0() const { return mV0; }
|
|
||||||
float V1() const { return mV1; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
FSoftwareTexture *mTexture = nullptr;
|
|
||||||
const uint8_t *mTexturePixels = nullptr;
|
|
||||||
int mTextureWidth = 0;
|
|
||||||
int mTextureHeight = 0;
|
|
||||||
const uint8_t *mTranslation = nullptr;
|
|
||||||
const uint8_t *mColormaps = nullptr;
|
|
||||||
TriBlendMode mBlendMode = TriBlendMode::Fill;
|
|
||||||
uint32_t mLight = 0;
|
|
||||||
uint32_t mColor = 0;
|
|
||||||
uint32_t mAlpha = 0;
|
|
||||||
uint16_t mLightAlpha = 0;
|
|
||||||
uint16_t mLightRed = 0;
|
|
||||||
uint16_t mLightGreen = 0;
|
|
||||||
uint16_t mLightBlue = 0;
|
|
||||||
uint16_t mFadeAlpha = 0;
|
|
||||||
uint16_t mFadeRed = 0;
|
|
||||||
uint16_t mFadeGreen = 0;
|
|
||||||
uint16_t mFadeBlue = 0;
|
|
||||||
uint16_t mDesaturate = 0;
|
|
||||||
bool mSimpleShade = true;
|
|
||||||
float mX0, mX1, mY0, mY1, mU0, mU1, mV0, mV1;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -74,25 +74,100 @@ static void WriteVaryings(int y, int x0, int x1, const TriDrawTriangleArgs* args
|
||||||
WriteVarying(args->v1->worldZ * args->v1->w + args->gradientX.WorldZ * startX + args->gradientY.WorldZ * startY, args->gradientX.WorldZ, x0, x1, thread->scanline.W, thread->scanline.WorldZ);
|
WriteVarying(args->v1->worldZ * args->v1->w + args->gradientX.WorldZ * startX + args->gradientY.WorldZ * startY, args->gradientX.WorldZ, x0, x1, thread->scanline.W, thread->scanline.WorldZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void WriteBlend(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
static uint32_t BlendColor(FRenderStyle style, uint32_t fg, uint32_t bg)
|
||||||
|
{
|
||||||
|
static const int shiftTable[] = {
|
||||||
|
0, 0, 0, 0, // STYLEALPHA_Zero
|
||||||
|
0, 0, 0, 0, // STYLEALPHA_One
|
||||||
|
24, 24, 24, 24, // STYLEALPHA_Src
|
||||||
|
24, 24, 24, 24, // STYLEALPHA_InvSrc
|
||||||
|
24, 16, 8, 0, // STYLEALPHA_SrcCol
|
||||||
|
24, 16, 8, 0, // STYLEALPHA_InvSrcCol
|
||||||
|
24, 16, 8, 0, // STYLEALPHA_DstCol
|
||||||
|
24, 16, 8, 0 // STYLEALPHA_InvDstCol
|
||||||
|
};
|
||||||
|
|
||||||
|
bool invsrc = style.SrcAlpha & 1;
|
||||||
|
bool invdst = style.DestAlpha & 1;
|
||||||
|
|
||||||
|
int srcinput = style.SrcAlpha <= STYLEALPHA_One ? 0 : (style.SrcAlpha >= STYLEALPHA_DstCol ? bg : fg);
|
||||||
|
int dstinput = style.DestAlpha <= STYLEALPHA_One ? 0 : (style.DestAlpha >= STYLEALPHA_DstCol ? bg : fg);
|
||||||
|
|
||||||
|
const int* shiftsrc = shiftTable + (style.SrcAlpha << 2);
|
||||||
|
const int* shiftdst = shiftTable + (style.DestAlpha << 2);
|
||||||
|
|
||||||
|
int32_t src[4], dst[4];
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
// Grab component for scale factors
|
||||||
|
src[i] = (srcinput >> shiftsrc[i]) & 0xff;
|
||||||
|
dst[i] = (dstinput >> shiftdst[i]) & 0xff;
|
||||||
|
|
||||||
|
// Inverse if needed
|
||||||
|
src[i] = invsrc ? 0xff - src[i] : src[i];
|
||||||
|
dst[i] = invdst ? 0xff - dst[i] : dst[i];
|
||||||
|
|
||||||
|
// Rescale 0-255 to 0-256
|
||||||
|
src[i] = src[i] + (src[i] >> 7);
|
||||||
|
dst[i] = dst[i] + (dst[i] >> 7);
|
||||||
|
|
||||||
|
// Multiply with input
|
||||||
|
src[i] = src[i] * ((fg >> (24 - (i << 3))) & 0xff);
|
||||||
|
dst[i] = dst[i] * ((bg >> (24 - (i << 3))) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t out[4];
|
||||||
|
switch (style.BlendOp)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case STYLEOP_Add: for (int i = 0; i < 4; i++) out[i] = clamp((src[i] + dst[i] + 127) >> 8, 0, 255); break;
|
||||||
|
case STYLEOP_Sub: for (int i = 0; i < 4; i++) out[i] = clamp((src[i] - dst[i] + 127) >> 8, 0, 255); break;
|
||||||
|
case STYLEOP_RevSub: for (int i = 0; i < 4; i++) out[i] = clamp((dst[i] - src[i] + 127) >> 8, 0, 255); break;
|
||||||
|
}
|
||||||
|
return MAKEARGB(out[0], out[1], out[2], out[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WriteColor(int y, int x0, int x1, PolyTriangleThreadData* thread)
|
||||||
{
|
{
|
||||||
uint32_t* dest = (uint32_t*)thread->dest;
|
uint32_t* dest = (uint32_t*)thread->dest;
|
||||||
uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch;
|
uint32_t* line = dest + y * (ptrdiff_t)thread->dest_pitch;
|
||||||
|
FRenderStyle style = thread->RenderStyle;
|
||||||
|
uint32_t* fragcolor = thread->scanline.FragColor;
|
||||||
|
|
||||||
if (!thread->AlphaTest)
|
if (style.BlendOp == STYLEOP_Add && style.SrcAlpha == STYLEALPHA_One && style.DestAlpha == STYLEALPHA_Zero)
|
||||||
{
|
{
|
||||||
for (int x = x0; x < x1; x++)
|
if (!thread->AlphaTest)
|
||||||
{
|
{
|
||||||
line[x] = thread->scanline.FragColor[x];
|
for (int x = x0; x < x1; x++)
|
||||||
|
{
|
||||||
|
line[x] = fragcolor[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int x = x0; x < x1; x++)
|
||||||
|
{
|
||||||
|
if (fragcolor[x] > 0x7f000000)
|
||||||
|
line[x] = fragcolor[x];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint32_t* fragcolor = thread->scanline.FragColor;
|
if (!thread->AlphaTest)
|
||||||
for (int x = x0; x < x1; x++)
|
|
||||||
{
|
{
|
||||||
if (fragcolor[x] > 0x7f000000)
|
for (int x = x0; x < x1; x++)
|
||||||
line[x] = thread->scanline.FragColor[x];
|
{
|
||||||
|
line[x] = BlendColor(style, fragcolor[x], line[x]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int x = x0; x < x1; x++)
|
||||||
|
{
|
||||||
|
if (fragcolor[x] > 0x7f000000)
|
||||||
|
line[x] = BlendColor(style, fragcolor[x], line[x]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +248,7 @@ static void DrawSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, Pol
|
||||||
RunShader(x0, x1, thread);
|
RunShader(x0, x1, thread);
|
||||||
|
|
||||||
if (thread->drawargs.WriteColor())
|
if (thread->drawargs.WriteColor())
|
||||||
WriteBlend(y, x0, x1, thread);
|
WriteColor(y, x0, x1, thread);
|
||||||
if (thread->drawargs.WriteDepth())
|
if (thread->drawargs.WriteDepth())
|
||||||
WriteDepth(y, x0, x1, thread);
|
WriteDepth(y, x0, x1, thread);
|
||||||
if (thread->drawargs.WriteStencil())
|
if (thread->drawargs.WriteStencil())
|
||||||
|
|
Loading…
Reference in a new issue