- implement all styles for sprites in softpoly

This commit is contained in:
Magnus Norddahl 2017-03-27 21:03:51 +02:00
parent 78095460ac
commit 0537e9c1ba
13 changed files with 139 additions and 138 deletions

View file

@ -128,7 +128,7 @@ private:
uint8_t mStencilWriteValue = 0; uint8_t mStencilWriteValue = 0;
const uint8_t *mColormaps = nullptr; const uint8_t *mColormaps = nullptr;
float mClipPlane[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; float mClipPlane[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
TriBlendMode mBlendMode = TriBlendMode::Copy; TriBlendMode mBlendMode = TriBlendMode::FillOpaque;
uint32_t mLight = 0; uint32_t mLight = 0;
uint32_t mSubsectorDepth = 0; uint32_t mSubsectorDepth = 0;
uint32_t mColor = 0; uint32_t mColor = 0;

View file

@ -53,7 +53,7 @@ public:
Loop<AdvancedShade, LinearFilter>(args, thread); Loop<AdvancedShade, LinearFilter>(args, thread);
} }
} }
else // no linear filtering for translated, shaded, fill or skycap else // no linear filtering for translated, shaded, stencil, fill or skycap
{ {
if (is_simple_shade) if (is_simple_shade)
{ {
@ -453,7 +453,7 @@ private:
using namespace TriScreenDrawerModes; using namespace TriScreenDrawerModes;
uint32_t texel; uint32_t texel;
if (SamplerT::Mode == (int)Samplers::Shaded || SamplerT::Mode == (int)Samplers::Fill) if (SamplerT::Mode == (int)Samplers::Shaded || SamplerT::Mode == (int)Samplers::Stencil || SamplerT::Mode == (int)Samplers::Fill)
{ {
return color; return color;
} }
@ -542,6 +542,14 @@ private:
sampleshadeout += sampleshadeout >> 7; // 255 -> 256 sampleshadeout += sampleshadeout >> 7; // 255 -> 256
return sampleshadeout; return sampleshadeout;
} }
else if (SamplerT::Mode == (int)Samplers::Stencil)
{
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]);
sampleshadeout += sampleshadeout >> 7; // 255 -> 256
return sampleshadeout;
}
else else
{ {
return 0; return 0;
@ -621,6 +629,8 @@ private:
} }
else if (BlendT::Mode == (int)BlendModes::AddClampShaded) else if (BlendT::Mode == (int)BlendModes::AddClampShaded)
{ {
ifgshade0 = (ifgshade0 * srcalpha + 128) >> 8;
ifgshade1 = (ifgshade1 * srcalpha + 128) >> 8;
__m128i alpha = _mm_set_epi16(ifgshade1, ifgshade1, ifgshade1, ifgshade1, ifgshade0, ifgshade0, ifgshade0, ifgshade0); __m128i alpha = _mm_set_epi16(ifgshade1, ifgshade1, ifgshade1, ifgshade1, ifgshade0, ifgshade0, ifgshade0, ifgshade0);
fgcolor = _mm_srli_epi16(_mm_mullo_epi16(fgcolor, alpha), 8); fgcolor = _mm_srli_epi16(_mm_mullo_epi16(fgcolor, alpha), 8);

View file

@ -272,7 +272,7 @@ private:
using namespace TriScreenDrawerModes; using namespace TriScreenDrawerModes;
uint8_t texel; uint8_t texel;
if (SamplerT::Mode == (int)Samplers::Shaded || SamplerT::Mode == (int)Samplers::Fill) if (SamplerT::Mode == (int)Samplers::Shaded || SamplerT::Mode == (int)Samplers::Stencil || SamplerT::Mode == (int)Samplers::Fill)
{ {
return color; return color;
} }
@ -301,13 +301,14 @@ private:
if (a == 256) if (a == 256)
return texel; return texel;
uint32_t capcolor = GPalette.BaseColors[color].d;
uint32_t texelrgb = GPalette.BaseColors[texel].d; uint32_t texelrgb = GPalette.BaseColors[texel].d;
uint32_t r = RPART(texelrgb); uint32_t r = RPART(texelrgb);
uint32_t g = GPART(texelrgb); uint32_t g = GPART(texelrgb);
uint32_t b = BPART(texelrgb); uint32_t b = BPART(texelrgb);
uint32_t capcolor_red = RPART(color); uint32_t capcolor_red = RPART(capcolor);
uint32_t capcolor_green = GPART(color); uint32_t capcolor_green = GPART(capcolor);
uint32_t capcolor_blue = BPART(color); uint32_t capcolor_blue = BPART(capcolor);
r = (r * a + capcolor_red * inv_a + 127) >> 8; r = (r * a + capcolor_red * inv_a + 127) >> 8;
g = (g * a + capcolor_green * inv_a + 127) >> 8; g = (g * a + capcolor_green * inv_a + 127) >> 8;
b = (b * a + capcolor_blue * inv_a + 127) >> 8; b = (b * a + capcolor_blue * inv_a + 127) >> 8;
@ -331,6 +332,12 @@ private:
sampleshadeout += sampleshadeout >> 7; // 255 -> 256 sampleshadeout += sampleshadeout >> 7; // 255 -> 256
return sampleshadeout; return sampleshadeout;
} }
else if (SamplerT::Mode == (int)Samplers::Stencil)
{
uint32_t texelX = ((((uint32_t)u << 8) >> 16) * texWidth) >> 16;
uint32_t texelY = ((((uint32_t)v << 8) >> 16) * texHeight) >> 16;
return texPixels[texelX * texHeight + texelY] != 0 ? 256 : 0;
}
else else
{ {
return 0; return 0;
@ -372,6 +379,7 @@ private:
} }
else if (BlendT::Mode == (int)BlendModes::Shaded) else if (BlendT::Mode == (int)BlendModes::Shaded)
{ {
fgshade = (fgshade * srcalpha + 128) >> 8;
uint32_t alpha = fgshade; uint32_t alpha = fgshade;
uint32_t inv_alpha = 256 - fgshade; uint32_t inv_alpha = 256 - fgshade;
int32_t fg_r = GPalette.BaseColors[shadedfg].r; int32_t fg_r = GPalette.BaseColors[shadedfg].r;
@ -390,6 +398,7 @@ private:
} }
else if (BlendT::Mode == (int)BlendModes::AddClampShaded) else if (BlendT::Mode == (int)BlendModes::AddClampShaded)
{ {
fgshade = (fgshade * srcalpha + 128) >> 8;
uint32_t alpha = fgshade; uint32_t alpha = fgshade;
int32_t fg_r = GPalette.BaseColors[shadedfg].r; int32_t fg_r = GPalette.BaseColors[shadedfg].r;
int32_t fg_g = GPalette.BaseColors[shadedfg].g; int32_t fg_g = GPalette.BaseColors[shadedfg].g;
@ -417,21 +426,21 @@ private:
if (BlendT::Mode == (int)BlendModes::AddClamp) if (BlendT::Mode == (int)BlendModes::AddClamp)
{ {
fg_r = MIN<int32_t>((fg_r * srcalpha + bg_r * destalpha + 127) >> 8, 255); fg_r = MIN(int32_t(fg_r * srcalpha + bg_r * destalpha + 127) >> 8, 255);
fg_g = MIN<int32_t>((fg_g * srcalpha + bg_g * destalpha + 127) >> 8, 255); fg_g = MIN(int32_t(fg_g * srcalpha + bg_g * destalpha + 127) >> 8, 255);
fg_b = MIN<int32_t>((fg_b * srcalpha + bg_b * destalpha + 127) >> 8, 255); fg_b = MIN(int32_t(fg_b * srcalpha + bg_b * destalpha + 127) >> 8, 255);
} }
else if (BlendT::Mode == (int)BlendModes::SubClamp) else if (BlendT::Mode == (int)BlendModes::SubClamp)
{ {
fg_r = MAX<int32_t>((fg_r * srcalpha - bg_r * destalpha + 127) >> 8, 0); fg_r = MAX(int32_t(fg_r * srcalpha - bg_r * destalpha + 127) >> 8, 0);
fg_g = MAX<int32_t>((fg_g * srcalpha - bg_g * destalpha + 127) >> 8, 0); fg_g = MAX(int32_t(fg_g * srcalpha - bg_g * destalpha + 127) >> 8, 0);
fg_b = MAX<int32_t>((fg_b * srcalpha - bg_b * destalpha + 127) >> 8, 0); fg_b = MAX(int32_t(fg_b * srcalpha - bg_b * destalpha + 127) >> 8, 0);
} }
else if (BlendT::Mode == (int)BlendModes::RevSubClamp) else if (BlendT::Mode == (int)BlendModes::RevSubClamp)
{ {
fg_r = MAX<int32_t>((bg_r * srcalpha - fg_r * destalpha + 127) >> 8, 0); fg_r = MAX(int32_t(bg_r * srcalpha - fg_r * destalpha + 127) >> 8, 0);
fg_g = MAX<int32_t>((bg_g * srcalpha - fg_g * destalpha + 127) >> 8, 0); fg_g = MAX(int32_t(bg_g * srcalpha - fg_g * destalpha + 127) >> 8, 0);
fg_b = MAX<int32_t>((bg_b * srcalpha - fg_b * destalpha + 127) >> 8, 0); fg_b = MAX(int32_t(bg_b * srcalpha - fg_b * destalpha + 127) >> 8, 0);
} }
shadedfg = RGB256k.All[((fg_r >> 2) << 12) | ((fg_g >> 2) << 6) | (fg_b >> 2)]; shadedfg = RGB256k.All[((fg_r >> 2) << 12) | ((fg_g >> 2) << 6) | (fg_b >> 2)];

View file

@ -99,10 +99,8 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD
{ {
int bmode = (int)drawargs.BlendMode(); int bmode = (int)drawargs.BlendMode();
if (drawargs.WriteColor() && drawargs.TexturePixels()) if (drawargs.WriteColor())
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriDraw32[bmode] : ScreenTriangle::TriDraw8[bmode]; drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriDrawers32[bmode] : ScreenTriangle::TriDrawers8[bmode];
else if (drawargs.WriteColor())
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriFill32[bmode] : ScreenTriangle::TriFill8[bmode];
} }
if (drawargs.WriteStencil()) if (drawargs.WriteStencil())

View file

@ -922,87 +922,62 @@ void ScreenTriangle::SubsectorWrite(const TriDrawTriangleArgs *args, WorkerThrea
} }
} }
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriDraw8 = std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriDrawers8 =
{ {
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Copy", "opaque", false &TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AlphaBlend", "masked", false &TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AddSolid", "translucent", false &TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Add", "add", false &TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Sub", "sub", false &TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "RevSub", "revsub", false &TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Stencil", "stencil", false &TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Shaded", "shaded", false &TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateCopy", "opaque", true &TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAlphaBlend", "masked", true &TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAdd", "add", true &TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateSub", "sub", true &TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateRevSub", "revsub", true &TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
&TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AddSrcColorOneMinusSrcColor", "addsrccolor", false &TriScreenDrawer8<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // "Skycap", "skycap", false &TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
}; &TriScreenDrawer8<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriFill8 = &TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
{ &TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Copy", "opaque", false &TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AlphaBlend", "masked", false &TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AddSolid", "translucent", false &TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // Skycap
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Add", "add", false
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Sub", "sub", false
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "RevSub", "revsub", false
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Stencil", "stencil", false
&TriScreenDrawer8<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Shaded", "shaded", false
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateCopy", "opaque", true
&TriScreenDrawer8<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAlphaBlend", "masked", true
&TriScreenDrawer8<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAdd", "add", true
&TriScreenDrawer8<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateSub", "sub", true
&TriScreenDrawer8<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateRevSub", "revsub", true
&TriScreenDrawer8<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AddSrcColorOneMinusSrcColor", "addsrccolor", false
&TriScreenDrawer8<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute // "Skycap", "skycap", false
}; };
#ifdef NO_SSE #ifdef NO_SSE
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriDraw32; std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriDrawers32;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriFill32;
#else #else
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriDraw32 = std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriDrawers32 =
{ {
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Copy", "opaque", false &TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureOpaque
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AlphaBlend", "masked", false &TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureMasked
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AddSolid", "translucent", false &TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAdd
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Add", "add", false &TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureSub
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "Sub", "sub", false &TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureRevSub
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "RevSub", "revsub", false &TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // TextureAddSrcColor
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Stencil", "stencil", false &TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedOpaque
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Shaded", "shaded", false &TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedMasked
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateCopy", "opaque", true &TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAdd
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAlphaBlend", "masked", true &TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedSub
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAdd", "add", true &TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedRevSub
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateSub", "sub", true &TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // TranslatedAddSrcColor
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateRevSub", "revsub", true &TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // Shaded
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::TextureSampler>::Execute, // "AddSrcColorOneMinusSrcColor", "addsrccolor", false &TriScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // AddShaded
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // "Skycap", "skycap", false &TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // Stencil
}; &TriScreenDrawer32<TriScreenDrawerModes::AddClampShadedBlend, TriScreenDrawerModes::StencilSampler>::Execute, // AddStencil
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillOpaque
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> ScreenTriangle::TriFill32 = &TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAdd
{ &TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillSub
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Copy", "opaque", false &TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillRevSub
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AlphaBlend", "masked", false &TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // FillAddSrcColor
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AddSolid", "translucent", false &TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::SkycapSampler>::Execute // Skycap
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Add", "add", false
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "Sub", "sub", false
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::FillSampler>::Execute, // "RevSub", "revsub", false
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Stencil", "stencil", false
&TriScreenDrawer32<TriScreenDrawerModes::ShadedBlend, TriScreenDrawerModes::ShadedSampler>::Execute, // "Shaded", "shaded", false
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateCopy", "opaque", true
&TriScreenDrawer32<TriScreenDrawerModes::MaskedBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAlphaBlend", "masked", true
&TriScreenDrawer32<TriScreenDrawerModes::AddClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateAdd", "add", true
&TriScreenDrawer32<TriScreenDrawerModes::SubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateSub", "sub", true
&TriScreenDrawer32<TriScreenDrawerModes::RevSubClampBlend, TriScreenDrawerModes::TranslatedSampler>::Execute, // "TranslateRevSub", "revsub", true
&TriScreenDrawer32<TriScreenDrawerModes::AddSrcColorBlend, TriScreenDrawerModes::FillSampler>::Execute, // "AddSrcColorOneMinusSrcColor", "addsrccolor", false
&TriScreenDrawer32<TriScreenDrawerModes::OpaqueBlend, TriScreenDrawerModes::FillSampler>::Execute // "Skycap", "skycap", false
}; };
#endif #endif

