Add a new blend mode for sprites

This commit is contained in:
Magnus Norddahl 2016-11-30 07:49:04 +01:00
parent 6cc33553c2
commit 03282c957b
7 changed files with 34 additions and 2 deletions

View file

@ -119,6 +119,7 @@ extern "C"
void TriDrawNormal32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawNormal32_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawNormal32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawNormal32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawNormal32_12_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_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillNormal8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillNormal8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillNormal8_2_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_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillNormal32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillNormal32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillNormal32_12_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_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawSubsector8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawSubsector8_2_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_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawSubsector8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawSubsector8_12_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_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawSubsector32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawSubsector32_2_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_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawSubsector32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriDrawSubsector32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriDrawSubsector32_12_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_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillSubsector8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector8_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillSubsector8_2_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_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillSubsector8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector8_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillSubsector8_12_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_0_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillSubsector32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector32_1_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillSubsector32_2_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_10_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillSubsector32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriFillSubsector32_11_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriFillSubsector32_12_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 TriStencil_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
void TriStencilClose_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *); void TriStencilClose_SSE2(const TriDrawTriangleArgs *, WorkerThreadData *);
} }

View file

@ -253,10 +253,11 @@ enum class TriBlendMode
TranslateAlphaBlend, // blend_alpha_blend(shade(translate(fg)), bg) TranslateAlphaBlend, // blend_alpha_blend(shade(translate(fg)), bg)
TranslateAdd, // blend_add(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) 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)) 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 class Drawers
{ {

View file

@ -150,6 +150,12 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPla
args.uniforms.srcalpha = 256; args.uniforms.srcalpha = 256;
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; 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]) else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add])
{ {
args.uniforms.destalpha = (uint32_t)(1.0 * 256); args.uniforms.destalpha = (uint32_t)(1.0 * 256);

View file

@ -376,6 +376,7 @@ FString DrawPolyTrianglesCommand::DebugInfo()
case TriBlendMode::TranslateAdd: blendmodestr = "TranslateAdd"; break; case TriBlendMode::TranslateAdd: blendmodestr = "TranslateAdd"; break;
case TriBlendMode::TranslateSub: blendmodestr = "TranslateSub"; break; case TriBlendMode::TranslateSub: blendmodestr = "TranslateSub"; break;
case TriBlendMode::TranslateRevSub: blendmodestr = "TranslateRevSub"; break; case TriBlendMode::TranslateRevSub: blendmodestr = "TranslateRevSub"; break;
case TriBlendMode::AddSrcColorOneMinusSrcColor: blendmodestr = "AddSrcColorOneMinusSrcColor"; break;
} }
FString info; FString info;

View file

@ -160,3 +160,10 @@ SSAVec4i DrawerCodegen::blend_stencil(SSAVec4i stencilcolor, SSAInt fgalpha, SSA
SSAVec4i color = (stencilcolor * srcalpha + bg * destalpha) / 256; SSAVec4i color = (stencilcolor * srcalpha + bg * destalpha) / 256;
return color.insert(3, 255); 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;
}

View file

@ -86,6 +86,7 @@ public:
SSAVec4i blend_revsub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha); SSAVec4i blend_revsub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha);
SSAVec4i blend_alpha_blend(SSAVec4i fg, SSAVec4i bg); SSAVec4i blend_alpha_blend(SSAVec4i fg, SSAVec4i bg);
SSAVec4i blend_stencil(SSAVec4i color, SSAInt fgalpha, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha); 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 // Calculates the final alpha values to be used when combined with the source texture alpha channel
SSAInt calc_blend_bgalpha(SSAVec4i fg, SSAInt destalpha); SSAInt calc_blend_bgalpha(SSAVec4i fg, SSAInt destalpha);

View file

@ -670,6 +670,10 @@ SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying)
fg = TranslateSample32(uvoffset); fg = TranslateSample32(uvoffset);
output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha));
break; break;
case TriBlendMode::AddSrcColorOneMinusSrcColor:
fg = Sample32(uvoffset);
output = blend_add_srccolor_oneminussrccolor(shade_bgra_simple(fg, currentlight), bg);
break;
} }
return output; 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 = ToPal8(blend_revsub(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha)));
output = (palindex == SSAInt(0)).select(bg, output); output = (palindex == SSAInt(0)).select(bg, output);
break; 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; return output;