- added Build's NPOT emulation to the backend.

For GZDoom this is completely disabled, of course, because the Doom engine does not need it, but in order to have the same backend code in both engines it needs to be present.
This commit is contained in:
Christoph Oelckers 2020-06-08 08:01:56 +02:00
parent 65df05cba2
commit 9e51a2f63c
7 changed files with 164 additions and 98 deletions

View file

@ -142,6 +142,9 @@ bool FGLRenderState::ApplyShader()
activeShader->muTextureModulateColor.Set(mStreamData.uTextureModulateColor);
activeShader->muTextureBlendColor.Set(mStreamData.uTextureBlendColor);
activeShader->muDetailParms.Set(&mStreamData.uDetailParms.X);
#ifdef NPOT_EMULATION
activeShader->muNpotEmulation.Set(&mStreamData.uNpotEmulation.X);
#endif
if (mGlowEnabled || activeShader->currentglowstate)
{

View file

@ -40,6 +40,7 @@
#include "hw_lightbuffer.h"
#include "i_specialpaths.h"
#include "printf.h"
#include "version.h"
#include "gl_interface.h"
#include "gl_debug.h"
@ -232,105 +233,106 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
float uClipHeightDirection;
int uShadowmapFilter;
};
uniform int uTextureMode;
uniform vec2 uClipSplit;
uniform float uAlphaThreshold;
// colors
uniform vec4 uObjectColor;
uniform vec4 uObjectColor2;
uniform vec4 uDynLightColor;
uniform vec4 uAddColor;
uniform vec4 uTextureBlendColor;
uniform vec4 uTextureModulateColor;
uniform vec4 uTextureAddColor;
uniform vec4 uBlendColor;
uniform vec4 uFogColor;
uniform float uDesaturationFactor;
uniform float uInterpolationFactor;
// Glowing walls stuff
uniform vec4 uGlowTopPlane;
uniform vec4 uGlowTopColor;
uniform vec4 uGlowBottomPlane;
uniform vec4 uGlowBottomColor;
uniform vec4 uGradientTopPlane;
uniform vec4 uGradientBottomPlane;
uniform vec4 uSplitTopPlane;
uniform vec4 uSplitBottomPlane;
uniform vec4 uDetailParms;
// Lighting + Fog
uniform vec4 uLightAttr;
#define uLightLevel uLightAttr.a
#define uFogDensity uLightAttr.b
#define uLightFactor uLightAttr.g
#define uLightDist uLightAttr.r
uniform int uFogEnabled;
// dynamic lights
uniform int uLightIndex;
// Blinn glossiness and specular level
uniform vec2 uSpecularMaterial;
// matrices
uniform mat4 ModelMatrix;
uniform mat4 NormalModelMatrix;
uniform mat4 TextureMatrix;
// light buffers
#ifdef SHADER_STORAGE_LIGHTS
layout(std430, binding = 1) buffer LightBufferSSO
{
vec4 lights[];
};
#elif defined NUM_UBO_LIGHTS
uniform LightBufferUBO
{
vec4 lights[NUM_UBO_LIGHTS];
};
#endif
// textures
uniform sampler2D tex;
uniform sampler2D ShadowMap;
uniform sampler2D texture2;
uniform sampler2D texture3;
uniform sampler2D texture4;
uniform sampler2D texture5;
uniform sampler2D texture6;
uniform sampler2D texture7;
uniform sampler2D texture8;
// timer data
uniform float timer;
// material types
#if defined(SPECULAR)
#define normaltexture texture2
#define speculartexture texture3
#define brighttexture texture4
#define detailtexture texture5
#define glowtexture texture6
#elif defined(PBR)
#define normaltexture texture2
#define metallictexture texture3
#define roughnesstexture texture4
#define aotexture texture5
#define brighttexture texture6
#define detailtexture texture7
#define glowtexture texture8
#else
#define brighttexture texture2
#define detailtexture texture3
#define glowtexture texture4
#endif
)";
i_data += "uniform int uTextureMode;\n";
i_data += "uniform vec2 uClipSplit;\n";
i_data += "uniform float uAlphaThreshold;\n";
// colors
i_data += "uniform vec4 uObjectColor;\n";
i_data += "uniform vec4 uObjectColor2;\n";
i_data += "uniform vec4 uDynLightColor;\n";
i_data += "uniform vec4 uAddColor;\n";
i_data += "uniform vec4 uTextureBlendColor;\n";
i_data += "uniform vec4 uTextureModulateColor;\n";
i_data += "uniform vec4 uTextureAddColor;\n";
i_data += "uniform vec4 uBlendColor;\n";
i_data += "uniform vec4 uFogColor;\n";
i_data += "uniform float uDesaturationFactor;\n";
i_data += "uniform float uInterpolationFactor;\n";
// Glowing walls stuff
i_data += "uniform vec4 uGlowTopPlane;\n";
i_data += "uniform vec4 uGlowTopColor;\n";
i_data += "uniform vec4 uGlowBottomPlane;\n";
i_data += "uniform vec4 uGlowBottomColor;\n";
i_data += "uniform vec4 uGradientTopPlane;\n";
i_data += "uniform vec4 uGradientBottomPlane;\n";
i_data += "uniform vec4 uSplitTopPlane;\n";
i_data += "uniform vec4 uSplitBottomPlane;\n";
i_data += "uniform vec4 uDetailParms;\n";
// Lighting + Fog
i_data += "uniform vec4 uLightAttr;\n";
i_data += "#define uLightLevel uLightAttr.a\n";
i_data += "#define uFogDensity uLightAttr.b\n";
i_data += "#define uLightFactor uLightAttr.g\n";
i_data += "#define uLightDist uLightAttr.r\n";
i_data += "uniform int uFogEnabled;\n";
// dynamic lights
i_data += "uniform int uLightIndex;\n";
// Blinn glossiness and specular level
i_data += "uniform vec2 uSpecularMaterial;\n";
// matrices
i_data += "uniform mat4 ModelMatrix;\n";
i_data += "uniform mat4 NormalModelMatrix;\n";
i_data += "uniform mat4 TextureMatrix;\n";
// light buffers
i_data += "#ifdef SHADER_STORAGE_LIGHTS\n";
i_data += "layout(std430, binding = 1) buffer LightBufferSSO\n";
i_data += "{\n";
i_data += " vec4 lights[];\n";
i_data += "};\n";
i_data += "#elif defined NUM_UBO_LIGHTS\n";
i_data += "uniform LightBufferUBO\n";
i_data += "{\n";
i_data += " vec4 lights[NUM_UBO_LIGHTS];\n";
i_data += "};\n";
i_data += "#endif\n";
// textures
i_data += "uniform sampler2D tex;\n";
i_data += "uniform sampler2D ShadowMap;\n";
i_data += "uniform sampler2D texture2;\n";
i_data += "uniform sampler2D texture3;\n";
i_data += "uniform sampler2D texture4;\n";
i_data += "uniform sampler2D texture5;\n";
i_data += "uniform sampler2D texture6;\n";
i_data += "uniform sampler2D texture7;\n";
i_data += "uniform sampler2D texture8;\n";
// timer data
i_data += "uniform float timer;\n";
// material types
i_data += "#if defined(SPECULAR)\n";
i_data += "#define normaltexture texture2\n";
i_data += "#define speculartexture texture3\n";
i_data += "#define brighttexture texture4\n";
i_data += "#define detailtexture texture5\n";
i_data += "#define glowtexture texture6\n";
i_data += "#elif defined(PBR)\n";
i_data += "#define normaltexture texture2\n";
i_data += "#define metallictexture texture3\n";
i_data += "#define roughnesstexture texture4\n";
i_data += "#define aotexture texture5\n";
i_data += "#define brighttexture texture6\n";
i_data += "#define detailtexture texture7\n";
i_data += "#define glowtexture texture8\n";
i_data += "#else\n";
i_data += "#define brighttexture texture2\n";
i_data += "#define detailtexture texture3\n";
i_data += "#define glowtexture texture4\n";
i_data += "#endif\n";
#ifdef __APPLE__
// The noise functions are completely broken in macOS OpenGL drivers
@ -342,6 +344,10 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
i_data += "#define noise4(unused) vec4(0)\n";
#endif // __APPLE__
#ifdef NPOT_EMULATION
i_data += "#define NPOT_EMULATION\nuniform vec2 uNpotEmulation;\n";
#endif
int vp_lump = fileSystem.CheckNumForFullName(vert_prog_lump, 0);
if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump);
FileData vp_data = fileSystem.ReadFile(vp_lump);
@ -577,6 +583,9 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
muSplitBottomPlane.Init(hShader, "uSplitBottomPlane");
muSplitTopPlane.Init(hShader, "uSplitTopPlane");
muDetailParms.Init(hShader, "uDetailParms");
#ifdef NPOT_EMULATION
muNpotEmulation.Init(hShader, "uNpotEmulation");
#endif
muInterpolationFactor.Init(hShader, "uInterpolationFactor");
muAlphaThreshold.Init(hShader, "uAlphaThreshold");
muSpecularMaterial.Init(hShader, "uSpecularMaterial");

