diff --git a/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp index 8bf4779e2..21995bb63 100644 --- a/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp +++ b/src/r_compiler/fixedfunction/drawtrianglecodegen.cpp @@ -32,11 +32,14 @@ #include "r_compiler/ssa/ssa_struct_type.h" #include "r_compiler/ssa/ssa_value.h" -void DrawTriangleCodegen::Generate(TriDrawVariant variant, bool truecolor, SSAValue args, SSAValue thread_data) +void DrawTriangleCodegen::Generate(TriDrawVariant variant, TriBlendMode blendmode, bool truecolor, SSAValue args, SSAValue thread_data) { - LoadArgs(variant, truecolor, args, thread_data); - Setup(variant, truecolor); - LoopBlockY(variant, truecolor); + this->variant = variant; + this->blendmode = blendmode; + this->truecolor = truecolor; + LoadArgs(args, thread_data); + Setup(); + LoopBlockY(); } SSAInt DrawTriangleCodegen::FloatTo28_4(SSAFloat v) @@ -46,7 +49,7 @@ SSAInt DrawTriangleCodegen::FloatTo28_4(SSAFloat v) return (a + (a.ashr(31) | SSAInt(1))).ashr(1); } -void DrawTriangleCodegen::Setup(TriDrawVariant variant, bool truecolor) +void DrawTriangleCodegen::Setup() { int pixelsize = truecolor ? 4 : 1; @@ -154,7 +157,7 @@ SSAFloat DrawTriangleCodegen::grady(SSAFloat x0, SSAFloat y0, SSAFloat x1, SSAFl return top / bottom; } -void DrawTriangleCodegen::LoopBlockY(TriDrawVariant variant, bool truecolor) +void DrawTriangleCodegen::LoopBlockY() { int pixelsize = truecolor ? 4 : 1; @@ -171,7 +174,7 @@ void DrawTriangleCodegen::LoopBlockY(TriDrawVariant variant, bool truecolor) SSAIfBlock branch; branch.if_block((y / q) % thread.num_cores == thread.core); { - LoopBlockX(variant, truecolor); + LoopBlockX(); } branch.end_block(); @@ -182,7 +185,7 @@ void DrawTriangleCodegen::LoopBlockY(TriDrawVariant variant, bool truecolor) loop.end_block(); } -void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor) +void DrawTriangleCodegen::LoopBlockX() { stack_x.store(minx); @@ -260,7 +263,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor) SetStencilBlock(x / 8 + y / 8 * stencilPitch); SSABool covered = a == SSAInt(0xF) && b == SSAInt(0xF) && c == SSAInt(0xF) && !clipneeded; - if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::DrawShadedSubsector && variant != TriDrawVariant::FillSubsector) + if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector) { covered = covered && StencilIsSingleValue(); } @@ -269,11 +272,11 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor) SSAIfBlock branch_covered; branch_covered.if_block(covered); { - LoopFullBlock(variant, truecolor); + LoopFullBlock(); } branch_covered.else_block(); { - LoopPartialBlock(variant, truecolor); + LoopPartialBlock(); } branch_covered.end_block(); @@ -284,10 +287,10 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor) loop.end_block(); } -void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor) +void DrawTriangleCodegen::LoopFullBlock() { SSAIfBlock branch_stenciltest; - if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::DrawShadedSubsector && variant != TriDrawVariant::FillSubsector) + if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector) { branch_stenciltest.if_block(StencilGetSingle() == stencilTestValue); } @@ -325,18 +328,18 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor) varying[i] = stack_varying[i].load(); loopx.loop_block(ix < SSAInt(q), q); { - if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::DrawShadedSubsector || variant == TriDrawVariant::FillSubsector) + if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) { SSAIfBlock branch; branch.if_block(subsectorbuffer[ix].load(true) >= subsectorDepth); { - ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying, variant, truecolor); + ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying); } branch.end_block(); } else { - ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying, variant, truecolor); + ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying); } for (int i = 0; i < TriVertex::NumVarying; i++) @@ -353,13 +356,13 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor) loopy.end_block(); } - if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::DrawShadedSubsector && variant != TriDrawVariant::FillSubsector) + if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector) { branch_stenciltest.end_block(); } } -void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolor) +void DrawTriangleCodegen::LoopPartialBlock() { int pixelsize = truecolor ? 4 : 1; @@ -404,7 +407,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo SSABool visible = (ix + x >= clipleft) && (ix + x < clipright) && (iy + y >= cliptop) && (iy + y < clipbottom); SSABool covered = CX1 > SSAInt(0) && CX2 > SSAInt(0) && CX3 > SSAInt(0) && visible; - if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::DrawShadedSubsector || variant == TriDrawVariant::FillSubsector) + if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) { covered = covered && subsectorbuffer[ix].load(true) >= subsectorDepth; } @@ -422,7 +425,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo } else { - ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying, variant, truecolor); + ProcessPixel(buffer[ix * pixelsize], subsectorbuffer[ix], varying); } } branch.end_block(); @@ -447,91 +450,101 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo loopy.end_block(); } -void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying, TriDrawVariant variant, bool truecolor) +SSAVec4i DrawTriangleCodegen::TranslateSample(SSAInt uvoffset) { - if (variant == TriDrawVariant::Fill || variant == TriDrawVariant::FillSubsector) + if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) + return translation[color * 4].load_vec4ub(true); + else + return translation[texturePixels[uvoffset].load(true).zext_int() * 4].load_vec4ub(true); +} + +SSAVec4i DrawTriangleCodegen::Sample(SSAInt uvoffset) +{ + if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) + return SSAVec4i::unpack(color); + else + return texturePixels[uvoffset * 4].load_vec4ub(true); +} + +void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying) +{ + SSAInt ufrac = varying[0]; + SSAInt vfrac = varying[1]; + + SSAInt upos = ((ufrac >> 16) * textureWidth) >> 16; + SSAInt vpos = ((vfrac >> 16) * textureHeight) >> 16; + SSAInt uvoffset = upos * textureHeight + vpos; + + if (truecolor) { - if (truecolor) + SSAVec4i fg; + SSAVec4i bg = buffer.load_vec4ub(false); + SSAInt alpha, inv_alpha; + SSAVec4i output; + + switch (blendmode) { - buffer.store_vec4ub(SSAVec4i::unpack(solidcolor)); - } - else - { - //buffer.store(solidcolor); + default: + case TriBlendMode::Copy: + fg = Sample(uvoffset); + output = blend_copy(shade_bgra_simple(fg, currentlight)); break; + case TriBlendMode::AlphaBlend: + fg = Sample(uvoffset); + output = blend_alpha_blend(shade_bgra_simple(fg, currentlight), bg); break; + case TriBlendMode::AddSolid: + fg = Sample(uvoffset); + output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, destalpha); break; + case TriBlendMode::Add: + fg = Sample(uvoffset); + output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break; + case TriBlendMode::Sub: + fg = Sample(uvoffset); + output = blend_sub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break; + case TriBlendMode::RevSub: + fg = Sample(uvoffset); + output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); break; + case TriBlendMode::Shaded: + fg = Sample(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); + break; + case TriBlendMode::TranslateCopy: + fg = TranslateSample(uvoffset); + output = blend_copy(shade_bgra_simple(fg, currentlight)); + break; + case TriBlendMode::TranslateAdd: + fg = TranslateSample(uvoffset); + output = blend_add(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); + break; + case TriBlendMode::TranslateSub: + fg = TranslateSample(uvoffset); + output = blend_sub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); + break; + case TriBlendMode::TranslateRevSub: + fg = TranslateSample(uvoffset); + output = blend_revsub(shade_bgra_simple(fg, currentlight), bg, srcalpha, calc_blend_bgalpha(fg, destalpha)); + break; } - if (variant != TriDrawVariant::FillSubsector) - subsectorbuffer.store(subsectorDepth); + buffer.store_vec4ub(output); } else { - SSAInt ufrac = varying[0]; - SSAInt vfrac = varying[1]; - - SSAInt upos = ((ufrac >> 16) * textureWidth) >> 16; - SSAInt vpos = ((vfrac >> 16) * textureHeight) >> 16; - SSAInt uvoffset = upos * textureHeight + vpos; - - if (truecolor) + if (variant == TriDrawVariant::FillNormal || variant == TriDrawVariant::FillSubsector || variant == TriDrawVariant::FuzzSubsector) { - if (variant == TriDrawVariant::DrawMasked || variant == TriDrawVariant::DrawSubsector) - { - SSAVec4i fg = texturePixels[uvoffset * 4].load_vec4ub(true); - SSAInt fg_alpha = fg[3]; - fg = (fg * currentlight) >> 8; - fg.insert(3, fg_alpha); - - SSAIfBlock branch_transparency; - branch_transparency.if_block(fg_alpha > SSAInt(127)); - { - buffer.store_vec4ub(fg); - if (variant != TriDrawVariant::DrawSubsector) - subsectorbuffer.store(subsectorDepth); - } - branch_transparency.end_block(); - } - else if (variant == TriDrawVariant::DrawShadedSubsector) - { - SSAInt alpha = texturePixels[uvoffset * 4].load(true).zext_int(); - alpha = alpha + (alpha >> 7); // // 255 -> 256 - SSAInt inv_alpha = 256 - alpha; - - SSAVec4i bgcolor = buffer.load_vec4ub(false); - buffer.store_vec4ub(blend_add(shade_bgra_simple(SSAVec4i::unpack(solidcolor), currentlight), bgcolor, alpha, inv_alpha)); - } - else - { - SSAVec4i fg = texturePixels[uvoffset * 4].load_vec4ub(true); - SSAInt fg_alpha = fg[3]; - fg = (fg * currentlight) >> 8; - fg.insert(3, fg_alpha); - - buffer.store_vec4ub(fg); - subsectorbuffer.store(subsectorDepth); - } + buffer.store(color.trunc_ubyte()); } else { - SSAUByte palindex = texturePixels[uvoffset].load(true); - - if (variant == TriDrawVariant::DrawMasked || variant == TriDrawVariant::DrawSubsector) - { - SSAIfBlock branch_transparency; - branch_transparency.if_block(!(palindex.zext_int() == SSAInt(0))); - { - buffer.store(palindex); - if (variant != TriDrawVariant::DrawSubsector) - subsectorbuffer.store(subsectorDepth); - } - branch_transparency.end_block(); - } - else - { - buffer.store(palindex); - subsectorbuffer.store(subsectorDepth); - } + SSAUByte fg = texturePixels[uvoffset].load(true); + buffer.store(fg); } } + + if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector && variant != TriDrawVariant::FuzzSubsector) + subsectorbuffer.store(subsectorDepth); } void DrawTriangleCodegen::SetStencilBlock(SSAInt block) @@ -582,7 +595,7 @@ SSABool DrawTriangleCodegen::StencilIsSingleValue() return (StencilBlockMask.load(false) & SSAInt(0xffffff00)) == SSAInt(0xffffff00); } -void DrawTriangleCodegen::LoadArgs(TriDrawVariant variant, bool truecolor, SSAValue args, SSAValue thread_data) +void DrawTriangleCodegen::LoadArgs(SSAValue args, SSAValue thread_data) { dest = args[0][0].load(true); pitch = args[0][1].load(true); @@ -596,7 +609,7 @@ void DrawTriangleCodegen::LoadArgs(TriDrawVariant variant, bool truecolor, SSAVa texturePixels = args[0][9].load(true); textureWidth = args[0][10].load(true); textureHeight = args[0][11].load(true); - solidcolor = args[0][12].load(true); + translation = args[0][12].load(true); LoadUniforms(args[0][13].load(true)); stencilValues = args[0][14].load(true); stencilMasks = args[0][15].load(true); @@ -625,17 +638,20 @@ void DrawTriangleCodegen::LoadUniforms(SSAValue uniforms) { light = uniforms[0][0].load(true); subsectorDepth = uniforms[0][1].load(true); + color = uniforms[0][2].load(true); + srcalpha = uniforms[0][3].load(true); + destalpha = uniforms[0][4].load(true); - SSAShort light_alpha = uniforms[0][2].load(true); - SSAShort light_red = uniforms[0][3].load(true); - SSAShort light_green = uniforms[0][4].load(true); - SSAShort light_blue = uniforms[0][5].load(true); - SSAShort fade_alpha = uniforms[0][6].load(true); - SSAShort fade_red = uniforms[0][7].load(true); - SSAShort fade_green = uniforms[0][8].load(true); - SSAShort fade_blue = uniforms[0][9].load(true); - SSAShort desaturate = uniforms[0][10].load(true); - SSAInt flags = uniforms[0][11].load(true); + SSAShort light_alpha = uniforms[0][5].load(true); + SSAShort light_red = uniforms[0][6].load(true); + SSAShort light_green = uniforms[0][7].load(true); + SSAShort light_blue = uniforms[0][8].load(true); + SSAShort fade_alpha = uniforms[0][9].load(true); + SSAShort fade_red = uniforms[0][10].load(true); + SSAShort fade_green = uniforms[0][11].load(true); + SSAShort fade_blue = uniforms[0][12].load(true); + SSAShort desaturate = uniforms[0][13].load(true); + SSAInt flags = uniforms[0][14].load(true); shade_constants.light = SSAVec4i(light_blue.zext_int(), light_green.zext_int(), light_red.zext_int(), light_alpha.zext_int()); shade_constants.fade = SSAVec4i(fade_blue.zext_int(), fade_green.zext_int(), fade_red.zext_int(), fade_alpha.zext_int()); shade_constants.desaturate = desaturate.zext_int(); diff --git a/src/r_compiler/fixedfunction/drawtrianglecodegen.h b/src/r_compiler/fixedfunction/drawtrianglecodegen.h index 8452b250f..d5539ef22 100644 --- a/src/r_compiler/fixedfunction/drawtrianglecodegen.h +++ b/src/r_compiler/fixedfunction/drawtrianglecodegen.h @@ -33,20 +33,23 @@ struct SSATriVertex class DrawTriangleCodegen : public DrawerCodegen { public: - void Generate(TriDrawVariant variant, bool truecolor, SSAValue args, SSAValue thread_data); + void Generate(TriDrawVariant variant, TriBlendMode blendmode, bool truecolor, SSAValue args, SSAValue thread_data); private: - void LoadArgs(TriDrawVariant variant, bool truecolor, SSAValue args, SSAValue thread_data); + void LoadArgs(SSAValue args, SSAValue thread_data); SSATriVertex LoadTriVertex(SSAValue v); void LoadUniforms(SSAValue uniforms); - void Setup(TriDrawVariant variant, bool truecolor); + void Setup(); SSAInt FloatTo28_4(SSAFloat v); - void LoopBlockY(TriDrawVariant variant, bool truecolor); - void LoopBlockX(TriDrawVariant variant, bool truecolor); - void LoopFullBlock(TriDrawVariant variant, bool truecolor); - void LoopPartialBlock(TriDrawVariant variant, bool truecolor); + void LoopBlockY(); + void LoopBlockX(); + void LoopFullBlock(); + void LoopPartialBlock(); - void ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying, TriDrawVariant variant, bool truecolor); + void ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying); + + SSAVec4i TranslateSample(SSAInt uvoffset); + SSAVec4i Sample(SSAInt uvoffset); void SetStencilBlock(SSAInt block); void StencilSet(SSAInt x, SSAInt y, SSAUByte value); @@ -58,6 +61,10 @@ private: SSAFloat gradx(SSAFloat x0, SSAFloat y0, SSAFloat x1, SSAFloat y1, SSAFloat x2, SSAFloat y2, SSAFloat c0, SSAFloat c1, SSAFloat c2); SSAFloat grady(SSAFloat x0, SSAFloat y0, SSAFloat x1, SSAFloat y1, SSAFloat x2, SSAFloat y2, SSAFloat c0, SSAFloat c1, SSAFloat c2); + TriDrawVariant variant; + TriBlendMode blendmode; + bool truecolor; + SSAStack stack_C1, stack_C2, stack_C3; SSAStack stack_y; SSAStack stack_dest; @@ -82,7 +89,8 @@ private: SSAUBytePtr texturePixels; SSAInt textureWidth; SSAInt textureHeight; - SSAInt solidcolor; + SSAUBytePtr translation; + SSAInt color, srcalpha, destalpha; SSAInt light; SSAInt subsectorDepth; diff --git a/src/r_compiler/llvmdrawers.cpp b/src/r_compiler/llvmdrawers.cpp index 458d90d1a..d9a43d3d7 100644 --- a/src/r_compiler/llvmdrawers.cpp +++ b/src/r_compiler/llvmdrawers.cpp @@ -57,7 +57,7 @@ public: void StopLogFatalErrors(); template - Func *GetProcAddress(const char *name) { return reinterpret_cast(PointerToFunction(name)); } + Func *GetProcAddress(const std::string &name) { return reinterpret_cast(PointerToFunction(name.c_str())); } llvm::LLVMContext &context() { return *mContext; } llvm::Module *module() { return mModule.get(); } @@ -82,7 +82,7 @@ private: void CodegenDrawSpan(const char *name, DrawSpanVariant variant); void CodegenDrawWall(const char *name, DrawWallVariant variant, int columns); void CodegenDrawSky(const char *name, DrawSkyVariant variant, int columns); - void CodegenDrawTriangle(const char *name, TriDrawVariant variant, bool truecolor); + void CodegenDrawTriangle(const std::string &name, TriDrawVariant variant, TriBlendMode blendmode, bool truecolor); static llvm::Type *GetDrawColumnArgsStruct(llvm::LLVMContext &context); static llvm::Type *GetDrawSpanArgsStruct(llvm::LLVMContext &context); @@ -186,17 +186,18 @@ LLVMDrawersImpl::LLVMDrawersImpl() CodegenDrawSky("DrawSky4", DrawSkyVariant::Single, 4); CodegenDrawSky("DrawDoubleSky1", DrawSkyVariant::Double, 1); CodegenDrawSky("DrawDoubleSky4", DrawSkyVariant::Double, 4); - CodegenDrawTriangle("TriDraw8", TriDrawVariant::Draw, false); - CodegenDrawTriangle("TriDraw32", TriDrawVariant::Draw, true); - CodegenDrawTriangle("TriDrawSubsector8", TriDrawVariant::DrawSubsector, false); - CodegenDrawTriangle("TriDrawSubsector32", TriDrawVariant::DrawSubsector, true); - CodegenDrawTriangle("TriDrawShadedSubsector8", TriDrawVariant::DrawShadedSubsector, false); - CodegenDrawTriangle("TriDrawShadedSubsector32", TriDrawVariant::DrawShadedSubsector, true); - CodegenDrawTriangle("TriFillSubsector8", TriDrawVariant::FillSubsector, false); - CodegenDrawTriangle("TriFillSubsector32", TriDrawVariant::FillSubsector, true); - CodegenDrawTriangle("TriFill8", TriDrawVariant::Fill, false); - CodegenDrawTriangle("TriFill32", TriDrawVariant::Fill, true); - CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, false); + for (int i = 0; i < NumTriBlendModes(); i++) + { + CodegenDrawTriangle("TriDraw8_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, false); + CodegenDrawTriangle("TriDraw32_" + std::to_string(i), TriDrawVariant::DrawNormal, (TriBlendMode)i, true); + CodegenDrawTriangle("TriFill8_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, false); + CodegenDrawTriangle("TriFill32_" + std::to_string(i), TriDrawVariant::FillNormal, (TriBlendMode)i, true); + CodegenDrawTriangle("TriDrawSubsector8_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, false); + CodegenDrawTriangle("TriDrawSubsector32_" + std::to_string(i), TriDrawVariant::DrawSubsector, (TriBlendMode)i, true); + CodegenDrawTriangle("TriFillSubsector8_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, false); + CodegenDrawTriangle("TriFillSubsector32_" + std::to_string(i), TriDrawVariant::FillSubsector, (TriBlendMode)i, true); + } + CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, TriBlendMode::Copy, false); mProgram.CreateEE(); @@ -262,16 +263,17 @@ LLVMDrawersImpl::LLVMDrawersImpl() DrawSky4 = mProgram.GetProcAddress("DrawSky4"); DrawDoubleSky1 = mProgram.GetProcAddress("DrawDoubleSky1"); DrawDoubleSky4 = mProgram.GetProcAddress("DrawDoubleSky4"); - TriDraw8 = mProgram.GetProcAddress("TriDraw8"); - TriDraw32 = mProgram.GetProcAddress("TriDraw32"); - TriDrawSubsector8 = mProgram.GetProcAddress("TriDrawSubsector8"); - TriDrawSubsector32 = mProgram.GetProcAddress("TriDrawSubsector32"); - TriDrawShadedSubsector8 = mProgram.GetProcAddress("TriDrawShadedSubsector8"); - TriDrawShadedSubsector32 = mProgram.GetProcAddress("TriDrawShadedSubsector32"); - TriFillSubsector8 = mProgram.GetProcAddress("TriFillSubsector8"); - TriFillSubsector32 = mProgram.GetProcAddress("TriFillSubsector32"); - TriFill8 = mProgram.GetProcAddress("TriFill8"); - TriFill32 = mProgram.GetProcAddress("TriFill32"); + for (int i = 0; i < NumTriBlendModes(); i++) + { + TriDrawNormal8.push_back(mProgram.GetProcAddress("TriDraw8_" + std::to_string(i))); + TriDrawNormal32.push_back(mProgram.GetProcAddress("TriDraw32_" + std::to_string(i))); + TriFillNormal8.push_back(mProgram.GetProcAddress("TriFill8_" + std::to_string(i))); + TriFillNormal32.push_back(mProgram.GetProcAddress("TriFill32_" + std::to_string(i))); + TriDrawSubsector8.push_back(mProgram.GetProcAddress("TriDrawSubsector8_" + std::to_string(i))); + TriDrawSubsector32.push_back(mProgram.GetProcAddress("TriDrawSubsector32_" + std::to_string(i))); + TriFillSubsector8.push_back(mProgram.GetProcAddress("TriFillSubsector8_" + std::to_string(i))); + TriFillSubsector32.push_back(mProgram.GetProcAddress("TriFillSubsector32_" + std::to_string(i))); + } TriStencil = mProgram.GetProcAddress("TriStencil"); #if 0 @@ -383,7 +385,7 @@ void LLVMDrawersImpl::CodegenDrawSky(const char *name, DrawSkyVariant variant, i I_FatalError("verifyFunction failed for CodegenDrawSky()"); } -void LLVMDrawersImpl::CodegenDrawTriangle(const char *name, TriDrawVariant variant, bool truecolor) +void LLVMDrawersImpl::CodegenDrawTriangle(const std::string &name, TriDrawVariant variant, TriBlendMode blendmode, bool truecolor) { llvm::IRBuilder<> builder(mProgram.context()); SSAScope ssa_scope(&mProgram.context(), mProgram.module(), &builder); @@ -394,12 +396,12 @@ void LLVMDrawersImpl::CodegenDrawTriangle(const char *name, TriDrawVariant varia function.create_public(); DrawTriangleCodegen codegen; - codegen.Generate(variant, truecolor, function.parameter(0), function.parameter(1)); + codegen.Generate(variant, blendmode, truecolor, function.parameter(0), function.parameter(1)); builder.CreateRetVoid(); if (llvm::verifyFunction(*function.func)) - I_FatalError("verifyFunction failed for CodegenDrawTriangle()"); + I_FatalError("verifyFunction failed for CodegenDrawTriangle(%d, %d, %d)", (int)variant, (int)blendmode, (int)truecolor); } llvm::Type *LLVMDrawersImpl::GetDrawColumnArgsStruct(llvm::LLVMContext &context) @@ -529,6 +531,9 @@ llvm::Type *LLVMDrawersImpl::GetTriUniformsStruct(llvm::LLVMContext &context) std::vector elements; elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t light; elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t subsectorDepth; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t color; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t srcalpha; + elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t destalpha; elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_alpha; elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_red; elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t light_green; @@ -558,7 +563,7 @@ llvm::Type *LLVMDrawersImpl::GetTriDrawTriangleArgs(llvm::LLVMContext &context) elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *texturePixels; elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureWidth; elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t textureHeight; - elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t solidcolor; + elements.push_back(llvm::Type::getInt8PtrTy(context)); // const uint8_t *translation; elements.push_back(GetTriUniformsStruct(context)); // const TriUniforms *uniforms; elements.push_back(llvm::Type::getInt8PtrTy(context)); // uint8_t *stencilValues; elements.push_back(llvm::Type::getInt32PtrTy(context)); // uint32_t *stencilMasks; diff --git a/src/r_compiler/llvmdrawers.h b/src/r_compiler/llvmdrawers.h index 9c3a3e45f..3b1396283 100644 --- a/src/r_compiler/llvmdrawers.h +++ b/src/r_compiler/llvmdrawers.h @@ -215,7 +215,9 @@ struct TriUniforms { uint32_t light; uint32_t subsectorDepth; - + uint32_t color; + uint32_t srcalpha; + uint32_t destalpha; uint16_t light_alpha; uint16_t light_red; uint16_t light_green; @@ -250,7 +252,7 @@ struct TriDrawTriangleArgs const uint8_t *texturePixels; uint32_t textureWidth; uint32_t textureHeight; - uint32_t solidcolor; + const uint8_t *translation; const TriUniforms *uniforms; uint8_t *stencilValues; uint32_t *stencilMasks; @@ -262,15 +264,31 @@ struct TriDrawTriangleArgs enum class TriDrawVariant { - Draw, - DrawMasked, - Fill, + DrawNormal, + FillNormal, DrawSubsector, - DrawShadedSubsector, FillSubsector, - Stencil, + FuzzSubsector, + Stencil }; +enum class TriBlendMode +{ + Copy, // blend_copy(shade(fg)) + AlphaBlend, // blend_alpha_blend(shade(fg), bg) + AddSolid, // blend_add(shade(fg), bg, srcalpha, destalpha) + 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) + TranslateCopy, // blend_copy(shade(translate(fg))) + 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)) +}; + +inline int NumTriBlendModes() { return (int)TriBlendMode::TranslateRevSub + 1; } + class LLVMDrawers { public: @@ -346,16 +364,14 @@ public: void(*DrawDoubleSky1)(const DrawSkyArgs *, const WorkerThreadData *) = nullptr; void(*DrawDoubleSky4)(const DrawSkyArgs *, const WorkerThreadData *) = nullptr; - void(*TriDraw8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - void(*TriDraw32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - void(*TriDrawSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - void(*TriDrawSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - void(*TriDrawShadedSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - void(*TriDrawShadedSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - void(*TriFillSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - void(*TriFillSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - void(*TriFill8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; - void(*TriFill32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; + std::vector TriDrawNormal8; + std::vector TriDrawNormal32; + std::vector TriFillNormal8; + std::vector TriFillNormal32; + std::vector TriDrawSubsector8; + std::vector TriDrawSubsector32; + std::vector TriFillSubsector8; + std::vector TriFillSubsector32; void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr; private: diff --git a/src/r_poly_decal.cpp b/src/r_poly_decal.cpp index 0c6c427a8..5641bfcd1 100644 --- a/src/r_poly_decal.cpp +++ b/src/r_poly_decal.cpp @@ -141,6 +141,7 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co uniforms.flags = 0; } uniforms.subsectorDepth = subsectorDepth; + uniforms.color = decal->AlphaColor; PolyDrawArgs args; args.uniforms = uniforms; @@ -151,7 +152,6 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co args.stenciltestvalue = 0; args.stencilwritevalue = 1; args.SetTexture(tex); - args.solidcolor = decal->AlphaColor; //mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor); - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawShadedSubsector); + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::Shaded); } diff --git a/src/r_poly_particle.cpp b/src/r_poly_particle.cpp index be8030071..e5797a108 100644 --- a/src/r_poly_particle.cpp +++ b/src/r_poly_particle.cpp @@ -83,8 +83,8 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *partic uniforms.flags = 0; } uniforms.subsectorDepth = subsectorDepth; - uint32_t alpha = particle->trans; + uniforms.color = (alpha << 24) | (particle->color & 0xffffff); PolyDrawArgs args; args.uniforms = uniforms; @@ -94,6 +94,5 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *partic args.ccw = true; args.stenciltestvalue = 0; args.stencilwritevalue = 1; - args.solidcolor = (alpha << 24) | (particle->color & 0xffffff); - PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector); + PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector, TriBlendMode::AlphaBlend); } diff --git a/src/r_poly_plane.cpp b/src/r_poly_plane.cpp index 9a425598b..9005e32f1 100644 --- a/src/r_poly_plane.cpp +++ b/src/r_poly_plane.cpp @@ -140,8 +140,8 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *s args.stenciltestvalue = 0; args.stencilwritevalue = 1; args.SetTexture(tex); - PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); - PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy); + PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); } void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uint32_t subsectorDepth, bool ceiling, double skyHeight) @@ -235,13 +235,13 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin if (!isSky) { args.SetTexture(tex); - PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); - PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy); + PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); } else { args.stencilwritevalue = 255; - PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); + PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); for (uint32_t i = 0; i < sub->numlines; i++) { @@ -309,7 +309,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin args.vinput = wallvert; args.vcount = 4; - PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); + PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); } } } diff --git a/src/r_poly_sky.cpp b/src/r_poly_sky.cpp index fc6963dbb..b0b06f262 100644 --- a/src/r_poly_sky.cpp +++ b/src/r_poly_sky.cpp @@ -79,7 +79,7 @@ void PolySkyDome::RenderRow(PolyDrawArgs &args, int row) args.vcount = mPrimStart[row + 1] - mPrimStart[row]; args.mode = TriangleDrawMode::Strip; args.ccw = false; - PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy); } void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap) @@ -92,8 +92,8 @@ void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int ro args.vcount = mPrimStart[row + 1] - mPrimStart[row]; args.mode = TriangleDrawMode::Fan; args.ccw = bottomCap; - args.solidcolor = solid; - PolyTriangleDrawer::draw(args, TriDrawVariant::Fill); + args.uniforms.color = solid; + PolyTriangleDrawer::draw(args, TriDrawVariant::FillNormal, TriBlendMode::Copy); } void PolySkyDome::CreateDome() diff --git a/src/r_poly_sprite.cpp b/src/r_poly_sprite.cpp index e1c6fcc14..43bdf40af 100644 --- a/src/r_poly_sprite.cpp +++ b/src/r_poly_sprite.cpp @@ -136,7 +136,7 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, AActor *thing, subse args.stenciltestvalue = 0; args.stencilwritevalue = 1; args.SetTexture(tex); - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector); + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend); } bool RenderPolySprite::IsThingCulled(AActor *thing) diff --git a/src/r_poly_triangle.cpp b/src/r_poly_triangle.cpp index d661fe0d7..07a4566dd 100644 --- a/src/r_poly_triangle.cpp +++ b/src/r_poly_triangle.cpp @@ -72,44 +72,32 @@ void PolyTriangleDrawer::set_viewport(int x, int y, int width, int height, DCanv dest_height = clamp(viewport_y + viewport_height, 0, dest_height - offsety); } -void PolyTriangleDrawer::draw(const PolyDrawArgs &args, TriDrawVariant variant) +void PolyTriangleDrawer::draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode) { if (dest_bgra) - DrawerCommandQueue::QueueCommand(args, variant); + DrawerCommandQueue::QueueCommand(args, variant, blendmode); else - draw_arrays(args, variant, nullptr); + draw_arrays(args, variant, blendmode, nullptr); } -void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVariant variant, WorkerThreadData *thread) +void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVariant variant, TriBlendMode blendmode, WorkerThreadData *thread) { if (drawargs.vcount < 3) return; auto llvm = LLVMDrawers::Instance(); void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *); -#if 1 + int bmode = (int)blendmode; switch (variant) { default: - case TriDrawVariant::Draw: drawfunc = dest_bgra ? llvm->TriDraw32: llvm->TriDraw8; break; - case TriDrawVariant::Fill: drawfunc = dest_bgra ? llvm->TriFill32 : llvm->TriFill8; break; - case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? llvm->TriDrawSubsector32 : llvm->TriDrawSubsector8; break; - case TriDrawVariant::DrawShadedSubsector: drawfunc = dest_bgra ? llvm->TriDrawShadedSubsector32 : llvm->TriDrawShadedSubsector8; break; - case TriDrawVariant::FillSubsector: drawfunc = dest_bgra ? llvm->TriFillSubsector32 : llvm->TriFillSubsector8; break; + case TriDrawVariant::DrawNormal: drawfunc = dest_bgra ? llvm->TriDrawNormal32[bmode] : llvm->TriDrawNormal8[bmode]; break; + case TriDrawVariant::FillNormal: drawfunc = dest_bgra ? llvm->TriFillNormal32[bmode] : llvm->TriFillNormal8[bmode]; break; + case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? llvm->TriDrawSubsector32[bmode] : llvm->TriDrawSubsector8[bmode]; break; + case TriDrawVariant::FuzzSubsector: + case TriDrawVariant::FillSubsector: drawfunc = dest_bgra ? llvm->TriFillSubsector32[bmode] : llvm->TriFillSubsector8[bmode]; break; case TriDrawVariant::Stencil: drawfunc = llvm->TriStencil; break; } -#else - switch (variant) - { - default: - case TriDrawVariant::Draw: drawfunc = dest_bgra ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::draw; break; - case TriDrawVariant::FillSubsector: - case TriDrawVariant::Fill: drawfunc = dest_bgra ? ScreenPolyTriangleDrawer::fill32 : ScreenPolyTriangleDrawer::fill; break; - case TriDrawVariant::DrawShadedSubsector: - case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? ScreenPolyTriangleDrawer::drawsubsector32 : llvm->TriDrawSubsector8; break; - case TriDrawVariant::Stencil: drawfunc = ScreenPolyTriangleDrawer::stencil; break; - } -#endif TriDrawTriangleArgs args; args.dest = dest; @@ -121,7 +109,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian args.texturePixels = drawargs.texturePixels; args.textureWidth = drawargs.textureWidth; args.textureHeight = drawargs.textureHeight; - args.solidcolor = drawargs.solidcolor; + args.translation = drawargs.translation; args.uniforms = &drawargs.uniforms; args.stencilTestValue = drawargs.stenciltestvalue; args.stencilWriteValue = drawargs.stencilwritevalue; @@ -336,6 +324,7 @@ void PolyTriangleDrawer::clipedge(const TriVertex *verts, TriVertex *clippedvert ///////////////////////////////////////////////////////////////////////////// +#if 0 void ScreenPolyTriangleDrawer::draw(const TriDrawTriangleArgs *args, WorkerThreadData *thread) { uint8_t *dest = args->dest; @@ -1641,11 +1630,12 @@ float ScreenPolyTriangleDrawer::grady(float x0, float y0, float x1, float y1, fl float bottom = -((x1 - x2) * (y0 - y2) - (x0 - x2) * (y1 - y2)); return top / bottom; } +#endif ///////////////////////////////////////////////////////////////////////////// -DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant) - : args(args), variant(variant) +DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode) + : args(args), variant(variant), blendmode(blendmode) { } @@ -1658,7 +1648,7 @@ void DrawPolyTrianglesCommand::Execute(DrawerThread *thread) thread_data.pass_end_y = thread->pass_end_y; thread_data.temp = thread->dc_temp_rgba; - PolyTriangleDrawer::draw_arrays(args, variant, &thread_data); + PolyTriangleDrawer::draw_arrays(args, variant, blendmode, &thread_data); } FString DrawPolyTrianglesCommand::DebugInfo() diff --git a/src/r_poly_triangle.h b/src/r_poly_triangle.h index 8f2fcf3d0..cc8558985 100644 --- a/src/r_poly_triangle.h +++ b/src/r_poly_triangle.h @@ -39,7 +39,7 @@ public: const uint8_t *texturePixels = nullptr; int textureWidth = 0; int textureHeight = 0; - uint32_t solidcolor = 0; + const uint8_t *translation = nullptr; uint8_t stenciltestvalue = 0; uint8_t stencilwritevalue = 0; @@ -58,11 +58,11 @@ class PolyTriangleDrawer { public: static void set_viewport(int x, int y, int width, int height, DCanvas *canvas); - static void draw(const PolyDrawArgs &args, TriDrawVariant variant); + static void draw(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode); private: static TriVertex shade_vertex(const TriUniforms &uniforms, TriVertex v); - static void draw_arrays(const PolyDrawArgs &args, TriDrawVariant variant, WorkerThreadData *thread); + static void draw_arrays(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode, WorkerThreadData *thread); static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, TriDrawTriangleArgs *args, WorkerThreadData *thread, void(*drawfunc)(const TriDrawTriangleArgs *, WorkerThreadData *)); static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2); static void clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert); @@ -188,6 +188,7 @@ private: std::vector masks; }; +#if 0 class ScreenPolyTriangleDrawer { public: @@ -204,11 +205,12 @@ private: static float gradx(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2); static float grady(float x0, float y0, float x1, float y1, float x2, float y2, float c0, float c1, float c2); }; +#endif class DrawPolyTrianglesCommand : public DrawerCommand { public: - DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant); + DrawPolyTrianglesCommand(const PolyDrawArgs &args, TriDrawVariant variant, TriBlendMode blendmode); void Execute(DrawerThread *thread) override; FString DebugInfo() override; @@ -216,6 +218,7 @@ public: private: PolyDrawArgs args; TriDrawVariant variant; + TriBlendMode blendmode; }; #endif diff --git a/src/r_poly_wall.cpp b/src/r_poly_wall.cpp index 1f1908ab4..e8bad52a7 100644 --- a/src/r_poly_wall.cpp +++ b/src/r_poly_wall.cpp @@ -193,12 +193,12 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip) if (!Masked) { - PolyTriangleDrawer::draw(args, TriDrawVariant::Draw); - PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil); + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawNormal, TriBlendMode::Copy); + PolyTriangleDrawer::draw(args, TriDrawVariant::Stencil, TriBlendMode::Copy); } else { - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector); + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend); } RenderPolyDecal::RenderWallDecals(worldToClip, Line, SubsectorDepth); diff --git a/src/r_poly_wallsprite.cpp b/src/r_poly_wallsprite.cpp index e2d1a9e86..ccebe5f0e 100644 --- a/src/r_poly_wallsprite.cpp +++ b/src/r_poly_wallsprite.cpp @@ -121,5 +121,5 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, AActor *thing, s args.stenciltestvalue = 0; args.stencilwritevalue = 1; args.SetTexture(tex); - PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector); + PolyTriangleDrawer::draw(args, TriDrawVariant::DrawSubsector, TriBlendMode::AlphaBlend); }