Added blending modes to triangle codegen

This commit is contained in:
Magnus Norddahl 2016-11-19 02:53:32 +01:00
parent 5d6ceb868e
commit 272fe7f754
13 changed files with 242 additions and 205 deletions

View file

@ -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();

View file

@ -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<SSAInt> stack_C1, stack_C2, stack_C3;
SSAStack<SSAInt> stack_y;
SSAStack<SSAUBytePtr> 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;

View file

@ -57,7 +57,7 @@ public:
void StopLogFatalErrors();
template<typename Func>
Func *GetProcAddress(const char *name) { return reinterpret_cast<Func*>(PointerToFunction(name)); }
Func *GetProcAddress(const std::string &name) { return reinterpret_cast<Func*>(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<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawSky4");
DrawDoubleSky1 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky1");
DrawDoubleSky4 = mProgram.GetProcAddress<void(const DrawSkyArgs *, const WorkerThreadData *)>("DrawDoubleSky4");
TriDraw8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw8");
TriDraw32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32");
TriDrawSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8");
TriDrawSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32");
TriDrawShadedSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawShadedSubsector8");
TriDrawShadedSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawShadedSubsector32");
TriFillSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector8");
TriFillSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32");
TriFill8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8");
TriFill32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32");
for (int i = 0; i < NumTriBlendModes(); i++)
{
TriDrawNormal8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw8_" + std::to_string(i)));
TriDrawNormal32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32_" + std::to_string(i)));
TriFillNormal8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8_" + std::to_string(i)));
TriFillNormal32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32_" + std::to_string(i)));
TriDrawSubsector8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8_" + std::to_string(i)));
TriDrawSubsector32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32_" + std::to_string(i)));
TriFillSubsector8.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector8_" + std::to_string(i)));
TriFillSubsector32.push_back(mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32_" + std::to_string(i)));
}
TriStencil = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("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<llvm::Type *> 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;

View file

@ -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<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawNormal8;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawNormal32;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillNormal8;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillNormal32;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawSubsector8;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriDrawSubsector32;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector8;
std::vector<void(*)(const TriDrawTriangleArgs *, WorkerThreadData *)> TriFillSubsector32;
void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
private:

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}
}
}

View file

@ -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()

View file

@ -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)

View file

@ -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<DrawPolyTrianglesCommand>(args, variant);
DrawerCommandQueue::QueueCommand<DrawPolyTrianglesCommand>(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()

View file

@ -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<uint32_t> 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

View file

@ -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);

View file

@ -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);
}