From 2a905e802621cc538b38e1c48c014f883d102f6c Mon Sep 17 00:00:00 2001 From: Emile Belanger Date: Sat, 16 Oct 2021 17:23:39 +0100 Subject: [PATCH] Fix palette mode for GLES --- .../rendering/gles/gles_renderstate.cpp | 4 ++ .../common/rendering/gles/gles_samplers.cpp | 18 +++++ .../static/shaders_gles/glsl/func_paletted.fp | 70 +++++++++++++++++-- wadsrc/static/shaders_gles/glsl/main.fp | 16 +++-- 4 files changed, 97 insertions(+), 11 deletions(-) diff --git a/source/common/rendering/gles/gles_renderstate.cpp b/source/common/rendering/gles/gles_renderstate.cpp index f3d92b126..20b7a3124 100644 --- a/source/common/rendering/gles/gles_renderstate.cpp +++ b/source/common/rendering/gles/gles_renderstate.cpp @@ -35,6 +35,9 @@ #include "gles_renderbuffers.h" #include "gles_hwtexture.h" #include "gles_buffers.h" +#include "gles_renderer.h" +#include "gles_samplers.h" + #include "hw_clock.h" #include "printf.h" @@ -479,6 +482,7 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio for (int i = 1; i < 3; i++) { auto systex = static_cast(mat->GetLayer(i, translation, &layer)); + GLRenderer->mSamplerManager->Bind(i, CLAMP_NONE, 255); systex->Bind(i, false); maxbound = i; } diff --git a/source/common/rendering/gles/gles_samplers.cpp b/source/common/rendering/gles/gles_samplers.cpp index 1e3b16d2d..c088657c7 100644 --- a/source/common/rendering/gles/gles_samplers.cpp +++ b/source/common/rendering/gles/gles_samplers.cpp @@ -119,8 +119,26 @@ uint8_t FSamplerManager::Bind(int texunit, int num, int lastval) break; case CLAMP_NOFILTER: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + case CLAMP_NOFILTER_X: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + case CLAMP_NOFILTER_Y: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + case CLAMP_NOFILTER_XY: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); diff --git a/wadsrc/static/shaders_gles/glsl/func_paletted.fp b/wadsrc/static/shaders_gles/glsl/func_paletted.fp index 8de8f0747..8104185c1 100644 --- a/wadsrc/static/shaders_gles/glsl/func_paletted.fp +++ b/wadsrc/static/shaders_gles/glsl/func_paletted.fp @@ -1,10 +1,70 @@ +const int RF_ShadeInterpolate = 64; vec4 ProcessTexel() { - float index = getTexel(vTexCoord.st).r; - index = ((index * 255.0) + 0.5) / 256.0; - vec4 tex = texture2D(texture2, vec2(index, 0.5)); - tex.a = 1.0; - return tex; + float fullbright = 0.0; + vec4 color; + float coordX = vTexCoord.x; + float coordY = vTexCoord.y; + vec2 newCoord; + + // z is the depth in view space, positive going into the screen + float z = abs(pixelpos.w); + +#ifdef NPOT_EMULATION + // Coordinate adjustment for NPOT textures. It is somehow fitting that Build games exploited this texture wrapping quirk of the software rendering engine... +#if (DEF_NPOT_EMULATION == 1) + { + float period = floor(coordY / uNpotEmulation.y); + coordX += uNpotEmulation.x * floor(mod(coordY, uNpotEmulation.y)); + coordY = period + mod(coordY, uNpotEmulation.y); + } +#endif + +#endif + newCoord = vec2(coordX, coordY); + + color = texture(tex, newCoord); + +#if ((DEF_BLEND_FLAGS & 16384) != 0) + float visibility = max(uGlobVis * uLightFactor * z - 0.5, 0.0); +#else + float visibility = max(uGlobVis * uLightFactor * z, 0.0); +#endif + + float numShades = float(uPalLightLevels & 255); + float shade = (1.0 - uLightLevel) * (numShades); + shade = clamp((shade + visibility), 0.0, numShades - 1.0); + + int palindex = int(color.r * 255.0 + 0.1); // The 0.1 is for roundoff error compensation. + int shadeindex = int(floor(shade)); + float colorIndexF = texelFetch(texture3, ivec2(palindex, shadeindex), 0).r; + int colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation. + vec4 palettedColor = texelFetch(texture2, ivec2(colorIndex, 0), 0); + +#if ((DEF_BLEND_FLAGS & 16384) != 0) + { + // Get the next shaded palette index for interpolation + colorIndexF = texelFetch(texture3, ivec2(palindex, shadeindex+1), 0).r; + colorIndex = int(colorIndexF * 255.0 + 0.1); // The 0.1 is for roundoff error compensation. + vec4 palettedColorNext = texelFetch(texture2, ivec2(colorIndex, 0), 0); + float shadeFrac = mod(shade, 1.0); + palettedColor.rgb = mix(palettedColor.rgb, palettedColorNext.rgb, shadeFrac); + } +#endif + + //palettedColor.a = color.r == 0.0? 0.0 : 1.0;// 1.0-floor(color.r); + + // Replaces above line without branch + palettedColor.a = floor(color.r + 0.999); + + color = palettedColor; + + //if (color.a < uAlphaThreshold) discard; // it's only here that we have the alpha value available to be able to perform the alpha test. + + // This replaces the above line to avoid the branch and the discard.. Seems to look the same but could be unforeseen issues. + float alpha = step(uAlphaThreshold, color.a); + + return vec4(color.rgb, alpha); } diff --git a/wadsrc/static/shaders_gles/glsl/main.fp b/wadsrc/static/shaders_gles/glsl/main.fp index 92e77eefe..5265e3b1f 100644 --- a/wadsrc/static/shaders_gles/glsl/main.fp +++ b/wadsrc/static/shaders_gles/glsl/main.fp @@ -115,29 +115,29 @@ const int Tex_Blend_Hardlight = 4; texel.rgb = clamp(texel.rgb, 0.0, 1.0); // Step 5: Apply a blend. This may just be a translucent overlay or one of the blend modes present in current Build engines. -#if (DEF_BLEND_FLAGS != 0) +#if ((DEF_BLEND_FLAGS & 7) != 0) vec3 tcol = texel.rgb * 255.0; // * 255.0 to make it easier to reuse the integer math. vec4 tint = uTextureBlendColor * 255.0; -#if (DEF_BLEND_FLAGS == 1) +#if ((DEF_BLEND_FLAGS & 7) == 1) tcol.b = tcol.b * (1.0 - uTextureBlendColor.a) + tint.b * uTextureBlendColor.a; tcol.g = tcol.g * (1.0 - uTextureBlendColor.a) + tint.g * uTextureBlendColor.a; tcol.r = tcol.r * (1.0 - uTextureBlendColor.a) + tint.r * uTextureBlendColor.a; -#elif (DEF_BLEND_FLAGS == 2) // Tex_Blend_Screen: +#elif ((DEF_BLEND_FLAGS & 7) == 2) // Tex_Blend_Screen: tcol.b = 255.0 - (((255.0 - tcol.b) * (255.0 - tint.r)) / 256.0); tcol.g = 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 256.0); tcol.r = 255.0 - (((255.0 - tcol.r) * (255.0 - tint.b)) / 256.0); -#elif (DEF_BLEND_FLAGS == 3) // Tex_Blend_Overlay: +#elif ((DEF_BLEND_FLAGS & 7) == 3) // Tex_Blend_Overlay: tcol.b = tcol.b < 128.0? (tcol.b * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - tint.b)) / 128.0); tcol.g = tcol.g < 128.0? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 128.0); tcol.r = tcol.r < 128.0? (tcol.r * tint.r) / 128.0 : 255.0 - (((255.0 - tcol.r) * (255.0 - tint.r)) / 128.0); -#elif (DEF_BLEND_FLAGS == 4) // Tex_Blend_Hardlight: +#elif ((DEF_BLEND_FLAGS & 7) == 4) // Tex_Blend_Hardlight: tcol.b = tint.b < 128.0 ? (tcol.b * tint.b) / 128.0 : 255.0 - (((255.0 - tcol.b) * (255.0 - tint.b)) / 128.0); tcol.g = tint.g < 128.0 ? (tcol.g * tint.g) / 128.0 : 255.0 - (((255.0 - tcol.g) * (255.0 - tint.g)) / 128.0); @@ -201,7 +201,7 @@ vec4 getTexel(vec2 st) #if (DEF_BLEND_FLAGS != 0) // only apply the texture manipulation if it contains something. - texel = ApplyTextureManipulation(texel, DEF_BLEND_FLAGS); + texel = ApplyTextureManipulation(texel); #endif @@ -275,6 +275,7 @@ float R_ZDoomColormap(float light, float z) //=========================================================================== float R_DoomLightingEquation(float light) { +#ifndef PALETTE_EMULATION // z is the depth in view space, positive going into the screen float z; @@ -301,6 +302,9 @@ float R_DoomLightingEquation(float light) // Result is the normalized colormap index (0 bright .. 1 dark) return clamp(colormap, 0.0, 31.0) / 32.0; +#else + return 0.0; // with palette emulation we do not want real lighting. +#endif }