From 82a17572ef835e2dce10b48662a000c2c9381a9c Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 5 Aug 2019 19:32:54 +0200 Subject: [PATCH] - implement getTexel part of main.fp --- .../polyrenderer/drawers/poly_triangle.cpp | 81 +--------- .../polyrenderer/drawers/poly_triangle.h | 1 + .../polyrenderer/drawers/screen_triangle.cpp | 147 ++++++++++++++++-- 3 files changed, 146 insertions(+), 83 deletions(-) diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.cpp b/src/rendering/polyrenderer/drawers/poly_triangle.cpp index e676a350637..e5e6c140481 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/poly_triangle.cpp @@ -303,16 +303,7 @@ void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPu mainVertexShader.Data = data; mainVertexShader.uClipSplit = constants.uClipSplit; - FColormap cm; - cm.Clear(); - if (constants.uLightLevel >= 0.0f) - { - drawargs.SetLight(GetColorTable(cm), (int)(constants.uLightLevel * 255.0f), mainVertexShader.Viewpoint->mGlobVis * 32.0f, false); - } - else - { - drawargs.SetLight(GetColorTable(cm), 255, mainVertexShader.Viewpoint->mGlobVis * 32.0f, true); - } + PushConstants = &constants; int numLights = 0; if (constants.uLightIndex >= 0) @@ -350,74 +341,18 @@ void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPu } drawargs.SetLights(polyLights, numLights); - if (SpecialEffect != EFF_NONE) +#if 0 + FColormap cm; + cm.Clear(); + if (constants.uLightLevel >= 0.0f) { - // To do: need new drawers for these - switch (SpecialEffect) - { - default: break; - case EFF_FOGBOUNDARY: drawargs.SetStyle(TriBlendMode::FogBoundary); break; - case EFF_SPHEREMAP: drawargs.SetStyle(TriBlendMode::Fill); break; - case EFF_BURN: drawargs.SetStyle(TriBlendMode::Fill); break; - case EFF_STENCIL: drawargs.SetStyle(TriBlendMode::Fill); break; - } + drawargs.SetLight(GetColorTable(cm), (int)(constants.uLightLevel * 255.0f), mainVertexShader.Viewpoint->mGlobVis * 32.0f, false); } else { - switch (EffectState) - { - default: - break; - case SHADER_Paletted: - break; - case SHADER_NoTexture: - drawargs.SetStyle(TriBlendMode::FillTranslucent); - return; - case SHADER_BasicFuzz: - case SHADER_SmoothFuzz: - case SHADER_SwirlyFuzz: - case SHADER_TranslucentFuzz: - case SHADER_JaggedFuzz: - case SHADER_NoiseFuzz: - case SHADER_SmoothNoiseFuzz: - case SHADER_SoftwareFuzz: - drawargs.SetStyle(TriBlendMode::Fuzzy); - return; - } - - auto style = RenderStyle; - if (style.BlendOp == STYLEOP_Add && style.SrcAlpha == STYLEALPHA_One && style.DestAlpha == STYLEALPHA_Zero) - { - drawargs.SetStyle(AlphaTest ? TriBlendMode::AlphaTest : TriBlendMode::Opaque); - } - else if (style.BlendOp == STYLEOP_Add && style.SrcAlpha == STYLEALPHA_Src && style.DestAlpha == STYLEALPHA_InvSrc) - { - drawargs.SetStyle(TriBlendMode::Normal); - } - else if (style.BlendOp == STYLEOP_Add && style.SrcAlpha == STYLEALPHA_SrcCol && style.DestAlpha == STYLEALPHA_One) - { - drawargs.SetStyle(TriBlendMode::SrcColor); - } - else - { - if (style == LegacyRenderStyles[STYLE_Normal]) drawargs.SetStyle(TriBlendMode::Normal); - else if (style == LegacyRenderStyles[STYLE_Stencil]) drawargs.SetStyle(TriBlendMode::Stencil); - else if (style == LegacyRenderStyles[STYLE_Translucent]) drawargs.SetStyle(TriBlendMode::Translucent); - else if (style == LegacyRenderStyles[STYLE_Add]) drawargs.SetStyle(TriBlendMode::Add); - //else if (style == LegacyRenderStyles[STYLE_Shaded]) drawargs.SetStyle(TriBlendMode::Shaded); - else if (style == LegacyRenderStyles[STYLE_TranslucentStencil]) drawargs.SetStyle(TriBlendMode::TranslucentStencil); - else if (style == LegacyRenderStyles[STYLE_Shadow]) drawargs.SetStyle(TriBlendMode::Shadow); - else if (style == LegacyRenderStyles[STYLE_Subtract]) drawargs.SetStyle(TriBlendMode::Subtract); - else if (style == LegacyRenderStyles[STYLE_AddStencil]) drawargs.SetStyle(TriBlendMode::AddStencil); - else if (style == LegacyRenderStyles[STYLE_AddShaded]) drawargs.SetStyle(TriBlendMode::AddShaded); - //else if (style == LegacyRenderStyles[STYLE_Multiply]) drawargs.SetStyle(TriBlendMode::Multiply); - //else if (style == LegacyRenderStyles[STYLE_InverseMultiply]) drawargs.SetStyle(TriBlendMode::InverseMultiply); - //else if (style == LegacyRenderStyles[STYLE_ColorBlend]) drawargs.SetStyle(TriBlendMode::ColorBlend); - else if (style == LegacyRenderStyles[STYLE_Source]) drawargs.SetStyle(TriBlendMode::Opaque); - //else if (style == LegacyRenderStyles[STYLE_ColorAdd]) drawargs.SetStyle(TriBlendMode::ColorAdd); - else drawargs.SetStyle(TriBlendMode::Opaque); - } + drawargs.SetLight(GetColorTable(cm), 255, mainVertexShader.Viewpoint->mGlobVis * 32.0f, true); } +#endif } void PolyTriangleThreadData::PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix) diff --git a/src/rendering/polyrenderer/drawers/poly_triangle.h b/src/rendering/polyrenderer/drawers/poly_triangle.h index 4f365ca0405..4bf2e4a1c85 100644 --- a/src/rendering/polyrenderer/drawers/poly_triangle.h +++ b/src/rendering/polyrenderer/drawers/poly_triangle.h @@ -238,6 +238,7 @@ class PolyTriangleThreadData int SpecialEffect = EFF_NONE; int EffectState = 0; bool AlphaTest = false; + const PolyPushConstants* PushConstants = nullptr; PolyDrawArgs drawargs; diff --git a/src/rendering/polyrenderer/drawers/screen_triangle.cpp b/src/rendering/polyrenderer/drawers/screen_triangle.cpp index 7d74f564e87..28b120e98c8 100644 --- a/src/rendering/polyrenderer/drawers/screen_triangle.cpp +++ b/src/rendering/polyrenderer/drawers/screen_triangle.cpp @@ -37,6 +37,7 @@ #include "swrenderer/drawers/r_draw_rgba.h" #include "screen_triangle.h" #include "x86.h" +#include static void WriteW(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) { @@ -219,29 +220,155 @@ static void WriteStencil(int y, int x0, int x1, PolyTriangleThreadData* thread) } } +static float wrap(float value) +{ + return value - std::floor(value); +} + +static uint32_t sampleTexture(float u, float v, const uint32_t* texPixels, int texWidth, int texHeight) +{ + int texelX = static_cast(wrap(u) * texWidth); + int texelY = static_cast(wrap(v) * texHeight); + return texPixels[texelX * texHeight + texelY]; +} + static void RunShader(int x0, int x1, PolyTriangleThreadData* thread) { int texWidth = thread->drawargs.TextureWidth(); int texHeight = thread->drawargs.TextureHeight(); const uint32_t* texPixels = (const uint32_t*)thread->drawargs.TexturePixels(); + auto constants = thread->PushConstants; + uint32_t* fragcolor = thread->scanline.FragColor; + float* u = thread->scanline.U; + float* v = thread->scanline.V; + + switch (constants->uTextureMode) + { + default: + case TM_NORMAL: + case TM_FOGLAYER: + for (int x = x0; x < x1; x++) + { + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + fragcolor[x] = texel; + } + break; + case TM_STENCIL: // TM_STENCIL + for (int x = x0; x < x1; x++) + { + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + fragcolor[x] = texel | 0x00ffffff; + } + break; + case TM_OPAQUE: + for (int x = x0; x < x1; x++) + { + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + fragcolor[x] = texel | 0xff000000; + } + break; + case TM_INVERSE: + for (int x = x0; x < x1; x++) + { + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + fragcolor[x] = MAKEARGB(APART(texel), 0xff - RPART(texel), 0xff - BPART(texel), 0xff - GPART(texel)); + } + break; + case TM_ALPHATEXTURE: + for (int x = x0; x < x1; x++) + { + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + uint32_t gray = (RPART(texel) * 77 + GPART(texel) * 143 + BPART(texel) * 37) >> 8; + uint32_t alpha = APART(texel); + alpha += alpha >> 7; + alpha = (alpha * gray + 127) >> 8; + texel = (alpha << 24) | 0x00ffffff; + fragcolor[x] = texel; + } + break; + case TM_CLAMPY: + for (int x = x0; x < x1; x++) + { + if (v[x] >= 0.0 && v[x] <= 1.0) + fragcolor[x] = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + else + fragcolor[x] = 0; + } + break; + case TM_INVERTOPAQUE: + for (int x = x0; x < x1; x++) + { + uint32_t texel = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight); + fragcolor[x] = MAKEARGB(0xff, 0xff - RPART(texel), 0xff - BPART(texel), 0xff - GPART(texel)); + } + } + +#if 0 + if (constants->uTextureMode != TM_FOGLAYER) + { + texel.rgb += uAddColor.rgb; + if (uObjectColor2.a == 0.0) texel *= uObjectColor; + else texel *= mix(uObjectColor, uObjectColor2, gradientdist.z); + texel = desaturate(texel); + } +#endif + +#if 0 for (int x = x0; x < x1; x++) { - float u = thread->scanline.U[x]; - float v = thread->scanline.V[x]; - u -= std::floor(u); - v -= std::floor(v); - - int texelX = (int)(u * texWidth); - int texelY = (int)(v * texHeight); - uint32_t fg = texPixels[texelX * texHeight + texelY]; - thread->scanline.FragColor[x] = fg; + uint32_t texel = fragcolor[x]; + + //#ifndef NO_ALPHATEST + //if (texel.a <= uAlphaThreshold) discard; + //#endif + + if (constants->uFogEnabled != -3) // check for special 2D 'fog' mode. + { + float fogdist = 0.0f; + float fogfactor = 0.0f; + + // calculate fog factor + if (constants->uFogEnabled != 0) + { + if (constants->uFogEnabled == 1 || constants->uFogEnabled == -1) + fogdist = max(16.0, pixelpos.w); + else + fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz)); + fogfactor = exp2(constants->uFogDensity * fogdist); + } + + if (constants->uTextureMode != 7) + { + texel = getLightColor(texel, fogdist, fogfactor); + if (constants->uFogEnabled < 0) + texel = applyFog(texel, fogfactor); + } + else + { + texel = vec4(uFogColor.rgb, (1.0 - fogfactor) * texel.a * 0.75 * vColor.a); + } + } + else // simple 2D (uses the fog color to add a color overlay) + { + if (constants->uTextureMode == 7) + { + float gray = grayscale(texel); + vec4 cm = (uObjectColor + gray * (uAddColor - uObjectColor)) * 2; + texel = vec4(clamp(cm.rgb, 0.0, 1.0), texel.a); + } + texel = texel * ProcessLight(texel, vColor); + texel.rgb = texel.rgb + uFogColor.rgb; + } + + fragcolor[x] = texel; } +#endif } static void DrawSpan(int y, int x0, int x1, const TriDrawTriangleArgs* args, PolyTriangleThreadData* thread) { - if (thread->drawargs.BlendMode() == TriBlendMode::Fill || thread->drawargs.BlendMode() == TriBlendMode::FillTranslucent) + if (thread->SpecialEffect != EFF_NONE || !(thread->EffectState == SHADER_Default || thread->EffectState == SHADER_Brightmap)) return; WriteVaryings(y, x0, x1, args, thread);