From 80805656ed75cb5425239fc8b76973178d8dd4d7 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Fri, 31 May 2019 06:43:24 +0200 Subject: [PATCH] - implement alpha test --- .../polyrenderer/drawers/poly_triangle.cpp | 2 +- .../polyrenderer/drawers/poly_triangle.h | 1 + .../polyrenderer/drawers/screen_triangle.cpp | 719 +++--------------- .../polyrenderer/drawers/screen_triangle.h | 9 +- 4 files changed, 99 insertions(+), 632 deletions(-) diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.cpp b/src/rendering/polyrenderer/drawers/poly_triangle.cpp index 7ca3628cc..022ca963f 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/poly_triangle.cpp @@ -347,7 +347,7 @@ void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPu auto style = RenderStyle; if (style.BlendOp == STYLEOP_Add && style.SrcAlpha == STYLEALPHA_One && style.DestAlpha == STYLEALPHA_Zero) { - drawargs.SetStyle(AlphaTest ? TriBlendMode::Normal : TriBlendMode::Opaque); + drawargs.SetStyle(AlphaTest ? TriBlendMode::AlphaTest : TriBlendMode::Opaque); } else if (style.BlendOp == STYLEOP_Add && style.SrcAlpha == STYLEALPHA_Src && style.DestAlpha == STYLEALPHA_InvSrc) { diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.h b/src/rendering/polyrenderer/drawers/poly_triangle.h index ed7d0aaea..f3ffaee7c 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.h +++ b/src/rendering/polyrenderer/drawers/poly_triangle.h @@ -205,6 +205,7 @@ public: uint16_t lightarray[MAXWIDTH]; uint32_t dynlights[MAXWIDTH]; float depthvalues[MAXWIDTH]; + uint8_t alphatestbuffer[MAXWIDTH]; static PolyTriangleThreadData *Get(DrawerThread *thread); diff --git a/src/rendering/polyrenderer/drawers/screen_triangle.cpp b/src/rendering/polyrenderer/drawers/screen_triangle.cpp index 664bd7137..23838bb9c 100644 --- a/src/rendering/polyrenderer/drawers/screen_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/screen_triangle.cpp @@ -189,6 +189,9 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa uint8_t *stencilLine; int pitch; + bool alphatest = thread->AlphaTest; + uint8_t *alphatestbuf = thread->alphatestbuffer; + if (OptT::Flags & SWTRI_WriteColor) { int bmode = (int)args->uniforms->BlendMode(); @@ -261,14 +264,14 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa stencilLine[x + 2] == stencilTestValue && stencilLine[x + 3] == stencilTestValue) { - if (OptT::Flags & SWTRI_WriteDepth) + if (!alphatest && (OptT::Flags & SWTRI_WriteDepth)) _mm_storeu_ps(zbufferLine + x, mposXW); x += 4; } while (zbufferLine[x] >= depthvalues[x] && stencilLine[x] == stencilTestValue && x < xend) { - if (OptT::Flags & SWTRI_WriteDepth) + if (!alphatest && (OptT::Flags & SWTRI_WriteDepth)) zbufferLine[x] = depthvalues[x]; x++; } @@ -279,14 +282,14 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa __m128 mposXW; while (x < xendsse && _mm_movemask_ps(_mm_cmpge_ps(_mm_loadu_ps(zbufferLine + x), mposXW = _mm_loadu_ps(depthvalues + x))) == 15) { - if (OptT::Flags & SWTRI_WriteDepth) + if (!alphatest && (OptT::Flags & SWTRI_WriteDepth)) _mm_storeu_ps(zbufferLine + x, mposXW); x += 4; } while (zbufferLine[x] >= depthvalues[x] && x < xend) { - if (OptT::Flags & SWTRI_WriteDepth) + if (!alphatest && (OptT::Flags & SWTRI_WriteDepth)) zbufferLine[x] = depthvalues[x]; x++; } @@ -312,25 +315,48 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa if (OptT::Flags & SWTRI_WriteColor) drawfunc(y, xstart, x, args, thread); - if (OptT::Flags & SWTRI_WriteStencil) + if (alphatest) { - int i = xstart; - int xendsse = xstart + ((x - xstart) / 16); - while (i < xendsse) + if (OptT::Flags & SWTRI_WriteStencil) { - _mm_storeu_si128((__m128i*)&stencilLine[i], _mm_set1_epi8(stencilWriteValue)); - i += 16; + for (int i = xstart; i < x; i++) + { + if (alphatestbuf[i] > 127) + stencilLine[i++] = stencilWriteValue; + } } - while (i < x) - stencilLine[i++] = stencilWriteValue; - } - - if (!(OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_WriteDepth)) - { - for (int i = xstart; i < x; i++) + if (OptT::Flags & SWTRI_WriteDepth) { - zbufferLine[i] = depthvalues[i]; + for (int i = xstart; i < x; i++) + { + if (alphatestbuf[i] > 127) + zbufferLine[i] = depthvalues[i]; + } + } + } + else + { + if (OptT::Flags & SWTRI_WriteStencil) + { + int i = xstart; + int xendsse = xstart + ((x - xstart) / 16); + while (i < xendsse) + { + _mm_storeu_si128((__m128i*)&stencilLine[i], _mm_set1_epi8(stencilWriteValue)); + i += 16; + } + + while (i < x) + stencilLine[i++] = stencilWriteValue; + } + + if (!(OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_WriteDepth)) + { + for (int i = xstart; i < x; i++) + { + zbufferLine[i] = depthvalues[i]; + } } } } @@ -391,7 +417,7 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa { while (zbufferLine[x] >= depthvalues[x] && stencilLine[x] == stencilTestValue && x < xend) { - if (OptT::Flags & SWTRI_WriteDepth) + if (!alphatest && (OptT::Flags & SWTRI_WriteDepth)) zbufferLine[x] = depthvalues[x]; x++; } @@ -400,7 +426,7 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa { while (zbufferLine[x] >= depthvalues[x] && x < xend) { - if (OptT::Flags & SWTRI_WriteDepth) + if (!alphatest && (OptT::Flags & SWTRI_WriteDepth)) zbufferLine[x] = depthvalues[x]; x++; } @@ -420,17 +446,40 @@ void DrawTriangle(const TriDrawTriangleArgs *args, PolyTriangleThreadData *threa if (OptT::Flags & SWTRI_WriteColor) drawfunc(y, xstart, x, args, thread); - if (OptT::Flags & SWTRI_WriteStencil) + if (alphatest) { - for (int i = xstart; i < x; i++) - stencilLine[i] = stencilWriteValue; - } - - if (!(OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_WriteDepth)) - { - for (int i = xstart; i < x; i++) + if (OptT::Flags & SWTRI_WriteStencil) { - zbufferLine[i] = depthvalues[i]; + for (int i = xstart; i < x; i++) + { + if (alphatestbuf[i] > 127) + stencilLine[i++] = stencilWriteValue; + } + } + + if (OptT::Flags & SWTRI_WriteDepth) + { + for (int i = xstart; i < x; i++) + { + if (alphatestbuf[i] > 127) + zbufferLine[i] = depthvalues[i]; + } + } + } + else + { + if (OptT::Flags & SWTRI_WriteStencil) + { + for (int i = xstart; i < x; i++) + stencilLine[i] = stencilWriteValue; + } + + if (!(OptT::Flags & SWTRI_DepthTest) && (OptT::Flags & SWTRI_WriteDepth)) + { + for (int i = xstart; i < x; i++) + { + zbufferLine[i] = depthvalues[i]; + } } } } @@ -841,6 +890,7 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyT const uint32_t *texPixels, *translation; uint32_t fillcolor; int actoralpha; + uint8_t *alphatestbuf; uint32_t *texel = thread->texel; int32_t *texelV = thread->texelV; @@ -891,6 +941,11 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyT _fuzzpos = swrenderer::fuzzpos; } + if (ModeT::SWFlags & SWSTYLEF_AlphaTest) + { + alphatestbuf = thread->alphatestbuffer; + } + uint32_t *dest = (uint32_t*)thread->dest; uint32_t *destLine = dest + thread->dest_pitch * y; @@ -904,7 +959,8 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyT !(ModeT::Flags & STYLEF_RedIsAlpha) && !(ModeT::SWFlags & SWSTYLEF_Skycap) && !(ModeT::SWFlags & SWSTYLEF_FogBoundary) && - !(ModeT::SWFlags & SWSTYLEF_Fill)) + !(ModeT::SWFlags & SWSTYLEF_Fill) && + !(ModeT::SWFlags & SWSTYLEF_AlphaTest)) { sseend += (x1 - x0) / 2 * 2; @@ -1064,6 +1120,11 @@ void DrawSpanOpt32(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyT fgalpha = (fgalpha * actoralpha) >> 8; } + if (ModeT::SWFlags & SWSTYLEF_AlphaTest) + { + alphatestbuf[x] = fgalpha; + } + uint32_t lightshade; if (OptT::Flags & SWOPT_FixedLight) { @@ -1591,536 +1652,6 @@ void DrawSpan8(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTrian } } -#if 0 -template -void DrawRect8(const void *destOrg, int destWidth, int destHeight, int destPitch, const RectDrawArgs *args, PolyTriangleThreadData *thread) -{ - using namespace TriScreenDrawerModes; - - int x0 = clamp((int)(args->X0() + 0.5f), 0, destWidth); - int x1 = clamp((int)(args->X1() + 0.5f), 0, destWidth); - int y0 = clamp((int)(args->Y0() + 0.5f), 0, destHeight); - int y1 = clamp((int)(args->Y1() + 0.5f), 0, destHeight); - - if (x1 <= x0 || y1 <= y0) - return; - - const uint8_t *colormaps, *texPixels, *translation; - int texWidth, texHeight; - uint32_t fillcolor; - int alpha; - uint32_t light; - - texPixels = args->TexturePixels(); - translation = args->Translation(); - texWidth = args->TextureWidth(); - texHeight = args->TextureHeight(); - fillcolor = args->Color(); - alpha = args->Alpha(); - colormaps = args->BaseColormap(); - light = args->Light(); - light += light >> 7; // 255 -> 256 - light = ((256 - light) * NUMCOLORMAPS) & 0xffffff00; - - fixed_t fuzzscale; - int _fuzzpos; - if (ModeT::BlendOp == STYLEOP_Fuzz) - { - fuzzscale = (200 << FRACBITS) / thread->dest_height; - _fuzzpos = swrenderer::fuzzpos; - } - - float fstepU = (args->U1() - args->U0()) / (args->X1() - args->X0()); - float fstepV = (args->V1() - args->V0()) / (args->Y1() - args->Y0()); - uint32_t startU = (int32_t)((args->U0() + (x0 + 0.5f - args->X0()) * fstepU) * 0x1000000); - uint32_t startV = (int32_t)((args->V0() + (y0 + 0.5f - args->Y0()) * fstepV) * 0x1000000); - uint32_t stepU = (int32_t)(fstepU * 0x1000000); - uint32_t stepV = (int32_t)(fstepV * 0x1000000); - - uint32_t posV = startV; - y1 = MIN(y1, thread->numa_end_y); - int num_cores = thread->num_cores; - int skip = thread->skipped_by_thread(y0); - posV += skip * stepV; - stepV *= num_cores; - for (int y = y0 + skip; y < y1; y += num_cores, posV += stepV) - { - uint8_t *destLine = ((uint8_t*)destOrg) + y * destPitch; - - uint32_t posU = startU; - for (int x = x0; x < x1; x++) - { - if (ModeT::BlendOp == STYLEOP_Fuzz) - { - using namespace swrenderer; - - uint32_t texelX = (((posU << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = (((posV << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = (texPixels[texelX * texHeight + texelY] != 0) ? 256 : 0; - - int scaled_x = (x * fuzzscale) >> FRACBITS; - int fuzz_x = fuzz_random_x_offset[scaled_x % FUZZ_RANDOM_X_SIZE] + _fuzzpos; - - fixed_t fuzzcount = FUZZTABLE << FRACBITS; - fixed_t fuzz = ((fuzz_x << FRACBITS) + y * fuzzscale) % fuzzcount; - unsigned int alpha = fuzzoffset[fuzz >> FRACBITS]; - - sampleshadeout = (sampleshadeout * alpha) >> 5; - - uint32_t a = 256 - sampleshadeout; - - uint32_t dest = GPalette.BaseColors[destLine[x]].d; - uint32_t r = (RPART(dest) * a) >> 8; - uint32_t g = (GPART(dest) * a) >> 8; - uint32_t b = (BPART(dest) * a) >> 8; - destLine[x] = RGB256k.All[((r >> 2) << 12) | ((g >> 2) << 6) | (b >> 2)]; - } - else - { - int fg = 0; - if (ModeT::SWFlags & SWSTYLEF_Fill) - { - fg = fillcolor; - } - else - { - uint32_t texelX = (((posU << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = (((posV << 8) >> 16) * texHeight) >> 16; - fg = texPixels[texelX * texHeight + texelY]; - } - - int fgalpha = 255; - - if (ModeT::BlendDest == STYLEALPHA_InvSrc) - { - if (fg == 0) - fgalpha = 0; - } - - if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) - { - if (ModeT::Flags & STYLEF_RedIsAlpha) - fgalpha = fg; - fg = fillcolor; - } - - if (!(ModeT::Flags & STYLEF_Alpha1)) - { - fgalpha = (fgalpha * alpha) >> 8; - } - - if (ModeT::SWFlags & SWSTYLEF_Translated) - fg = translation[fg]; - - uint8_t shadedfg = colormaps[light + fg]; - - if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) - { - destLine[x] = shadedfg; - } - else if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_One) - { - uint32_t src = GPalette.BaseColors[shadedfg]; - uint32_t dest = GPalette.BaseColors[destLine[x]]; - - if (ModeT::BlendOp == STYLEOP_Add) - { - uint32_t out_r = MIN(RPART(dest) + RPART(src), 255); - uint32_t out_g = MIN(GPART(dest) + GPART(src), 255); - uint32_t out_b = MIN(BPART(dest) + BPART(src), 255); - destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; - } - else if (ModeT::BlendOp == STYLEOP_RevSub) - { - uint32_t out_r = MAX(RPART(dest) - RPART(src), 0); - uint32_t out_g = MAX(GPART(dest) - GPART(src), 0); - uint32_t out_b = MAX(BPART(dest) - BPART(src), 0); - destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; - } - else //if (ModeT::BlendOp == STYLEOP_Sub) - { - uint32_t out_r = MAX(RPART(src) - RPART(dest), 0); - uint32_t out_g = MAX(GPART(src) - GPART(dest), 0); - uint32_t out_b = MAX(BPART(src) - BPART(dest), 0); - destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; - } - } - else if (ModeT::SWFlags & SWSTYLEF_SrcColorOneMinusSrcColor) - { - uint32_t src = GPalette.BaseColors[shadedfg]; - uint32_t dest = GPalette.BaseColors[destLine[x]]; - - uint32_t sfactor_r = RPART(src); sfactor_r += sfactor_r >> 7; // 255 -> 256 - uint32_t sfactor_g = GPART(src); sfactor_g += sfactor_g >> 7; // 255 -> 256 - uint32_t sfactor_b = BPART(src); sfactor_b += sfactor_b >> 7; // 255 -> 256 - uint32_t sfactor_a = fgalpha; sfactor_a += sfactor_a >> 7; // 255 -> 256 - uint32_t dfactor_r = 256 - sfactor_r; - uint32_t dfactor_g = 256 - sfactor_g; - uint32_t dfactor_b = 256 - sfactor_b; - uint32_t out_r = (RPART(dest) * dfactor_r + RPART(src) * sfactor_r + 128) >> 8; - uint32_t out_g = (GPART(dest) * dfactor_g + GPART(src) * sfactor_g + 128) >> 8; - uint32_t out_b = (BPART(dest) * dfactor_b + BPART(src) * sfactor_b + 128) >> 8; - - destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; - } - else if (ModeT::BlendSrc == STYLEALPHA_Src && ModeT::BlendDest == STYLEALPHA_InvSrc && fgalpha == 255) - { - destLine[x] = shadedfg; - } - else if (ModeT::BlendSrc != STYLEALPHA_Src || ModeT::BlendDest != STYLEALPHA_InvSrc || fgalpha != 0) - { - uint32_t src = GPalette.BaseColors[shadedfg]; - uint32_t dest = GPalette.BaseColors[destLine[x]]; - - uint32_t sfactor = fgalpha; sfactor += sfactor >> 7; // 255 -> 256 - uint32_t dfactor = 256 - sfactor; - uint32_t src_r = RPART(src) * sfactor; - uint32_t src_g = GPART(src) * sfactor; - uint32_t src_b = BPART(src) * sfactor; - uint32_t dest_r = RPART(dest); - uint32_t dest_g = GPART(dest); - uint32_t dest_b = BPART(dest); - if (ModeT::BlendDest == STYLEALPHA_One) - { - dest_r <<= 8; - dest_g <<= 8; - dest_b <<= 8; - } - else - { - uint32_t dfactor = 256 - sfactor; - dest_r *= dfactor; - dest_g *= dfactor; - dest_b *= dfactor; - } - - uint32_t out_r, out_g, out_b; - if (ModeT::BlendOp == STYLEOP_Add) - { - if (ModeT::BlendDest == STYLEALPHA_One) - { - out_r = MIN((dest_r + src_r + 128) >> 8, 255); - out_g = MIN((dest_g + src_g + 128) >> 8, 255); - out_b = MIN((dest_b + src_b + 128) >> 8, 255); - } - else - { - out_r = (dest_r + src_r + 128) >> 8; - out_g = (dest_g + src_g + 128) >> 8; - out_b = (dest_b + src_b + 128) >> 8; - } - } - else if (ModeT::BlendOp == STYLEOP_RevSub) - { - out_r = MAX(static_cast(dest_r - src_r + 128) >> 8, 0); - out_g = MAX(static_cast(dest_g - src_g + 128) >> 8, 0); - out_b = MAX(static_cast(dest_b - src_b + 128) >> 8, 0); - } - else //if (ModeT::BlendOp == STYLEOP_Sub) - { - out_r = MAX(static_cast(src_r - dest_r + 128) >> 8, 0); - out_g = MAX(static_cast(src_g - dest_g + 128) >> 8, 0); - out_b = MAX(static_cast(src_b - dest_b + 128) >> 8, 0); - } - - destLine[x] = RGB256k.All[((out_r >> 2) << 12) | ((out_g >> 2) << 6) | (out_b >> 2)]; - } - } - - posU += stepU; - } - } -} - -template -void DrawRectOpt32(const void *destOrg, int destWidth, int destHeight, int destPitch, const RectDrawArgs *args, PolyTriangleThreadData *thread) -{ - using namespace TriScreenDrawerModes; - - int x0 = clamp((int)(args->X0() + 0.5f), 0, destWidth); - int x1 = clamp((int)(args->X1() + 0.5f), 0, destWidth); - int y0 = clamp((int)(args->Y0() + 0.5f), 0, destHeight); - int y1 = clamp((int)(args->Y1() + 0.5f), 0, destHeight); - - if (x1 <= x0 || y1 <= y0) - return; - - const uint32_t *texPixels, *translation; - int texWidth, texHeight; - uint32_t fillcolor; - int alpha; - uint32_t light; - uint32_t shade_fade_r, shade_fade_g, shade_fade_b, shade_light_r, shade_light_g, shade_light_b, desaturate, inv_desaturate; - - texPixels = (const uint32_t*)args->TexturePixels(); - translation = (const uint32_t*)args->Translation(); - texWidth = args->TextureWidth(); - texHeight = args->TextureHeight(); - fillcolor = args->Color(); - alpha = args->Alpha(); - light = args->Light(); - light += light >> 7; // 255 -> 256 - - if (OptT::Flags & SWOPT_ColoredFog) - { - shade_fade_r = args->ShadeFadeRed(); - shade_fade_g = args->ShadeFadeGreen(); - shade_fade_b = args->ShadeFadeBlue(); - shade_light_r = args->ShadeLightRed(); - shade_light_g = args->ShadeLightGreen(); - shade_light_b = args->ShadeLightBlue(); - desaturate = args->ShadeDesaturate(); - inv_desaturate = 256 - desaturate; - } - - fixed_t fuzzscale; - int _fuzzpos; - if (ModeT::BlendOp == STYLEOP_Fuzz) - { - fuzzscale = (200 << FRACBITS) / thread->dest_height; - _fuzzpos = swrenderer::fuzzpos; - } - - float fstepU = (args->U1() - args->U0()) / (args->X1() - args->X0()); - float fstepV = (args->V1() - args->V0()) / (args->Y1() - args->Y0()); - uint32_t startU = (int32_t)((args->U0() + (x0 + 0.5f - args->X0()) * fstepU) * 0x1000000); - uint32_t startV = (int32_t)((args->V0() + (y0 + 0.5f - args->Y0()) * fstepV) * 0x1000000); - uint32_t stepU = (int32_t)(fstepU * 0x1000000); - uint32_t stepV = (int32_t)(fstepV * 0x1000000); - - uint32_t posV = startV; - y1 = MIN(y1, thread->numa_end_y); - int num_cores = thread->num_cores; - int skip = thread->skipped_by_thread(y0); - posV += skip * stepV; - stepV *= num_cores; - for (int y = y0 + skip; y < y1; y += num_cores, posV += stepV) - { - uint32_t *destLine = ((uint32_t*)destOrg) + y * destPitch; - - uint32_t posU = startU; - for (int x = x0; x < x1; x++) - { - if (ModeT::BlendOp == STYLEOP_Fuzz) - { - using namespace swrenderer; - - uint32_t texelX = (((posU << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = (((posV << 8) >> 16) * texHeight) >> 16; - unsigned int sampleshadeout = APART(texPixels[texelX * texHeight + texelY]); - sampleshadeout += sampleshadeout >> 7; // 255 -> 256 - - int scaled_x = (x * fuzzscale) >> FRACBITS; - int fuzz_x = fuzz_random_x_offset[scaled_x % FUZZ_RANDOM_X_SIZE] + _fuzzpos; - - fixed_t fuzzcount = FUZZTABLE << FRACBITS; - fixed_t fuzz = ((fuzz_x << FRACBITS) + y * fuzzscale) % fuzzcount; - unsigned int alpha = fuzzoffset[fuzz >> FRACBITS]; - - sampleshadeout = (sampleshadeout * alpha) >> 5; - - uint32_t a = 256 - sampleshadeout; - - uint32_t dest = destLine[x]; - uint32_t out_r = (RPART(dest) * a) >> 8; - uint32_t out_g = (GPART(dest) * a) >> 8; - uint32_t out_b = (BPART(dest) * a) >> 8; - destLine[x] = MAKEARGB(255, out_r, out_g, out_b); - } - else - { - uint32_t fg = 0; - - if (ModeT::SWFlags & SWSTYLEF_Fill) - { - fg = fillcolor; - } - else if (ModeT::SWFlags & SWSTYLEF_FogBoundary) - { - fg = destLine[x]; - } - else - { - uint32_t texelX = (((posU << 8) >> 16) * texWidth) >> 16; - uint32_t texelY = (((posV << 8) >> 16) * texHeight) >> 16; - - if (ModeT::SWFlags & SWSTYLEF_Translated) - { - fg = translation[((const uint8_t*)texPixels)[texelX * texHeight + texelY]]; - } - else if (ModeT::Flags & STYLEF_RedIsAlpha) - { - fg = ((const uint8_t*)texPixels)[texelX * texHeight + texelY]; - } - else - { - fg = texPixels[texelX * texHeight + texelY]; - } - } - - if ((ModeT::Flags & STYLEF_ColorIsFixed) && !(ModeT::SWFlags & SWSTYLEF_Fill)) - { - if (ModeT::Flags & STYLEF_RedIsAlpha) - fg = (fg << 24) | (fillcolor & 0x00ffffff); - else - fg = (fg & 0xff000000) | (fillcolor & 0x00ffffff); - } - - uint32_t fgalpha = fg >> 24; - - if (!(ModeT::Flags & STYLEF_Alpha1)) - { - fgalpha = (fgalpha * alpha) >> 8; - } - - int lightshade = light; - - uint32_t lit_r = 0, lit_g = 0, lit_b = 0; - - uint32_t shadedfg_r, shadedfg_g, shadedfg_b; - if (OptT::Flags & SWOPT_ColoredFog) - { - uint32_t fg_r = RPART(fg); - uint32_t fg_g = GPART(fg); - uint32_t fg_b = BPART(fg); - uint32_t intensity = ((fg_r * 77 + fg_g * 143 + fg_b * 37) >> 8) * desaturate; - shadedfg_r = (((shade_fade_r + ((fg_r * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_r) >> 8; - shadedfg_g = (((shade_fade_g + ((fg_g * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_g) >> 8; - shadedfg_b = (((shade_fade_b + ((fg_b * inv_desaturate + intensity) >> 8) * lightshade) >> 8) * shade_light_b) >> 8; - } - else - { - shadedfg_r = (RPART(fg) * lightshade) >> 8; - shadedfg_g = (GPART(fg) * lightshade) >> 8; - shadedfg_b = (BPART(fg) * lightshade) >> 8; - } - - if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_Zero) - { - destLine[x] = MAKEARGB(255, shadedfg_r, shadedfg_g, shadedfg_b); - } - else if (ModeT::BlendSrc == STYLEALPHA_One && ModeT::BlendDest == STYLEALPHA_One) - { - uint32_t dest = destLine[x]; - - if (ModeT::BlendOp == STYLEOP_Add) - { - uint32_t out_r = MIN(RPART(dest) + shadedfg_r, 255); - uint32_t out_g = MIN(GPART(dest) + shadedfg_g, 255); - uint32_t out_b = MIN(BPART(dest) + shadedfg_b, 255); - destLine[x] = MAKEARGB(255, out_r, out_g, out_b); - } - else if (ModeT::BlendOp == STYLEOP_RevSub) - { - uint32_t out_r = MAX(RPART(dest) - shadedfg_r, 0); - uint32_t out_g = MAX(GPART(dest) - shadedfg_g, 0); - uint32_t out_b = MAX(BPART(dest) - shadedfg_b, 0); - destLine[x] = MAKEARGB(255, out_r, out_g, out_b); - } - else //if (ModeT::BlendOp == STYLEOP_Sub) - { - uint32_t out_r = MAX(shadedfg_r - RPART(dest), 0); - uint32_t out_g = MAX(shadedfg_g - GPART(dest), 0); - uint32_t out_b = MAX(shadedfg_b - BPART(dest), 0); - destLine[x] = MAKEARGB(255, out_r, out_g, out_b); - } - } - else if (ModeT::SWFlags & SWSTYLEF_SrcColorOneMinusSrcColor) - { - uint32_t dest = destLine[x]; - - uint32_t sfactor_r = shadedfg_r; sfactor_r += sfactor_r >> 7; // 255 -> 256 - uint32_t sfactor_g = shadedfg_g; sfactor_g += sfactor_g >> 7; // 255 -> 256 - uint32_t sfactor_b = shadedfg_b; sfactor_b += sfactor_b >> 7; // 255 -> 256 - uint32_t sfactor_a = fgalpha; sfactor_a += sfactor_a >> 7; // 255 -> 256 - uint32_t dfactor_r = 256 - sfactor_r; - uint32_t dfactor_g = 256 - sfactor_g; - uint32_t dfactor_b = 256 - sfactor_b; - uint32_t out_r = (RPART(dest) * dfactor_r + shadedfg_r * sfactor_r + 128) >> 8; - uint32_t out_g = (GPART(dest) * dfactor_g + shadedfg_g * sfactor_g + 128) >> 8; - uint32_t out_b = (BPART(dest) * dfactor_b + shadedfg_b * sfactor_b + 128) >> 8; - - destLine[x] = MAKEARGB(255, out_r, out_g, out_b); - } - else if (ModeT::BlendSrc == STYLEALPHA_Src && ModeT::BlendDest == STYLEALPHA_InvSrc && fgalpha == 255) - { - destLine[x] = MAKEARGB(255, shadedfg_r, shadedfg_g, shadedfg_b); - } - else if (ModeT::BlendSrc != STYLEALPHA_Src || ModeT::BlendDest != STYLEALPHA_InvSrc || fgalpha != 0) - { - uint32_t dest = destLine[x]; - - uint32_t sfactor = fgalpha; sfactor += sfactor >> 7; // 255 -> 256 - uint32_t src_r = shadedfg_r * sfactor; - uint32_t src_g = shadedfg_g * sfactor; - uint32_t src_b = shadedfg_b * sfactor; - uint32_t dest_r = RPART(dest); - uint32_t dest_g = GPART(dest); - uint32_t dest_b = BPART(dest); - if (ModeT::BlendDest == STYLEALPHA_One) - { - dest_r <<= 8; - dest_g <<= 8; - dest_b <<= 8; - } - else - { - uint32_t dfactor = 256 - sfactor; - dest_r *= dfactor; - dest_g *= dfactor; - dest_b *= dfactor; - } - - uint32_t out_r, out_g, out_b; - if (ModeT::BlendOp == STYLEOP_Add) - { - if (ModeT::BlendDest == STYLEALPHA_One) - { - out_r = MIN((dest_r + src_r + 128) >> 8, 255); - out_g = MIN((dest_g + src_g + 128) >> 8, 255); - out_b = MIN((dest_b + src_b + 128) >> 8, 255); - } - else - { - out_r = (dest_r + src_r + 128) >> 8; - out_g = (dest_g + src_g + 128) >> 8; - out_b = (dest_b + src_b + 128) >> 8; - } - } - else if (ModeT::BlendOp == STYLEOP_RevSub) - { - out_r = MAX(static_cast(dest_r - src_r + 128) >> 8, 0); - out_g = MAX(static_cast(dest_g - src_g + 128) >> 8, 0); - out_b = MAX(static_cast(dest_b - src_b + 128) >> 8, 0); - } - else //if (ModeT::BlendOp == STYLEOP_Sub) - { - out_r = MAX(static_cast(src_r - dest_r + 128) >> 8, 0); - out_g = MAX(static_cast(src_g - dest_g + 128) >> 8, 0); - out_b = MAX(static_cast(src_b - dest_b + 128) >> 8, 0); - } - - destLine[x] = MAKEARGB(255, out_r, out_g, out_b); - } - } - - posU += stepU; - } - } -} - -template -void DrawRect32(const void *destOrg, int destWidth, int destHeight, int destPitch, const RectDrawArgs *args, PolyTriangleThreadData *thread) -{ - using namespace TriScreenDrawerModes; - - if (args->SimpleShade()) - DrawRectOpt32(destOrg, destWidth, destHeight, destPitch, args, thread); - else - DrawRectOpt32(destOrg, destWidth, destHeight, destPitch, args, thread); -} -#endif - void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs *, PolyTriangleThreadData *) = { &DrawSpan8, @@ -2130,6 +1661,7 @@ void(*ScreenTriangle::SpanDrawers8[])(int, int, int, const TriDrawTriangleArgs * &DrawSpan8, &DrawSpan8, &DrawSpan8, + &DrawSpan8, &DrawSpan8, &DrawSpan8, &DrawSpan8, @@ -2163,6 +1695,7 @@ void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs &DrawSpan32, &DrawSpan32, &DrawSpan32, + &DrawSpan32, &DrawSpan32, &DrawSpan32, &DrawSpan32, @@ -2187,72 +1720,6 @@ void(*ScreenTriangle::SpanDrawers32[])(int, int, int, const TriDrawTriangleArgs &DrawSpan32 }; -#if 0 -void(*ScreenTriangle::RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *) = -{ - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8, - &DrawRect8 -}; - -void(*ScreenTriangle::RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *) = -{ - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32, - &DrawRect32 -}; -#endif - void(*ScreenTriangle::TriangleDrawers[])(const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread, int16_t *edges, int topY, int bottomY) = { &DrawTriangle, diff --git a/src/rendering/polyrenderer/drawers/screen_triangle.h b/src/rendering/polyrenderer/drawers/screen_triangle.h index 3e9bef620..151cdfcea 100644 --- a/src/rendering/polyrenderer/drawers/screen_triangle.h +++ b/src/rendering/polyrenderer/drawers/screen_triangle.h @@ -106,6 +106,7 @@ enum class TriBlendMode Fill, FillTranslucent, Normal, + AlphaTest, Fuzzy, Stencil, Translucent, @@ -139,10 +140,6 @@ public: static void(*SpanDrawers8[])(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); static void(*SpanDrawers32[])(int y, int x0, int x1, const TriDrawTriangleArgs *args, PolyTriangleThreadData *thread); -#if 0 - static void(*RectDrawers8[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *); - static void(*RectDrawers32[])(const void *, int, int, int, const RectDrawArgs *, PolyTriangleThreadData *); -#endif static int FuzzStart; }; @@ -155,7 +152,8 @@ namespace TriScreenDrawerModes SWSTYLEF_Skycap = 2, SWSTYLEF_FogBoundary = 4, SWSTYLEF_Fill = 8, - SWSTYLEF_SrcColorOneMinusSrcColor = 16 + SWSTYLEF_SrcColorOneMinusSrcColor = 16, + SWSTYLEF_AlphaTest = 32 }; struct StyleOpaque { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_One, BlendDest = STYLEALPHA_Zero, Flags = STYLEF_Alpha1, SWFlags = 0; }; @@ -166,6 +164,7 @@ namespace TriScreenDrawerModes struct StyleFillTranslucent { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_Fill; }; struct StyleNormal { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = 0; }; + struct StyleAlphaTest { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1, SWFlags = SWSTYLEF_AlphaTest; }; struct StyleFuzzy { static const int BlendOp = STYLEOP_Fuzz, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = 0; }; struct StyleStencil { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = STYLEF_Alpha1 | STYLEF_ColorIsFixed, SWFlags = 0; }; struct StyleTranslucent { static const int BlendOp = STYLEOP_Add, BlendSrc = STYLEALPHA_Src, BlendDest = STYLEALPHA_InvSrc, Flags = 0, SWFlags = 0; };