View file

@ -88,25 +88,30 @@ struct TriDrawTriangleArgs
enum class TriBlendMode enum class TriBlendMode
{ {
Copy, // blend_copy(shade(fg)) TextureOpaque,
AlphaBlend, // blend_alpha_blend(shade(fg), bg) TextureMasked,
AddSolid, // blend_add(shade(fg), bg, srcalpha, destalpha) TextureAdd,
Add, // blend_add(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) TextureSub,
Sub, // blend_sub(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) TextureRevSub,
RevSub, // blend_revsub(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) TextureAddSrcColor,
Stencil, // blend_stencil(shade(color), fg.a, bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) TranslatedOpaque,
Shaded, // blend_stencil(shade(color), fg.index, bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) TranslatedMasked,
TranslateCopy, // blend_copy(shade(translate(fg))) TranslatedAdd,
TranslateAlphaBlend, // blend_alpha_blend(shade(translate(fg)), bg) TranslatedSub,
TranslateAdd, // blend_add(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) TranslatedRevSub,
TranslateSub, // blend_sub(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) TranslatedAddSrcColor,
TranslateRevSub,// blend_revsub(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) Shaded,
AddSrcColorOneMinusSrcColor, // glBlendMode(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR) used by GZDoom's fullbright additive sprites AddShaded,
Skycap // Fade to sky color when the V texture coordinate go beyond the [-1, 1] range Stencil,
AddStencil,
FillOpaque,
FillAdd,
FillSub,
FillRevSub,
FillAddSrcColor,
Skycap
}; };
inline int NumTriBlendModes() { return (int)TriBlendMode::Skycap + 1; }
class ScreenTriangle class ScreenTriangle
{ {
public: public:
@ -115,10 +120,8 @@ public:
static void StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread); static void StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread);
static void SubsectorWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread); static void SubsectorWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread);
static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDraw8; static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawers8;
static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDraw32; static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawers32;
static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFill8;
static std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFill32;
}; };
struct ScreenTriangleStepVariables struct ScreenTriangleStepVariables
@ -147,10 +150,11 @@ namespace TriScreenDrawerModes
struct SimpleShade { static const int Mode = (int)ShadeMode::Simple; }; struct SimpleShade { static const int Mode = (int)ShadeMode::Simple; };
struct AdvancedShade { static const int Mode = (int)ShadeMode::Advanced; }; struct AdvancedShade { static const int Mode = (int)ShadeMode::Advanced; };
enum class Samplers { Texture, Fill, Shaded, Translated, Skycap }; enum class Samplers { Texture, Fill, Shaded, Stencil, Translated, Skycap };
struct TextureSampler { static const int Mode = (int)Samplers::Texture; }; struct TextureSampler { static const int Mode = (int)Samplers::Texture; };
struct FillSampler { static const int Mode = (int)Samplers::Fill; }; struct FillSampler { static const int Mode = (int)Samplers::Fill; };
struct ShadedSampler { static const int Mode = (int)Samplers::Shaded; }; struct ShadedSampler { static const int Mode = (int)Samplers::Shaded; };
struct StencilSampler { static const int Mode = (int)Samplers::Stencil; };
struct TranslatedSampler { static const int Mode = (int)Samplers::Translated; }; struct TranslatedSampler { static const int Mode = (int)Samplers::Translated; };
struct SkycapSampler { static const int Mode = (int)Samplers::Skycap; }; struct SkycapSampler { static const int Mode = (int)Samplers::Skycap; };
} }

