From cdc0bf1cd501e88733fd7f7dd4f644a0a0e4c1d2 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Fri, 2 Jun 2017 16:57:37 -0400 Subject: [PATCH 1/9] - condense all of unloved/2.pk3's compatibility entries together since they are all the same --- wadsrc/static/compatibility.txt | 36 --------------------------------- 1 file changed, 36 deletions(-) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 2e9a7f1f4a..8863326e12 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -649,50 +649,14 @@ B68EB7CFB4CC481796E2919B9C16DFBD // Moc11.wad e1m6 } 1ED329858AB154C55878DA1C11A4F100 // unloved.pk3:unlovedmaps.wad map01 -{ - clipmidtex -} - FA23E72FA955E66EC68609F72C0BA71E // unloved.pk3:unlovedmaps.wad map02 -{ - clipmidtex -} - 41BEC1F643CFEEC997AF98276A05EC88 // unloved.pk3:unlovedmaps.wad map03 -{ - clipmidtex -} - AF9A6370BE562584BC11165ECF364713 // unloved.pk3:unlovedmaps.wad map04 -{ - clipmidtex -} - DC96228097DD004C40CCB1DB14A91EAA // unloved.pk3:unlovedmaps.wad map05 -{ - clipmidtex -} - 261E64897A572C8DB8DC041E64BE27AD // unloved2beta1.pk3:u2_new2maps2.wad map06 -{ - clipmidtex -} - 04800B1F35E8C036EBABC8C616402927 // unloved2beta1.pk3:u2_new2maps2.wad map07 -{ - clipmidtex -} - 9E54F70648A77BBD090FF78A3AA05367 // unloved2beta1.pk3:u2_new2maps2.wad map08 -{ - clipmidtex -} - 72E9E0F41F691B7F956E62F35B4A617F // unloved2beta1.pk3:u2_new2maps2.wad map09 -{ - clipmidtex -} - 3D3FE412E87AD8B2316DAEC9E25F2E5D // unloved2beta1.pk3:u2_new2maps2.wad map10 { clipmidtex From f593e2aa3c9252dff1c1f71916e457c36388ad42 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 3 Jun 2017 16:58:09 +0200 Subject: [PATCH 2/9] - Fix stat output to use the console scale --- src/stats.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/stats.cpp b/src/stats.cpp index d0d5d2f022..d4c1d37dfa 100644 --- a/src/stats.cpp +++ b/src/stats.cpp @@ -89,8 +89,10 @@ void FStat::ToggleStat () void FStat::PrintStat () { + int textScale = active_con_scale(); + int fontheight = ConFont->GetHeight() + 1; - int y = SCREENHEIGHT; + int y = SCREENHEIGHT / textScale; int count = 0; for (FStat *stat = FirstStat; stat != NULL; stat = stat->m_Next) @@ -107,7 +109,10 @@ void FStat::PrintStat () // Count number of linefeeds but ignore terminating ones. if (stattext[i] == '\n') y -= fontheight; } - screen->DrawText(ConFont, CR_GREEN, 5, y, stattext, TAG_DONE); + screen->DrawText(ConFont, CR_GREEN, 5 / textScale, y, stattext, + DTA_VirtualWidth, screen->GetWidth() / textScale, + DTA_VirtualHeight, screen->GetHeight() / textScale, + DTA_KeepRatio, true, TAG_DONE); count++; } } From 2c7a0c87c860bd66fd9b892369fef45728829949 Mon Sep 17 00:00:00 2001 From: jplebreton Date: Sat, 3 Jun 2017 08:42:57 -0700 Subject: [PATCH 3/9] add FloatBobStrength Actor property, a multiplier on Z offset created by FloatBob behavior. default of 1.0 is current behavior, set higher/lower for more/less extreme bobbing. --- src/actor.h | 1 + src/namedef.h | 1 + src/p_mobj.cpp | 4 +++- src/scripting/thingdef_properties.cpp | 9 +++++++++ wadsrc/static/zscript/actor.txt | 2 ++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/actor.h b/src/actor.h index be3f28ec61..b1cf58676f 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1169,6 +1169,7 @@ public: uint8_t smokecounter; uint8_t FloatBobPhase; + double FloatBobStrength; uint8_t FriendPlayer; // [RH] Player # + 1 this friendly monster works for (so 0 is no player, 1 is player 0, etc) PalEntry BloodColor; uint32_t BloodTranslation; diff --git a/src/namedef.h b/src/namedef.h index a22a5de5f0..c2c23f497a 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -503,6 +503,7 @@ xx(Scale) xx(ScaleX) xx(ScaleY) xx(Floatbobphase) +xx(Floatbobstrength) xx(Target) xx(Master) xx(Tracer) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 54be4a2deb..fc0abc373e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -282,6 +282,7 @@ DEFINE_FIELD(AActor, Floorclip) DEFINE_FIELD(AActor, DamageType) DEFINE_FIELD(AActor, DamageTypeReceived) DEFINE_FIELD(AActor, FloatBobPhase) +DEFINE_FIELD(AActor, FloatBobStrength) DEFINE_FIELD(AActor, RipperLevel) DEFINE_FIELD(AActor, RipLevelMin) DEFINE_FIELD(AActor, RipLevelMax) @@ -443,6 +444,7 @@ void AActor::Serialize(FSerializer &arc) ("inventory", Inventory) A("inventoryid", InventoryID) A("floatbobphase", FloatBobPhase) + A("floatbobstrength", FloatBobStrength) A("translation", Translation) A("bloodcolor", BloodColor) A("bloodtranslation", BloodTranslation) @@ -7988,7 +7990,7 @@ double AActor::GetBobOffset(double ticfrac) const { return 0; } - return BobSin(FloatBobPhase + level.maptime + ticfrac); + return BobSin(FloatBobPhase + level.maptime + ticfrac) * FloatBobStrength; } DEFINE_ACTION_FUNCTION(AActor, GetBobOffset) diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 170fa11483..d10f505173 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -653,6 +653,15 @@ DEFINE_PROPERTY(floatbobphase, I, Actor) defaults->FloatBobPhase = id; } +//========================================================================== +// +//========================================================================== +DEFINE_PROPERTY(floatbobstrength, F, Actor) +{ + PROP_DOUBLE_PARM(id, 0); + defaults->FloatBobStrength = id; +} + //========================================================================== // //========================================================================== diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 49d2944650..3195f18cf0 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -131,6 +131,7 @@ class Actor : Thinker native native name DamageType; native name DamageTypeReceived; native uint8 FloatBobPhase; + native double FloatBobStrength; native int RipperLevel; native int RipLevelMin; native int RipLevelMax; @@ -325,6 +326,7 @@ class Actor : Thinker native BounceCount -1; FloatSpeed 4; FloatBobPhase -1; // randomly initialize by default + FloatBobStrength 1.0; Gravity 1; Friction 1; DamageFactor 1.0; // damage multiplier as target of damage. From d38dae5de8ba7a98cc50e73d6c9d9bea5a04a86a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 3 Jun 2017 18:14:24 +0200 Subject: [PATCH 4/9] - Add gpu stat that displays how much time the GPU spent on named GL groups --- src/gl/system/gl_debug.cpp | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/gl/system/gl_debug.cpp b/src/gl/system/gl_debug.cpp index 22bbf597b0..f65b5d3079 100644 --- a/src/gl/system/gl_debug.cpp +++ b/src/gl/system/gl_debug.cpp @@ -29,8 +29,10 @@ #include "gl/system/gl_system.h" #include "gl/system/gl_interface.h" #include "gl/system/gl_debug.h" +#include "stats.h" #include #include +#include #ifndef _MSC_VER #include @@ -46,6 +48,20 @@ CUSTOM_CVAR(Int, gl_debug_level, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN CVAR(Bool, gl_debug_breakpoint, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); +namespace +{ + bool gpuStatActive = false; + bool keepGpuStatActive = false; + std::vector> timeElapsedQueries; + FString gpuStatOutput; +} + +ADD_STAT(gpu) +{ + keepGpuStatActive = true; + return gpuStatOutput; +} + //----------------------------------------------------------------------------- // // Updates OpenGL debugging state @@ -54,6 +70,22 @@ CVAR(Bool, gl_debug_breakpoint, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); void FGLDebug::Update() { + gpuStatOutput = ""; + for (auto &query : timeElapsedQueries) + { + GLuint timeElapsed = 0; + glGetQueryObjectuiv(query.second, GL_QUERY_RESULT, &timeElapsed); + glDeleteQueries(1, &query.second); + + FString out; + out.Format("%s=%04.2f ms\n", query.first.GetChars(), timeElapsed / 1000000.0f); + gpuStatOutput += out; + } + timeElapsedQueries.clear(); + + gpuStatActive = keepGpuStatActive; + keepGpuStatActive = false; + if (!HasDebugApi()) return; @@ -98,6 +130,14 @@ void FGLDebug::PushGroup(const FString &name) { glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, (GLsizei)name.Len(), name.GetChars()); } + + if (gpuStatActive) + { + GLuint queryHandle = 0; + glGenQueries(1, &queryHandle); + glBeginQuery(GL_TIME_ELAPSED, queryHandle); + timeElapsedQueries.push_back({ name, queryHandle }); + } } void FGLDebug::PopGroup() @@ -106,6 +146,11 @@ void FGLDebug::PopGroup() { glPopDebugGroup(); } + + if (gpuStatActive) + { + glEndQuery(GL_TIME_ELAPSED); + } } //----------------------------------------------------------------------------- From 7edb75d2992a950736a370666a6da8e91902bf16 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 3 Jun 2017 18:28:12 +0200 Subject: [PATCH 5/9] - The mandatory include compile error fix for unix --- src/gl/system/gl_debug.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/system/gl_debug.cpp b/src/gl/system/gl_debug.cpp index f65b5d3079..1fca45f0ca 100644 --- a/src/gl/system/gl_debug.cpp +++ b/src/gl/system/gl_debug.cpp @@ -32,7 +32,7 @@ #include "stats.h" #include #include -#include +#include #ifndef _MSC_VER #include From 797cb94b4fd015a6ca361bcefad7a5be825ab46a Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 3 Jun 2017 19:24:54 +0200 Subject: [PATCH 6/9] - Add stat shadowmap to get performance for the upload part of the shadow maps --- src/gl/dynlights/gl_shadowmap.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/gl/dynlights/gl_shadowmap.cpp b/src/gl/dynlights/gl_shadowmap.cpp index 609e09e641..81ed1af737 100644 --- a/src/gl/dynlights/gl_shadowmap.cpp +++ b/src/gl/dynlights/gl_shadowmap.cpp @@ -33,6 +33,7 @@ #include "gl/shaders/gl_shadowmapshader.h" #include "r_state.h" #include "g_levellocals.h" +#include "stats.h" /* The 1D shadow maps are stored in a 1024x1024 texture as float depth values (R32F). @@ -67,11 +68,31 @@ as on the CPU, except everything uses indexes as pointers are not allowed in GLSL. */ +namespace +{ + cycle_t UpdateCycles; + int LightsProcessed; + int LightsShadowmapped; +} + +ADD_STAT(shadowmap) +{ + FString out; + out.Format("upload=%04.2f ms lights=%d shadowmapped=%d", UpdateCycles.TimeMS(), LightsProcessed, LightsShadowmapped); + return out; +} + void FShadowMap::Update() { + UpdateCycles.Reset(); + LightsProcessed = 0; + LightsShadowmapped = 0; + if (!IsEnabled()) return; + UpdateCycles.Clock(); + UploadAABBTree(); UploadLights(); @@ -98,6 +119,8 @@ void FShadowMap::Update() GLRenderer->mBuffers->BindShadowMapTexture(16); FGLDebug::PopGroup(); + + UpdateCycles.Unclock(); } bool FShadowMap::ShadowTest(ADynamicLight *light, const DVector3 &pos) @@ -133,8 +156,11 @@ void FShadowMap::UploadLights() TThinkerIterator it(STAT_DLIGHT); while (auto light = it.Next()) { + LightsProcessed++; if (light->shadowmapped) { + LightsShadowmapped++; + mLightToShadowmap[light] = lightindex >> 2; mLights[lightindex] = light->X(); From 1df7dc81e6aa857cd0275abfcbd05913f5d9afa6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 2 Jun 2017 10:05:39 +0200 Subject: [PATCH 7/9] - fixed: The statusbar's MustDrawLog method was called with an incorrect number of parameters. --- src/g_statusbar/shared_sbar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 2710c5156d..30bc5f1df1 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -1079,7 +1079,7 @@ bool DBaseStatusBar::MustDrawLog(EHudState state) { IFVIRTUAL(DBaseStatusBar, MustDrawLog) { - VMValue params[] = { (DObject*)this }; + VMValue params[] = { (DObject*)this, int(state) }; int rv; VMReturn ret(&rv); VMCall(func, params, countof(params), &ret, 1); From 265df4b79702fa655aac4abc28578f98d30fcdc3 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 3 Jun 2017 21:19:34 +0200 Subject: [PATCH 8/9] - Change shadowmap resolution from 1024 to 128 --- src/gl/dynlights/gl_shadowmap.cpp | 2 +- src/gl/dynlights/gl_shadowmap.h | 4 ++++ src/gl/renderer/gl_renderbuffers.cpp | 2 +- wadsrc/static/shaders/glsl/shadowmap.fp | 14 +++++++++----- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/gl/dynlights/gl_shadowmap.cpp b/src/gl/dynlights/gl_shadowmap.cpp index 81ed1af737..1585aec82b 100644 --- a/src/gl/dynlights/gl_shadowmap.cpp +++ b/src/gl/dynlights/gl_shadowmap.cpp @@ -106,7 +106,7 @@ void FShadowMap::Update() glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer); - glViewport(0, 0, 1024, 1024); + glViewport(0, 0, SHADOWMAP_QUALITY, 1024); GLRenderer->RenderScreenQuad(); const auto &viewport = GLRenderer->mScreenViewport; diff --git a/src/gl/dynlights/gl_shadowmap.h b/src/gl/dynlights/gl_shadowmap.h index 281936f80e..d6a68198cb 100644 --- a/src/gl/dynlights/gl_shadowmap.h +++ b/src/gl/dynlights/gl_shadowmap.h @@ -8,6 +8,10 @@ class ADynamicLight; struct level_info_t; +// This constant must match the same constant in shadowmap.fp +//#define SHADOWMAP_QUALITY 1024 +#define SHADOWMAP_QUALITY 128 + class FShadowMap { public: diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index 74dc36e729..fbc8294b13 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -770,7 +770,7 @@ void FGLRenderBuffers::CreateShadowMap() glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding); - mShadowMapTexture = Create2DTexture("ShadowMap", GL_R32F, 1024, 1024); + mShadowMapTexture = Create2DTexture("ShadowMap", GL_R32F, SHADOWMAP_QUALITY, 1024); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); diff --git a/wadsrc/static/shaders/glsl/shadowmap.fp b/wadsrc/static/shaders/glsl/shadowmap.fp index 194da954ef..9e4efdd4e5 100644 --- a/wadsrc/static/shaders/glsl/shadowmap.fp +++ b/wadsrc/static/shaders/glsl/shadowmap.fp @@ -2,6 +2,10 @@ in vec2 TexCoord; out vec4 FragColor; +// This constant must match the same constant in gl_shadowmap.h +// #define SHADOWMAP_QUALITY 1024 +#define SHADOWMAP_QUALITY 128 + struct GPUNode { vec2 aabb_min; @@ -140,12 +144,12 @@ void main() if (radius > 0.0) { vec2 pixelpos; - switch (int(gl_FragCoord.x) / 256) + switch (int(gl_FragCoord.x) / int(SHADOWMAP_QUALITY/4)) { - case 0: pixelpos = vec2((gl_FragCoord.x - 128.0) / 128.0, 1.0); break; - case 1: pixelpos = vec2(1.0, (gl_FragCoord.x - 384.0) / 128.0); break; - case 2: pixelpos = vec2(-(gl_FragCoord.x - 640.0) / 128.0, -1.0); break; - case 3: pixelpos = vec2(-1.0, -(gl_FragCoord.x - 896.0) / 128.0); break; + case 0: pixelpos = vec2((gl_FragCoord.x - float(SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8), 1.0); break; + case 1: pixelpos = vec2(1.0, (gl_FragCoord.x - float(SHADOWMAP_QUALITY/4 + SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8)); break; + case 2: pixelpos = vec2(-(gl_FragCoord.x - float(SHADOWMAP_QUALITY/2 + SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8), -1.0); break; + case 3: pixelpos = vec2(-1.0, -(gl_FragCoord.x - float(SHADOWMAP_QUALITY*3/4 + SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8)); break; } pixelpos = lightpos + pixelpos * radius; From 7acb492852a91b6861c66906158cf91a240fde43 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 4 Jun 2017 00:44:49 +0200 Subject: [PATCH 9/9] - Add gl_shadowmap_quality cvar that controls the resolution of the 1D shadow map texture --- src/gl/dynlights/gl_shadowmap.cpp | 20 +++++++++++++++++++- src/gl/dynlights/gl_shadowmap.h | 4 ---- src/gl/renderer/gl_renderbuffers.cpp | 16 ++++++++++++++-- src/gl/renderer/gl_renderbuffers.h | 2 ++ src/gl/shaders/gl_shadowmapshader.cpp | 1 + src/gl/shaders/gl_shadowmapshader.h | 2 ++ src/gl/system/gl_cvars.h | 1 + wadsrc/static/shaders/glsl/shadowmap.fp | 15 ++++++++------- 8 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/gl/dynlights/gl_shadowmap.cpp b/src/gl/dynlights/gl_shadowmap.cpp index 1585aec82b..0f493b7517 100644 --- a/src/gl/dynlights/gl_shadowmap.cpp +++ b/src/gl/dynlights/gl_shadowmap.cpp @@ -82,6 +82,23 @@ ADD_STAT(shadowmap) return out; } +CUSTOM_CVAR(Int, gl_shadowmap_quality, 128, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +{ + switch (self) + { + case 32: + case 64: + case 128: + case 256: + case 512: + case 1024: + break; + default: + self = 128; + break; + } +} + void FShadowMap::Update() { UpdateCycles.Reset(); @@ -102,11 +119,12 @@ void FShadowMap::Update() GLRenderer->mBuffers->BindShadowMapFB(); GLRenderer->mShadowMapShader->Bind(); + GLRenderer->mShadowMapShader->ShadowmapQuality.Set(gl_shadowmap_quality); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, mLightList); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, mNodesBuffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, mLinesBuffer); - glViewport(0, 0, SHADOWMAP_QUALITY, 1024); + glViewport(0, 0, gl_shadowmap_quality, 1024); GLRenderer->RenderScreenQuad(); const auto &viewport = GLRenderer->mScreenViewport; diff --git a/src/gl/dynlights/gl_shadowmap.h b/src/gl/dynlights/gl_shadowmap.h index d6a68198cb..281936f80e 100644 --- a/src/gl/dynlights/gl_shadowmap.h +++ b/src/gl/dynlights/gl_shadowmap.h @@ -8,10 +8,6 @@ class ADynamicLight; struct level_info_t; -// This constant must match the same constant in shadowmap.fp -//#define SHADOWMAP_QUALITY 1024 -#define SHADOWMAP_QUALITY 128 - class FShadowMap { public: diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index fbc8294b13..d60045f3e3 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -81,6 +81,7 @@ FGLRenderBuffers::~FGLRenderBuffers() ClearBloom(); ClearExposureLevels(); ClearAmbientOcclusion(); + ClearShadowMap(); } void FGLRenderBuffers::ClearScene() @@ -759,18 +760,27 @@ void FGLRenderBuffers::BindShadowMapTexture(int texunit) glBindTexture(GL_TEXTURE_2D, mShadowMapTexture); } +void FGLRenderBuffers::ClearShadowMap() +{ + DeleteFrameBuffer(mShadowMapFB); + DeleteTexture(mShadowMapTexture); + mCurrentShadowMapSize = 0; +} + void FGLRenderBuffers::CreateShadowMap() { - if (mShadowMapTexture != 0) + if (mShadowMapTexture != 0 && gl_shadowmap_quality == mCurrentShadowMapSize) return; + ClearShadowMap(); + GLint activeTex, textureBinding, frameBufferBinding; glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTex); glActiveTexture(GL_TEXTURE0); glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding); - mShadowMapTexture = Create2DTexture("ShadowMap", GL_R32F, SHADOWMAP_QUALITY, 1024); + mShadowMapTexture = Create2DTexture("ShadowMap", GL_R32F, gl_shadowmap_quality, 1024); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -781,6 +791,8 @@ void FGLRenderBuffers::CreateShadowMap() glBindTexture(GL_TEXTURE_2D, textureBinding); glActiveTexture(activeTex); glBindFramebuffer(GL_FRAMEBUFFER, frameBufferBinding); + + mCurrentShadowMapSize = gl_shadowmap_quality; } //========================================================================== diff --git a/src/gl/renderer/gl_renderbuffers.h b/src/gl/renderer/gl_renderbuffers.h index 5df3bcca05..c6aec6286c 100644 --- a/src/gl/renderer/gl_renderbuffers.h +++ b/src/gl/renderer/gl_renderbuffers.h @@ -87,6 +87,7 @@ private: void ClearBloom(); void ClearExposureLevels(); void ClearAmbientOcclusion(); + void ClearShadowMap(); void CreateScene(int width, int height, int samples, bool needsSceneTextures); void CreatePipeline(int width, int height); void CreateBloom(int width, int height); @@ -140,6 +141,7 @@ private: // Shadow map texture GLuint mShadowMapTexture = 0; GLuint mShadowMapFB = 0; + int mCurrentShadowMapSize = 0; static bool FailedCreate; static bool BuffersActive; diff --git a/src/gl/shaders/gl_shadowmapshader.cpp b/src/gl/shaders/gl_shadowmapshader.cpp index 674d0a04f2..8b81d386ae 100644 --- a/src/gl/shaders/gl_shadowmapshader.cpp +++ b/src/gl/shaders/gl_shadowmapshader.cpp @@ -40,6 +40,7 @@ void FShadowMapShader::Bind() mShader.SetFragDataLocation(0, "FragColor"); mShader.Link("shaders/glsl/shadowmap"); mShader.SetAttribLocation(0, "PositionInProjection"); + ShadowmapQuality.Init(mShader, "ShadowmapQuality"); } mShader.Bind(); } diff --git a/src/gl/shaders/gl_shadowmapshader.h b/src/gl/shaders/gl_shadowmapshader.h index 7d01f9974a..309dccb525 100644 --- a/src/gl/shaders/gl_shadowmapshader.h +++ b/src/gl/shaders/gl_shadowmapshader.h @@ -8,6 +8,8 @@ class FShadowMapShader public: void Bind(); + FBufferedUniform1f ShadowmapQuality; + private: FShaderProgram mShader; }; diff --git a/src/gl/system/gl_cvars.h b/src/gl/system/gl_cvars.h index b7122b01c3..51ab642de7 100644 --- a/src/gl/system/gl_cvars.h +++ b/src/gl/system/gl_cvars.h @@ -27,6 +27,7 @@ EXTERN_CVAR (Bool, gl_lights_checkside); EXTERN_CVAR (Bool, gl_light_sprites); EXTERN_CVAR (Bool, gl_light_particles); EXTERN_CVAR (Bool, gl_light_shadowmap); +EXTERN_CVAR (Int, gl_shadowmap_quality); EXTERN_CVAR(Int, gl_fogmode) EXTERN_CVAR(Int, gl_lightmode) diff --git a/wadsrc/static/shaders/glsl/shadowmap.fp b/wadsrc/static/shaders/glsl/shadowmap.fp index 9e4efdd4e5..47696aa74d 100644 --- a/wadsrc/static/shaders/glsl/shadowmap.fp +++ b/wadsrc/static/shaders/glsl/shadowmap.fp @@ -3,8 +3,9 @@ in vec2 TexCoord; out vec4 FragColor; // This constant must match the same constant in gl_shadowmap.h -// #define SHADOWMAP_QUALITY 1024 -#define SHADOWMAP_QUALITY 128 +// #define ShadowmapQuality 1024 +//#define ShadowmapQuality 128 +uniform float ShadowmapQuality; struct GPUNode { @@ -144,12 +145,12 @@ void main() if (radius > 0.0) { vec2 pixelpos; - switch (int(gl_FragCoord.x) / int(SHADOWMAP_QUALITY/4)) + switch (int(gl_FragCoord.x) / int(ShadowmapQuality/4.0)) { - case 0: pixelpos = vec2((gl_FragCoord.x - float(SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8), 1.0); break; - case 1: pixelpos = vec2(1.0, (gl_FragCoord.x - float(SHADOWMAP_QUALITY/4 + SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8)); break; - case 2: pixelpos = vec2(-(gl_FragCoord.x - float(SHADOWMAP_QUALITY/2 + SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8), -1.0); break; - case 3: pixelpos = vec2(-1.0, -(gl_FragCoord.x - float(SHADOWMAP_QUALITY*3/4 + SHADOWMAP_QUALITY/8)) / float(SHADOWMAP_QUALITY/8)); break; + case 0: pixelpos = vec2((gl_FragCoord.x - float(ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0), 1.0); break; + case 1: pixelpos = vec2(1.0, (gl_FragCoord.x - float(ShadowmapQuality/4.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0)); break; + case 2: pixelpos = vec2(-(gl_FragCoord.x - float(ShadowmapQuality/2.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0), -1.0); break; + case 3: pixelpos = vec2(-1.0, -(gl_FragCoord.x - float(ShadowmapQuality*3.0/4.0 + ShadowmapQuality/8.0)) / float(ShadowmapQuality/8.0)); break; } pixelpos = lightpos + pixelpos * radius;