From 03282c957b28a24b1bc90f430f041a85e2dd9a62 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Wed, 30 Nov 2016 07:49:04 +0100 Subject: [PATCH] Add a new blend mode for sprites --- src/r_drawers.cpp | 6 ++++++ src/r_drawers.h | 5 +++-- src/r_poly_sprite.cpp | 6 ++++++ src/r_poly_triangle.cpp | 1 + tools/drawergen/fixedfunction/drawercodegen.cpp | 7 +++++++ tools/drawergen/fixedfunction/drawercodegen.h | 1 + tools/drawergen/fixedfunction/drawtrianglecodegen.cpp | 10 ++++++++++ 7 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/r_drawers.cpp b/src/r_drawers.cpp index 72241fe74..f94f409c4 100644 --- a/src/r_drawers.cpp +++ b/src/r_drawers.cpp @@ -119,6 +119,7 @@ extern "C" void TriDrawNormal32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawNormal32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawNormal32_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawNormal32_13_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillNormal8_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillNormal8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillNormal8_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); @@ -145,6 +146,7 @@ extern "C" void TriFillNormal32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillNormal32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillNormal32_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillNormal32_13_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector8_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector8_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); @@ -158,6 +160,7 @@ extern "C" void TriDrawSubsector8_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector8_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector8_13_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector32_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector32_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); @@ -171,6 +174,7 @@ extern "C" void TriDrawSubsector32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector32_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriDrawSubsector32_13_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector8_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector8_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); @@ -184,6 +188,7 @@ extern "C" void TriFillSubsector8_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector8_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector8_13_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector32_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector32_2_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); @@ -197,6 +202,7 @@ extern "C" void TriFillSubsector32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector32_12_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); + void TriFillSubsector32_13_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriStencil_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriStencilClose_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); } diff --git a/src/r_drawers.h b/src/r_drawers.h index bb541e99c..e986181ab 100644 --- a/src/r_drawers.h +++ b/src/r_drawers.h @@ -253,10 +253,11 @@ enum class TriBlendMode TranslateAlphaBlend, // blend_alpha_blend(shade(translate(fg)), bg) TranslateAdd, // blend_add(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) TranslateSub, // blend_sub(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) - TranslateRevSub // blend_revsub(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) + TranslateRevSub,// blend_revsub(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) + AddSrcColorOneMinusSrcColor // glBlendMode(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR) used by GZDoom's fullbright additive sprites }; -inline int NumTriBlendModes() { return (int)TriBlendMode::TranslateRevSub + 1; } +inline int NumTriBlendModes() { return (int)TriBlendMode::AddSrcColorOneMinusSrcColor + 1; } class Drawers { diff --git a/src/r_poly_sprite.cpp b/src/r_poly_sprite.cpp index edb46c460..eb1328b48 100644 --- a/src/r_poly_sprite.cpp +++ b/src/r_poly_sprite.cpp @@ -150,6 +150,12 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPla args.uniforms.srcalpha = 256; blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; } + else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && args.translation == nullptr) + { + args.uniforms.destalpha = 256; + args.uniforms.srcalpha = 256; + blendmode = TriBlendMode::AddSrcColorOneMinusSrcColor; + } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add]) { args.uniforms.destalpha = (uint32_t)(1.0 * 256); diff --git a/src/r_poly_triangle.cpp b/src/r_poly_triangle.cpp index ed7ab55b9..a3398df2b 100644 --- a/src/r_poly_triangle.cpp +++ b/src/r_poly_triangle.cpp @@ -376,6 +376,7 @@ FString DrawPolyTrianglesCommand::DebugInfo() case TriBlendMode::TranslateAdd: blendmodestr = "TranslateAdd"; break; case TriBlendMode::TranslateSub: blendmodestr = "TranslateSub"; break; case TriBlendMode::TranslateRevSub: blendmodestr = "TranslateRevSub"; break; + case TriBlendMode::AddSrcColorOneMinusSrcColor: blendmodestr = "AddSrcColorOneMinusSrcColor"; break; } FString info; diff --git a/tools/drawergen/fixedfunction/drawercodegen.cpp b/tools/drawergen/fixedfunction/drawercodegen.cpp index 02c6e302a..a4ad1a941 100644 --- a/tools/drawergen/fixedfunction/drawercodegen.cpp +++ b/tools/drawergen/fixedfunction/drawercodegen.cpp @@ -160,3 +160,10 @@ SSAVec4i DrawerCodegen::blend_stencil(SSAVec4i stencilcolor, SSAInt fgalpha, SSA SSAVec4i color = (stencilcolor * srcalpha + bg * destalpha) / 256; return color.insert(3, 255); } + +SSAVec4i DrawerCodegen::blend_add_srccolor_oneminussrccolor(SSAVec4i fg, SSAVec4i bg) +{ + SSAVec4i fgcolor = fg + (fg >> 7); // 255 -> 256 + SSAVec4i inv_fgcolor = SSAVec4i(256) - fgcolor; + return fg + (bg * inv_fgcolor + 128) >> 8; +} diff --git a/tools/drawergen/fixedfunction/drawercodegen.h b/tools/drawergen/fixedfunction/drawercodegen.h index 8404f3acd..d1931e99c 100644 --- a/tools/drawergen/fixedfunction/drawercodegen.h +++ b/tools/drawergen/fixedfunction/drawercodegen.h @@ -86,6 +86,7 @@ public: SSAVec4i blend_revsub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha); SSAVec4i blend_alpha_blend(SSAVec4i fg, SSAVec4i bg); SSAVec4i blend_stencil(SSAVec4i color, SSAInt fgalpha, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha); + SSAVec4i blend_add_srccolor_oneminussrccolor(SSAVec4i fg, SSAVec4i bg); // Calculates the final alpha values to be used when combined with the source texture alpha channel SSAInt calc_blend_bgalpha(SSAVec4i fg, SSAInt destalpha); diff --git a/tools/drawergen/fixedfunction/drawtrianglecodegen.cpp b/tools/drawergen/fixedfunction/drawtrianglecodegen.cpp index 8178a58cc..b53a5f791 100644 --- a/tools/drawergen/fixedfunction/drawtrianglecodegen.cpp +++ b/tools/drawergen/fixedfunction/drawtrianglecodegen.cpp @@ -670,6 +670,10 @@ SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying) fg = TranslateSample32(uvoffset); output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break; + case TriBlendMode::AddSrcColorOneMinusSrcColor: + fg = Sample32(uvoffset); + output = blend_add_srccolor_oneminussrccolor(shade_bgra_simple(fg, currentlight), bg); + break; } return output; @@ -771,6 +775,12 @@ SSAInt DrawTriangleCodegen::ProcessPixel8(SSAInt bg, SSAInt *varying) output = ToPal8(blend_revsub(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha))); output = (palindex == SSAInt(0)).select(bg, output); break; + case TriBlendMode::AddSrcColorOneMinusSrcColor: + palindex = Sample8(uvoffset); + fg = ToBgra(Shade8(palindex)); + output = ToPal8(blend_add_srccolor_oneminussrccolor(fg, ToBgra(bg))); + output = (palindex == SSAInt(0)).select(bg, output); + break; } return output;