View file

@ -133,7 +133,7 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClip
args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false); args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
args.SetSubsectorDepth(subsectorDepth); args.SetSubsectorDepth(subsectorDepth);
args.SetTransform(&worldToClip); args.SetTransform(&worldToClip);
args.SetStyle(TriBlendMode::Copy); args.SetStyle(TriBlendMode::TextureOpaque);
args.SetFaceCullCCW(true); args.SetFaceCullCCW(true);
args.SetStencilTestValue(stencilValue); args.SetStencilTestValue(stencilValue);
args.SetWriteStencil(true, stencilValue + 1); args.SetWriteStencil(true, stencilValue + 1);
@ -312,7 +312,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
if (!isSky) if (!isSky)
{ {
args.SetTexture(tex); args.SetTexture(tex);
args.SetStyle(TriBlendMode::Copy); args.SetStyle(TriBlendMode::TextureOpaque);
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan); args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
} }
else else

View file

@ -253,7 +253,7 @@ void RenderPolyScene::RenderPortals(int portalDepth)
args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(foggy), true); args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(foggy), true);
args.SetColor(0, 0); args.SetColor(0, 0);
args.SetClipPlane(PortalPlane); args.SetClipPlane(PortalPlane);
args.SetStyle(TriBlendMode::Copy); args.SetStyle(TriBlendMode::FillOpaque);
for (auto &portal : SectorPortals) for (auto &portal : SectorPortals)
{ {

View file

@ -70,18 +70,20 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
uint32_t topcapcolor = frontskytex->GetSkyCapColor(false); uint32_t topcapcolor = frontskytex->GetSkyCapColor(false);
uint32_t bottomcapcolor = frontskytex->GetSkyCapColor(true); uint32_t bottomcapcolor = frontskytex->GetSkyCapColor(true);
uint8_t topcapindex = RGB256k.All[((RPART(topcapcolor) >> 2) << 12) | ((GPART(topcapcolor) >> 2) << 6) | (BPART(topcapcolor) >> 2)];
uint8_t bottomcapindex = RGB256k.All[((RPART(bottomcapcolor) >> 2) << 12) | ((GPART(bottomcapcolor) >> 2) << 6) | (BPART(bottomcapcolor) >> 2)];
for (int i = 1; i <= mRows; i++) for (int i = 1; i <= mRows; i++)
{ {
RenderRow(args, i, topcapcolor); RenderRow(args, i, topcapcolor, topcapindex);
RenderRow(args, rc + i, bottomcapcolor); RenderRow(args, rc + i, bottomcapcolor, bottomcapindex);
} }
} }
void PolySkyDome::RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor) void PolySkyDome::RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor, uint8_t capcolorindex)
{ {
args.SetFaceCullCCW(false); args.SetFaceCullCCW(false);
args.SetColor(capcolor, 0); args.SetColor(capcolor, capcolorindex);
args.SetStyle(TriBlendMode::Skycap); args.SetStyle(TriBlendMode::Skycap);
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleStrip); args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleStrip);
} }
@ -93,7 +95,7 @@ void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int ro
args.SetFaceCullCCW(bottomCap); args.SetFaceCullCCW(bottomCap);
args.SetColor(solid, palsolid); args.SetColor(solid, palsolid);
args.SetStyle(TriBlendMode::Copy); args.SetStyle(TriBlendMode::FillOpaque);
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleFan); args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleFan);
} }