View file

@ -262,6 +262,9 @@ class FShader
FBufferedUniform1f muAlphaThreshold;
FBufferedUniform2f muSpecularMaterial;
FBufferedUniform1f muTimer;
#ifdef NPOT_EMULATION
FBufferedUniform2f muNpotEmulation;
#endif
int lights_index;
int modelmatrix_index;

View file

@ -4,6 +4,7 @@
#include "matrix.h"
#include "hw_material.h"
#include "texmanip.h"
#include "version.h"
struct FColormap;
class IVertexBuffer;
@ -198,6 +199,9 @@ struct StreamData
FVector4 uSplitBottomPlane;
FVector4 uDetailParms;
#ifdef NPOT_EMULATION
FVector2 uNpotEmulation;
#endif
};
class FRenderState
@ -289,7 +293,9 @@ public:
mStreamData.uSplitBottomPlane = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uDynLightColor = { 0.0f, 0.0f, 0.0f, 0.0f };
mStreamData.uDetailParms = { 0.0f, 0.0f, 0.0f, 0.0f };
#ifdef NPOT_EMULATION
mStreamData.uNpotEmulation = { 0,0 };
#endif
mModelMatrix.loadIdentity();
mTextureMatrix.loadIdentity();
ClearClipSplit();
@ -472,6 +478,13 @@ public:
mStreamData.uAddColor = pe;
}
void SetNpotEmulation(float factor, float offset)
{
#ifdef NPOT_EMULATION
mStreamData.uNpotEmulation = { offset, factor };
#endif
}
void ApplyTextureManipulation(TextureManipulation* texfx)
{
if (!texfx || texfx->AddColor.a == 0)

View file

@ -25,6 +25,7 @@
#include "hw_shaderpatcher.h"
#include "filesystem.h"
#include "engineerrors.h"
#include "version.h"
#include <ShaderLang.h>
VkShaderManager::VkShaderManager(VulkanDevice *device) : device(device)
@ -162,6 +163,9 @@ static const char *shaderBindings = R"(
vec4 uSplitBottomPlane;
vec4 uDetailParms;
#ifdef NPOT_EMULATION
vec2 uNpotEmulation;
#endif
};
layout(set = 0, binding = 3, std140) uniform StreamUBO {
@ -248,6 +252,7 @@ static const char *shaderBindings = R"(
#define uSplitTopPlane data[uDataIndex].uSplitTopPlane
#define uSplitBottomPlane data[uDataIndex].uSplitBottomPlane
#define uDetailParms data[uDataIndex].uDetailParms
#define uNpotEmulation data[uDataIndex].uNpotEmulation
#define SUPPORTS_SHADOWMAPS
#define VULKAN_COORDINATE_SYSTEM
@ -270,6 +275,9 @@ std::unique_ptr<VulkanShader> VkShaderManager::LoadVertShader(FString shadername
FString code = GetTargetGlslVersion();
code << defines;
code << "\n#define MAX_STREAM_DATA " << std::to_string(MAX_STREAM_DATA).c_str() << "\n";
#ifdef NPOT_EMULATION
code << "#define NPOT_EMULATION\n"
#endif
code << shaderBindings;
if (!device->UsedDeviceFeatures.shaderClipDistance) code << "#define NO_CLIPDISTANCE_SUPPORT\n";
code << "#line 1\n";

View file

@ -175,6 +175,10 @@ static const uint8_t renderwalltotier[] =
side_t::mid,
};
#ifdef NPOT_EMULATION
CVAR(Bool, hw_npottest, false, 0)
#endif
void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
{
int tmode = state.GetTextureMode();
@ -187,6 +191,23 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
SetGlowPlanes(state, frontsector->ceilingplane, frontsector->floorplane);
}
state.SetMaterial(texture, UF_Texture, 0, flags & 3, 0, -1);
#ifdef NPOT_EMULATION
// Test code, could be reactivated as a compatibility option in the unlikely event that some old vanilla map eve needs it.
if (hw_npottest)
{
int32_t size = xs_CRoundToInt(texture->GetDisplayHeight());
int32_t size2;
for (size2 = 1; size2 < size; size2 += size2) {}
if (size == size2)
state.SetNpotEmulation(0.f, 0.f);
else
{
float xOffset = 1.f / texture->GetDisplayWidth();
state.SetNpotEmulation((1.f * size2) / size, xOffset);
}
}
#endif
if (type == RENDERWALL_M2SNF)
{
@ -274,6 +295,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags)
state.EnableSplit(false);
}
state.SetNpotEmulation(0.f, 0.f);
state.SetObjectColor(0xffffffff);
state.SetObjectColor2(0);
state.SetAddColor(0);

View file

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