From ddd1b629c343925be322112c097252f8819de6d9 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 9 Jul 2017 19:01:34 +0200 Subject: [PATCH] - Calculate globvis/r_visibility in r_utility and use it in GL and poly renderers --- src/gl/renderer/gl_renderer.h | 2 + src/gl/renderer/gl_renderstate.cpp | 1 + src/gl/scene/gl_scene.cpp | 4 +- src/gl/shaders/gl_shader.cpp | 1 + src/gl/shaders/gl_shader.h | 1 + src/polyrenderer/poly_renderer.cpp | 2 + src/polyrenderer/scene/poly_light.cpp | 10 ++-- src/polyrenderer/scene/poly_light.h | 15 +++--- src/r_renderer.h | 3 -- src/r_utility.cpp | 71 +++++++++++++++++++++++++ src/r_utility.h | 2 + src/swrenderer/r_swrenderer.cpp | 11 ---- src/swrenderer/r_swrenderer.h | 3 -- src/swrenderer/scene/r_light.cpp | 22 +------- src/swrenderer/viewport/r_viewport.cpp | 4 +- wadsrc/static/shaders/glsl/main.fp | 8 +-- wadsrc/static/shaders/glsl/shaderdefs.i | 1 + 17 files changed, 102 insertions(+), 59 deletions(-) diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 63168ff245..1db0f2db3b 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -151,6 +151,8 @@ public: float mSceneClearColor[3]; + float mGlobVis = 0.0f; + FGLRenderer(OpenGLFrameBuffer *fb); ~FGLRenderer() ; diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 9391406406..411b7fb691 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -151,6 +151,7 @@ bool FRenderState::ApplyShader() activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muFogEnabled.Set(fogset); activeShader->muPalLightLevels.Set(static_cast(gl_bandedswlight) | (static_cast(gl_fogmode) << 8)); + activeShader->muGlobVis.Set(GLRenderer->mGlobVis / 32.0f); activeShader->muTextureMode.Set(mTextureMode); activeShader->muCameraPos.Set(mCameraPos.vec); activeShader->muLightParms.Set(mLightParms); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 2f1c97ee1a..2dc4953cfc 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -83,7 +83,7 @@ CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) EXTERN_CVAR (Bool, cl_capfps) EXTERN_CVAR (Bool, r_deathcamera) EXTERN_CVAR (Float, underwater_fade_scalar) - +EXTERN_CVAR (Float, r_visibility) extern bool NoInterpolateView; @@ -785,6 +785,8 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f R_SetupFrame (r_viewpoint, r_viewwindow, camera); SetViewArea(); + GLRenderer->mGlobVis = R_GetGlobVis(r_viewwindow, r_visibility); + // We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1. double radPitch = r_viewpoint.Angles.Pitch.Normalized180().Radians(); double angx = cos(radPitch); diff --git a/src/gl/shaders/gl_shader.cpp b/src/gl/shaders/gl_shader.cpp index 2fdf9fbf33..69ac1b32a3 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -227,6 +227,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char * muDesaturation.Init(hShader, "uDesaturationFactor"); muFogEnabled.Init(hShader, "uFogEnabled"); muPalLightLevels.Init(hShader, "uPalLightLevels"); + muGlobVis.Init(hShader, "uGlobVis"); muTextureMode.Init(hShader, "uTextureMode"); muCameraPos.Init(hShader, "uCameraPos"); muLightParms.Init(hShader, "uLightAttr"); diff --git a/src/gl/shaders/gl_shader.h b/src/gl/shaders/gl_shader.h index e8012aa5d3..f41f7467bc 100644 --- a/src/gl/shaders/gl_shader.h +++ b/src/gl/shaders/gl_shader.h @@ -260,6 +260,7 @@ class FShader FBufferedUniform1f muDesaturation; FBufferedUniform1i muFogEnabled; FBufferedUniform1i muPalLightLevels; + FBufferedUniform1f muGlobVis; FBufferedUniform1i muTextureMode; FBufferedUniform4f muCameraPos; FBufferedUniform4f muLightParms; diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index 2da2dbcf93..fc119e65e2 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -40,6 +40,7 @@ EXTERN_CVAR(Bool, r_shadercolormaps) EXTERN_CVAR(Int, screenblocks) +EXTERN_CVAR(Float, r_visibility) void InitGLRMapinfoData(); ///////////////////////////////////////////////////////////////////////////// @@ -122,6 +123,7 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines) if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps; else NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS * 256 * R_OldBlend; + Light.SetVisibility(Viewwindow, r_visibility); PolyCameraLight::Instance()->SetCamera(Viewpoint, RenderTarget, actor); //Viewport->SetupFreelook(); diff --git a/src/polyrenderer/scene/poly_light.cpp b/src/polyrenderer/scene/poly_light.cpp index 92c74e4695..183f133dc8 100644 --- a/src/polyrenderer/scene/poly_light.cpp +++ b/src/polyrenderer/scene/poly_light.cpp @@ -27,6 +27,11 @@ #include "poly_light.h" #include "polyrenderer/poly_renderer.h" +void PolyLightVisibility::SetVisibility(FViewWindow &viewwindow, float vis) +{ + GlobVis = R_GetGlobVis(viewwindow, vis); +} + fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy) { bool nolightfade = !foggy && ((level.flags3 & LEVEL3_NOLIGHTFADE)); @@ -42,8 +47,3 @@ fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy) return (NUMCOLORMAPS * 2 * FRACUNIT) - ((lightlevel + 12) * (FRACUNIT*NUMCOLORMAPS / 128)); } } - -double PolyLightVisibility::FocalTangent() -{ - return PolyRenderer::Instance()->Viewwindow.FocalTangent; -} diff --git a/src/polyrenderer/scene/poly_light.h b/src/polyrenderer/scene/poly_light.h index dcb397cb82..252acf2d66 100644 --- a/src/polyrenderer/scene/poly_light.h +++ b/src/polyrenderer/scene/poly_light.h @@ -24,6 +24,8 @@ #include "swrenderer/scene/r_light.h" +struct FViewWindow; + // Keep using the software renderer's camera light class, for now. // The DFrameBuffer abstraction relies on this being globally shared typedef swrenderer::CameraLight PolyCameraLight; @@ -31,9 +33,11 @@ typedef swrenderer::CameraLight PolyCameraLight; class PolyLightVisibility { public: - double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); } - double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); } - double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility * 0.5 / FocalTangent(); } + void SetVisibility(FViewWindow &viewwindow, float vis); + + double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : GlobVis; } + double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : GlobVis; } + double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : GlobVis * 0.5; } // The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros double WallVis(double screenZ, bool foggy) const { return WallGlobVis(foggy) / screenZ; } @@ -43,9 +47,6 @@ public: static fixed_t LightLevelToShade(int lightlevel, bool foggy); private: - static double FocalTangent(); - - // 1706 is the value for walls on 1080p 16:9 displays. - double WallVisibility = 1706.0; + double GlobVis = 0.0f; bool NoLightFade = false; }; diff --git a/src/r_renderer.h b/src/r_renderer.h index 3666638801..01d241bb9c 100644 --- a/src/r_renderer.h +++ b/src/r_renderer.h @@ -54,9 +54,6 @@ struct FRenderer virtual void CleanLevelData() {} virtual bool RequireGLNodes() { return false; } - virtual double GetVisibility() { return 8.f; } - virtual void SetVisibility(double vis) { } - }; diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 9aa8b4cb02..ead7d569bf 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -278,6 +278,77 @@ void R_ExecuteSetViewSize (FRenderViewpoint &viewpoint, FViewWindow &viewwindow) viewwindowy = (viewwidth == screen->GetWidth()) ? 0 : (StatusBar->GetTopOfStatusbar() - viewheight) >> 1; } +//========================================================================== +// +// r_visibility +// +// Controls how quickly light ramps across a 1/z range. +// +//========================================================================== + +double R_ClampVisibility(double vis) +{ + // Allow negative visibilities, just for novelty's sake + return clamp(vis, -204.7, 204.7); // (205 and larger do not work in 5:4 aspect ratio) +} + +CUSTOM_CVAR(Float, r_visibility, 8.0f, CVAR_NOINITCALL) +{ + if (netgame && self != 8.0f) + { + Printf("Visibility cannot be changed in net games.\n"); + self = 8.0f; + } + else + { + float clampValue = (float)R_ClampVisibility(self); + if (self != clampValue) + self = clampValue; + } +} + +//========================================================================== +// +// R_GetGlobVis +// +// Calculates the global visibility constant used by the software renderer +// +//========================================================================== + +double R_GetGlobVis(const FViewWindow &viewwindow, double vis) +{ + vis = R_ClampVisibility(vis); + + double virtwidth = screen->GetWidth(); + double virtheight = screen->GetHeight(); + + if (AspectTallerThanWide(viewwindow.WidescreenRatio)) + { + virtheight = (virtheight * AspectMultiplier(viewwindow.WidescreenRatio)) / 48; + } + else + { + virtwidth = (virtwidth * AspectMultiplier(viewwindow.WidescreenRatio)) / 48; + } + + double YaspectMul = 320.0 * virtheight / (200.0 * virtwidth); + double InvZtoScale = YaspectMul * viewwindow.centerx; + + double wallVisibility = vis; + + // Prevent overflow on walls + double maxVisForWall = (InvZtoScale * (screen->GetWidth() * r_Yaspect) / (viewwidth * screen->GetHeight() * viewwindow.FocalTangent)); + maxVisForWall = 32767.0 / maxVisForWall; + if (vis < 0 && vis < -maxVisForWall) + wallVisibility = -maxVisForWall; + else if (vis > 0 && vis > maxVisForWall) + wallVisibility = maxVisForWall; + + wallVisibility = InvZtoScale * screen->GetWidth() * AspectBaseHeight(viewwindow.WidescreenRatio) / (viewwidth * screen->GetHeight() * 3) * (wallVisibility * viewwindow.FocalTangent); + + return wallVisibility / viewwindow.FocalTangent; +} + //========================================================================== // // CVAR screenblocks diff --git a/src/r_utility.h b/src/r_utility.h index 8a938cc01a..07fae0cbbd 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -122,6 +122,8 @@ void R_ExecuteSetViewSize (FRenderViewpoint &viewpoint, FViewWindow &viewwindow) void R_SetViewSize (int blocks); void R_SetWindow (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, int windowSize, int fullWidth, int fullHeight, int stHeight, bool renderingToCanvas = false); +double R_GetGlobVis(const FViewWindow &viewwindow, double vis); +double R_ClampVisibility(double vis); extern void R_FreePastViewers (); extern void R_ClearPastViewer (AActor *actor); diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index de1172740d..93cfcb78fa 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -378,14 +378,3 @@ void FSoftwareRenderer::PreprocessLevel() void FSoftwareRenderer::CleanLevelData() { } - -double FSoftwareRenderer::GetVisibility() -{ - return mScene.MainThread()->Light->GetVisibility(); -} - -void FSoftwareRenderer::SetVisibility(double vis) -{ - mScene.MainThread()->Light->SetVisibility(mScene.MainThread()->Viewport.get(), vis); -} - diff --git a/src/swrenderer/r_swrenderer.h b/src/swrenderer/r_swrenderer.h index eeb6fd36c0..91b4dcdfb8 100644 --- a/src/swrenderer/r_swrenderer.h +++ b/src/swrenderer/r_swrenderer.h @@ -35,9 +35,6 @@ struct FSoftwareRenderer : public FRenderer void PreprocessLevel() override; void CleanLevelData() override; - double GetVisibility() override; - void SetVisibility(double vis) override; - private: void PrecacheTexture(FTexture *tex, int cache); diff --git a/src/swrenderer/scene/r_light.cpp b/src/swrenderer/scene/r_light.cpp index 685ce369c2..022f2745fb 100644 --- a/src/swrenderer/scene/r_light.cpp +++ b/src/swrenderer/scene/r_light.cpp @@ -104,8 +104,7 @@ namespace swrenderer // Changes how rapidly things get dark with distance void LightVisibility::SetVisibility(RenderViewport *viewport, double vis) { - // Allow negative visibilities, just for novelty's sake - vis = clamp(vis, -204.7, 204.7); // (205 and larger do not work in 5:4 aspect ratio) + vis = R_ClampVisibility(vis); CurrentVisibility = vis; @@ -167,25 +166,6 @@ namespace swrenderer } } - // Controls how quickly light ramps across a 1/z range. Set this, and it - // sets all the r_*Visibility variables (except r_SkyVisibilily, which is - // currently unused). - CCMD(r_visibility) - { - if (argv.argc() < 2) - { - Printf("Visibility is %g\n", Renderer->GetVisibility()); - } - else if (!netgame) - { - Renderer->SetVisibility(atof(argv[1])); - } - else - { - Printf("Visibility cannot be changed in net games.\n"); - } - } - ///////////////////////////////////////////////////////////////////////// void ColormapLight::SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack) diff --git a/src/swrenderer/viewport/r_viewport.cpp b/src/swrenderer/viewport/r_viewport.cpp index 9cfac43736..783fc8f0df 100644 --- a/src/swrenderer/viewport/r_viewport.cpp +++ b/src/swrenderer/viewport/r_viewport.cpp @@ -46,6 +46,8 @@ CVAR(String, r_viewsize, "", CVAR_NOSET) +EXTERN_CVAR(Float, r_visibility); + namespace swrenderer { RenderViewport::RenderViewport() @@ -109,7 +111,7 @@ namespace swrenderer InitTextureMapping(); // Reset r_*Visibility vars - thread->Light->SetVisibility(this, thread->Light->GetVisibility()); + thread->Light->SetVisibility(this, r_visibility); SetupBuffer(); } diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 0c27e8cf0b..d3fd31882a 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -103,12 +103,6 @@ vec4 getTexel(vec2 st) //=========================================================================== float R_DoomLightingEquation(float light) { - // globVis = WallVisibility / r_viewwindow.FocalTangent / 32.0 - // - // WallVisibility is calculated in LightVisibility::SetVisibility - // 1706 is the default value for WallVisibility on 1080p 16:9 displays. - float globVis = 1706.0 / 1.3333333333333333 / 32.0; - // L is the integer light level used in the game float L = light * 255.0; @@ -124,7 +118,7 @@ float R_DoomLightingEquation(float light) } // The zdoom light equation - float vis = min(globVis / z, 24.0 / 32.0); + float vis = min(uGlobVis / z, 24.0 / 32.0); float shade = 2.0 - (L + 12.0) / 128.0; float lightscale; if ((uPalLightLevels & 0xff) != 0) diff --git a/wadsrc/static/shaders/glsl/shaderdefs.i b/wadsrc/static/shaders/glsl/shaderdefs.i index c109c8524a..c8fcf7b6b3 100644 --- a/wadsrc/static/shaders/glsl/shaderdefs.i +++ b/wadsrc/static/shaders/glsl/shaderdefs.i @@ -43,6 +43,7 @@ uniform vec4 uLightAttr; #define uLightDist uLightAttr.r uniform int uFogEnabled; uniform int uPalLightLevels; +uniform float uGlobVis; // uGlobVis = R_GetGlobVis(r_visibility) / 32.0 // dynamic lights uniform int uLightIndex;