View file

@ -38,7 +38,7 @@ private:
void SkyVertex(int r, int c, bool yflip); void SkyVertex(int r, int c, bool yflip);
void CreateSkyHemisphere(bool zflip); void CreateSkyHemisphere(bool zflip);
void CreateDome(); void CreateDome();
void RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor); void RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor, uint8_t capcolorindex);
void RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap); void RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap);
TriVertex SetVertexXYZ(float xx, float yy, float zz, float uu = 0, float vv = 0); TriVertex SetVertexXYZ(float xx, float yy, float zz, float uu = 0, float vv = 0);

View file

@ -150,33 +150,33 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
if (thing->RenderStyle == LegacyRenderStyles[STYLE_Normal] || if (thing->RenderStyle == LegacyRenderStyles[STYLE_Normal] ||
(r_drawfuzz == 0 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])) (r_drawfuzz == 0 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
{ {
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 1.0, 0.0); args.SetStyle(args.Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 1.0, 0.0);
} }
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && !args.Translation()) else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && !args.Translation())
{ {
args.SetStyle(TriBlendMode::AddSrcColorOneMinusSrcColor, 1.0, 1.0); args.SetStyle(TriBlendMode::TextureAddSrcColor, 1.0, 1.0);
} }
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add]) else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add])
{ {
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0); args.SetStyle(args.Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, thing->Alpha, 1.0);
} }
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Subtract]) else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Subtract])
{ {
args.SetStyle(args.Translation() ? TriBlendMode::TranslateRevSub : TriBlendMode::RevSub, thing->Alpha, 1.0); args.SetStyle(args.Translation() ? TriBlendMode::TranslatedRevSub : TriBlendMode::TextureRevSub, thing->Alpha, 1.0);
} }
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_SoulTrans]) else if (thing->RenderStyle == LegacyRenderStyles[STYLE_SoulTrans])
{ {
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, transsouls, 1.0 - transsouls); args.SetStyle(args.Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, transsouls, 1.0 - transsouls);
} }
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] || else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] ||
(r_drawfuzz == 2 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])) (r_drawfuzz == 2 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
{ // NYI - Fuzzy - for now, just a copy of "Shadow" { // NYI - Fuzzy - for now, just a copy of "Shadow"
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0); args.SetStyle(args.Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 0.0, 160 / 255.0);
} }
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shadow] || else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shadow] ||
(r_drawfuzz == 1 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])) (r_drawfuzz == 1 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
{ {
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0); args.SetStyle(args.Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, 0.0, 160 / 255.0);
} }
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil]) else if (thing->RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil])
{ {
@ -186,23 +186,23 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddStencil]) else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddStencil])
{ {
args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24); args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24);
args.SetStyle(TriBlendMode::Stencil, thing->Alpha, 1.0 - thing->Alpha); args.SetStyle(TriBlendMode::AddStencil, thing->Alpha, 1.0);
} }
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shaded]) else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shaded])
{ {
args.SetColor(0, 0); args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24);
args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha); args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha);
args.SetTexture(tex, thing->Translation, true); args.SetTexture(tex, thing->Translation, true);
} }
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddShaded]) else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddShaded])
{ {
args.SetColor(0, 0); args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24);
args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha); args.SetStyle(TriBlendMode::AddShaded, thing->Alpha, 1.0);
args.SetTexture(tex, thing->Translation, true); args.SetTexture(tex, thing->Translation, true);
} }
else else
{ {
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0 - thing->Alpha); args.SetStyle(args.Translation() ? TriBlendMode::TranslatedAdd : TriBlendMode::TextureAdd, thing->Alpha, 1.0 - thing->Alpha);
} }
args.SetSubsectorDepthTest(true); args.SetSubsectorDepthTest(true);

