diff --git a/source/glbackend/gl_shader.cpp b/source/glbackend/gl_shader.cpp index e9c86a853..b4be8d217 100644 --- a/source/glbackend/gl_shader.cpp +++ b/source/glbackend/gl_shader.cpp @@ -135,9 +135,8 @@ bool PolymostShader::Load(const char * name, const char * vert_prog, const char if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, VIEWPOINT_BINDINGPOINT); Flags.Init(hShader, "u_flags"); - NPOTEmulationFactor.Init(hShader, "u_npotEmulationFactor"); - NPOTEmulationXOffset.Init(hShader, "u_npotEmulationXOffset"); - + + NPOTEmulation.Init(hShader, "uNpotEmulation"); TextureMode.Init(hShader, "uTextureMode"); FogColor.Init(hShader, "uFogColor"); muFogEnabled.Init(hShader, "uFogEnabled"); diff --git a/source/glbackend/gl_shader.h b/source/glbackend/gl_shader.h index 40cc4da4b..594a7fd0a 100644 --- a/source/glbackend/gl_shader.h +++ b/source/glbackend/gl_shader.h @@ -27,9 +27,8 @@ class PolymostShader : public FShader { public: FBufferedUniform1i Flags; - FBufferedUniform1f NPOTEmulationFactor; - FBufferedUniform1f NPOTEmulationXOffset; - FBufferedUniformPalEntry FogColor; + FBufferedUniform2f NPOTEmulation; + FBufferedUniformPalEntry FogColor; FBufferedUniform1i TextureMode; FBufferedUniform4f DetailParms; diff --git a/source/glbackend/glbackend.cpp b/source/glbackend/glbackend.cpp index bd75f7d52..09ceaed50 100644 --- a/source/glbackend/glbackend.cpp +++ b/source/glbackend/glbackend.cpp @@ -138,6 +138,7 @@ auto i_data = R"( uniform int uFogEnabled; uniform vec4 uFogColor; uniform int uTextureMode; + uniform vec2 uNpotEmulation; )"; @@ -543,8 +544,7 @@ void PolymostRenderState::Apply(PolymostShader* shader, GLState& oldState) shader->Flags.Set(Flags); shader->TextureMode.Set(LayerFlags); - shader->NPOTEmulationFactor.Set(NPOTEmulationFactor); - shader->NPOTEmulationXOffset.Set(NPOTEmulationXOffset); + shader->NPOTEmulation.Set(&NPOTEmulation.X); shader->AlphaThreshold.Set(AlphaTest ? AlphaThreshold : -1.f); shader->FogColor.Set((Flags& RF_MapFog)? PalEntry(0x999999) : FogColor); float lightattr[] = { ShadeDiv / (numshades - 2), VisFactor, (Flags & RF_MapFog) ? -5.f : 0.f , ShadeDiv >= 1 / 1000.f? Shade : 0 }; diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index da742736c..c336b5440 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -391,8 +391,8 @@ public: void SetNpotEmulation(float factor, float xOffset) { - renderState.NPOTEmulationFactor = factor; - renderState.NPOTEmulationXOffset = xOffset; + renderState.NPOTEmulation.Y = factor; + renderState.NPOTEmulation.X = xOffset; } void SetShadeInterpolate(int32_t yes) diff --git a/source/glbackend/pm_renderstate.h b/source/glbackend/pm_renderstate.h index aeb727761..b8a6fe2a9 100644 --- a/source/glbackend/pm_renderstate.h +++ b/source/glbackend/pm_renderstate.h @@ -55,8 +55,7 @@ struct PolymostRenderState float VisFactor = 128.f; int Flags = 0; int LayerFlags = 0; - float NPOTEmulationFactor = 1.f; - float NPOTEmulationXOffset; + FVector2 NPOTEmulation = { 0.f, 0.f }; float AlphaThreshold = 0.5f; bool AlphaTest = true; float Color[4] = { 1,1,1,1 }; diff --git a/wadsrc/static/engine/shaders/glsl/polymost.fp b/wadsrc/static/engine/shaders/glsl/polymost.fp index 135ccb426..e83922462 100644 --- a/wadsrc/static/engine/shaders/glsl/polymost.fp +++ b/wadsrc/static/engine/shaders/glsl/polymost.fp @@ -33,9 +33,6 @@ uniform sampler2D s_palette; uniform int u_flags; -uniform float u_npotEmulationFactor; -uniform float u_npotEmulationXOffset; - in vec4 v_color; in float v_distance; in vec4 v_texCoord; @@ -161,12 +158,12 @@ void main() float coordY = v_texCoord.y; vec2 newCoord; - // Coordinate adjustment for NPOT textures (something must have gone very wrong to make this necessary...) - if (u_npotEmulationFactor != 0.0) + // Coordinate adjustment for NPOT textures. It is somehow fitting that Build games exploited this texture wrapping quirk of the software rendering engine... + if (uNpotEmulation.y != 0.0) { - float period = floor(coordY / u_npotEmulationFactor); - coordX += u_npotEmulationXOffset * floor(mod(coordY, u_npotEmulationFactor)); - coordY = period + mod(coordY, u_npotEmulationFactor); + float period = floor(coordY / uNpotEmulation.y); + coordX += uNpotEmulation.x * floor(mod(coordY, uNpotEmulation.y)); + coordY = period + mod(coordY, uNpotEmulation.y); } newCoord = vec2(coordX, coordY); diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 8960103bf..048579eee 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -540,6 +540,14 @@ vec3 ApplyNormalMap(vec2 texcoord) void SetMaterialProps(inout Material material, vec2 texCoord) { +#ifdef NPOT_EMULATION + if (uNpotEmulation.y != 0.0) + { + float period = floor(texCoord.t / uNpotEmulation.y); + texCoord.s += uNpotEmulation.x * floor(mod(texCoord.t, uNpotEmulation.y)); + texCoord.t = period + mod(texCoord.t, uNpotEmulation.y); + } +#endif material.Base = getTexel(texCoord.st); material.Normal = ApplyNormalMap(texCoord.st);