diff --git a/src/r_compiler/fixedfunction/drawercodegen.cpp b/src/r_compiler/fixedfunction/drawercodegen.cpp index 761023ceff..65b726b934 100644 --- a/src/r_compiler/fixedfunction/drawercodegen.cpp +++ b/src/r_compiler/fixedfunction/drawercodegen.cpp @@ -107,18 +107,27 @@ SSAVec4i DrawerCodegen::blend_copy(SSAVec4i fg) SSAVec4i DrawerCodegen::blend_add(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha) { + SSAInt alpha = fg[3]; + alpha = alpha + (alpha >> 7); // 255 -> 256 + srcalpha = (alpha * srcalpha + 128) >> 8; SSAVec4i color = (fg * srcalpha + bg * destalpha) / 256; return color.insert(3, 255); } SSAVec4i DrawerCodegen::blend_sub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha) { + SSAInt alpha = fg[3]; + alpha = alpha + (alpha >> 7); // 255 -> 256 + srcalpha = (alpha * srcalpha + 128) >> 8; SSAVec4i color = (bg * destalpha - fg * srcalpha) / 256; return color.insert(3, 255); } SSAVec4i DrawerCodegen::blend_revsub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha) { + SSAInt alpha = fg[3]; + alpha = alpha + (alpha >> 7); // 255 -> 256 + srcalpha = (alpha * srcalpha + 128) >> 8; SSAVec4i color = (fg * srcalpha - bg * destalpha) / 256; return color.insert(3, 255); } @@ -126,7 +135,7 @@ SSAVec4i DrawerCodegen::blend_revsub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAVec4i DrawerCodegen::blend_alpha_blend(SSAVec4i fg, SSAVec4i bg) { SSAInt alpha = fg[3]; - alpha = alpha + (alpha >> 7); // // 255 -> 256 + alpha = alpha + (alpha >> 7); // 255 -> 256 SSAInt inv_alpha = 256 - alpha; SSAVec4i color = (fg * alpha + bg * inv_alpha) / 256; return color.insert(3, 255); @@ -139,3 +148,15 @@ SSAInt DrawerCodegen::calc_blend_bgalpha(SSAVec4i fg, SSAInt destalpha) SSAInt inv_alpha = 256 - alpha; return (destalpha * alpha + 256 * inv_alpha + 128) >> 8; } + +SSAVec4i DrawerCodegen::blend_stencil(SSAVec4i stencilcolor, SSAInt fgalpha, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha) +{ + fgalpha = fgalpha + (fgalpha >> 7); // 255 -> 256 + SSAInt inv_fgalpha = 256 - fgalpha; + + srcalpha = (fgalpha * srcalpha + 128) >> 8; + destalpha = (destalpha * fgalpha + 256 * inv_fgalpha + 128) >> 8; + + SSAVec4i color = (stencilcolor * srcalpha + bg * destalpha) / 256; + return color.insert(3, 255); +} diff --git a/src/r_compiler/fixedfunction/drawercodegen.h b/src/r_compiler/fixedfunction/drawercodegen.h index 5de52dca1c..ef6e8d11ef 100644 --- a/src/r_compiler/fixedfunction/drawercodegen.h +++ b/src/r_compiler/fixedfunction/drawercodegen.h @@ -85,6 +85,7 @@ public: SSAVec4i blend_sub(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_stencil(SSAVec4i color, SSAInt fgalpha, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha); // 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/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp index da6933149d..4ee444067e 100644 --- a/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp +++ b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp @@ -552,7 +552,6 @@ SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying) SSAInt uvoffset = upos * textureHeight + vpos; SSAVec4i fg; - SSAInt alpha, inv_alpha; SSAVec4i output; switch (blendmode) @@ -584,10 +583,7 @@ SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying) break; case TriBlendMode::Shaded: fg = Sample32(uvoffset); - alpha = fg[0]; - alpha = alpha + (alpha >> 7); // 255 -> 256 - inv_alpha = 256 - alpha; - output = blend_add(shade_bgra_simple(SSAVec4i::unpack(color), currentlight), bg, alpha, inv_alpha); + output = blend_stencil(shade_bgra_simple(SSAVec4i::unpack(color), currentlight), fg[3], bg, srcalpha, destalpha); break; case TriBlendMode::TranslateCopy: fg = TranslateSample32(uvoffset); @@ -667,10 +663,7 @@ SSAInt DrawTriangleCodegen::ProcessPixel8(SSAInt bg, SSAInt *varying) output = ToPal8(blend_revsub(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha))); break; case TriBlendMode::Shaded: - alpha = Sample8(uvoffset); - alpha = alpha + (alpha >> 7); // 255 -> 256 - inv_alpha = 256 - alpha; - output = ToPal8(blend_add(ToBgra(Shade8(color)), ToBgra(bg), alpha, inv_alpha)); + output = ToPal8(blend_stencil(ToBgra(Shade8(color)), Sample8(uvoffset), ToBgra(bg), srcalpha, destalpha)); break; case TriBlendMode::TranslateCopy: output = Shade8(TranslateSample8(uvoffset)); diff --git a/src/r_compiler/llvmdrawers.h b/src/r_compiler/llvmdrawers.h index 1cbafa11a6..dbaef8b479 100644 --- a/src/r_compiler/llvmdrawers.h +++ b/src/r_compiler/llvmdrawers.h @@ -281,7 +281,7 @@ enum class TriBlendMode Add, // blend_add(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) Sub, // blend_sub(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) RevSub, // blend_revsub(shade(fg), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) - Shaded, // blend_add(color, bg, fg.a, 1 - fg.a) + Shaded, // blend_stencil(shade(color), fg, bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) TranslateCopy, // blend_copy(shade(translate(fg))) TranslateAlphaBlend, // blend_alpha_blend(shade(translate(fg)), bg) TranslateAdd, // blend_add(shade(translate(fg)), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)) diff --git a/src/r_poly_decal.cpp b/src/r_poly_decal.cpp index 5035b4529e..f23ca28631 100644 --- a/src/r_poly_decal.cpp +++ b/src/r_poly_decal.cpp @@ -128,30 +128,31 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co bool fullbrightSprite = (decal->RenderFlags & RF_FULLBRIGHT) == RF_FULLBRIGHT; - TriUniforms uniforms; + PolyDrawArgs args; + args.uniforms.flags = 0; if (fullbrightSprite || fixedlightlev >= 0 || fixedcolormap) { - uniforms.light = 256; - uniforms.flags = TriUniforms::fixed_light; + args.uniforms.light = 256; + args.uniforms.flags |= TriUniforms::fixed_light; } else { - uniforms.light = (uint32_t)((front->lightlevel + actualextralight) / 255.0f * 256.0f); - uniforms.flags = 0; + args.uniforms.light = (uint32_t)((front->lightlevel + actualextralight) / 255.0f * 256.0f); } - uniforms.subsectorDepth = subsectorDepth; + args.uniforms.subsectorDepth = subsectorDepth; if (r_swtruecolor) { - uniforms.color = 0xff000000 | decal->AlphaColor; + args.uniforms.color = 0xff000000 | decal->AlphaColor; } else { - uniforms.color = ((uint32_t)decal->AlphaColor) >> 24; + args.uniforms.color = ((uint32_t)decal->AlphaColor) >> 24; } + + args.uniforms.srcalpha = 256; + args.uniforms.destalpha = 0; - PolyDrawArgs args; - args.uniforms = uniforms; args.objectToClip = &worldToClip; args.vinput = vertices; args.vcount = 4; diff --git a/src/r_poly_sprite.cpp b/src/r_poly_sprite.cpp index e4738ab264..bc032b91ca 100644 --- a/src/r_poly_sprite.cpp +++ b/src/r_poly_sprite.cpp @@ -116,21 +116,19 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, AActor *thing, subse bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)); - TriUniforms uniforms; + PolyDrawArgs args; + args.uniforms.flags = 0; if (fullbrightSprite || fixedlightlev >= 0 || fixedcolormap) { - uniforms.light = 256; - uniforms.flags = TriUniforms::fixed_light; + args.uniforms.light = 256; + args.uniforms.flags |= TriUniforms::fixed_light; } else { - uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f); - uniforms.flags = 0; + args.uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f); } - uniforms.subsectorDepth = subsectorDepth; + args.uniforms.subsectorDepth = subsectorDepth; - PolyDrawArgs args; - args.uniforms = uniforms; args.objectToClip = &worldToClip; args.vinput = vertices; args.vcount = 4; @@ -141,106 +139,91 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, AActor *thing, subse args.SetTexture(tex, thing->Translation); args.SetColormap(sub->sector->ColorMap); + TriBlendMode blendmode; + if (thing->RenderStyle == LegacyRenderStyles[STYLE_Normal] || (r_drawfuzz == 0 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])) { args.uniforms.destalpha = 0; args.uniforms.srcalpha = 256; - (args.translation) ? - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::TranslateAdd) : - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add); + blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add]) { args.uniforms.destalpha = (uint32_t)(1.0 * 256); args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - (args.translation) ? - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::TranslateAdd) : - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add); + blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Subtract]) { args.uniforms.destalpha = (uint32_t)(1.0 * 256); args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - (args.translation) ? - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::TranslateSub) : - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Sub); + blendmode = args.translation ? TriBlendMode::TranslateSub : TriBlendMode::Sub; } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_SoulTrans]) { args.uniforms.destalpha = (uint32_t)(256 - transsouls * 256); args.uniforms.srcalpha = (uint32_t)(transsouls * 256); - (args.translation) ? - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::TranslateAdd) : - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add); + blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] || (r_drawfuzz == 2 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])) { // NYI - Fuzzy - for now, just a copy of "Shadow" args.uniforms.destalpha = 160; args.uniforms.srcalpha = 0; - (args.translation) ? - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::TranslateAdd) : - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add); - + blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shadow] || (r_drawfuzz == 1 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])) { args.uniforms.destalpha = 160; args.uniforms.srcalpha = 0; - (args.translation) ? - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::TranslateAdd) : - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add); - + blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil]) { - // NYI args.uniforms.destalpha = (uint32_t)(256 - thing->Alpha * 256); args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); args.uniforms.color = 0xff000000 | thing->fillcolor; - (args.translation) ? - PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::TranslateAdd) : - PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::Add); + blendmode = TriBlendMode::Shaded; } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddStencil]) { - // NYI args.uniforms.destalpha = 256; - args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); + args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256) * 2; // Don't know this needs to be multiplied by two.. args.uniforms.color = 0xff000000 | thing->fillcolor; - (args.translation) ? - PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::TranslateAdd) : - PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::Add); + blendmode = TriBlendMode::Shaded; } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shaded]) { - args.uniforms.destalpha = 256; args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - args.SetTexture(tex, false); + args.uniforms.destalpha = 256 - args.uniforms.srcalpha; args.uniforms.color = 0; - uniforms.flags |= TriUniforms::simple_shade; - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Shaded); + blendmode = TriBlendMode::Shaded; } else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddShaded]) - { // NYI? + { args.uniforms.destalpha = 256; args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - args.SetTexture(tex, false); args.uniforms.color = 0; - uniforms.flags |= TriUniforms::simple_shade; - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Shaded); + blendmode = TriBlendMode::Shaded; } else { args.uniforms.destalpha = (uint32_t)(256 - thing->Alpha * 256); args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256); - (args.translation) ? - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::TranslateAdd) : - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Add); + blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add; + } + + if (!r_swtruecolor) + { + uint32_t r = (args.uniforms.color >> 16) & 0xff; + uint32_t g = (args.uniforms.color >> 8) & 0xff; + uint32_t b = args.uniforms.color & 0xff; + args.uniforms.color = RGB32k.RGB[r >> 3][g >> 3][b >> 3]; } + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, blendmode); } bool RenderPolySprite::IsThingCulled(AActor *thing)