View file

@ -272,12 +272,15 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &c
} }
else if (!Masked) else if (!Masked)
{ {
args.SetStyle(TriBlendMode::Copy); args.SetStyle(TriBlendMode::TextureOpaque);
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
} }
else else
{ {
args.SetStyle((Line->flags & ML_ADDTRANS) ? TriBlendMode::Add : TriBlendMode::AlphaBlend, Line->alpha, 1.0); bool addtrans = !!(Line->flags & ML_ADDTRANS);
double srcalpha = MIN(Line->alpha, 1.0);
double destalpha = addtrans ? 1.0 : 1.0 - srcalpha;
args.SetStyle(TriBlendMode::TextureAdd, srcalpha, destalpha);
args.SetSubsectorDepthTest(true); args.SetSubsectorDepthTest(true);
args.SetWriteSubsectorDepth(true); args.SetWriteSubsectorDepth(true);
args.SetWriteStencil(false); args.SetWriteStencil(false);

View file

@ -109,6 +109,6 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPl
args.SetSubsectorDepthTest(true); args.SetSubsectorDepthTest(true);
args.SetWriteSubsectorDepth(false); args.SetWriteSubsectorDepth(false);
args.SetWriteStencil(false); args.SetWriteStencil(false);
args.SetStyle(TriBlendMode::AlphaBlend); args.SetStyle(TriBlendMode::TextureMasked);
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan); args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
} }