diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index 27263f62c..e3924ad40 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -153,6 +153,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 939140640..411b7fb69 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 2f1c97ee1..2dc4953cf 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 758f85435..c944f27c5 100644 --- a/src/gl/shaders/gl_shader.cpp +++ b/src/gl/shaders/gl_shader.cpp @@ -230,6 +230,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 e8012aa5d..f41f7467b 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 2da2dbcf9..fc119e65e 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 92c74e469..183f133dc 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 dcb397cb8..252acf2d6 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 366663880..01d241bb9 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 9aa8b4cb0..ead7d569b 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 8a938cc01..07fae0cbb 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/sound/musicformats/music_libsndfile.cpp b/src/sound/musicformats/music_libsndfile.cpp index 85b670a6b..fed79dcf0 100644 --- a/src/sound/musicformats/music_libsndfile.cpp +++ b/src/sound/musicformats/music_libsndfile.cpp @@ -339,18 +339,12 @@ bool SndFileSong::Read(SoundStream *stream, void *vbuff, int ilen, void *userdat if (currentpos + framestoread > song->Loop_End) { size_t endblock = (song->Loop_End - currentpos) * song->Channels * 2; - size_t endlen = song->Decoder->read(buff, 0 == endblock ? len : endblock); - if (endlen != 0) - { - buff = buff + endlen; - len -= endlen; - song->Decoder->seek(song->Loop_Start, false, true); - } - else - { - song->CritSec.Leave(); - return false; - } + size_t endlen = song->Decoder->read(buff, endblock); + + // Even if zero bytes was read give it a chance to start from the beginning + buff = buff + endlen; + len -= endlen; + song->Decoder->seek(song->Loop_Start, false, true); } while (len > 0) { diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index de1172740..93cfcb78f 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 eeb6fd36c..91b4dcdfb 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 685ce369c..022f2745f 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 9cfac4373..783fc8f0d 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/src/win32/hardware.cpp b/src/win32/hardware.cpp index 0fb64c008..2c5987726 100644 --- a/src/win32/hardware.cpp +++ b/src/win32/hardware.cpp @@ -56,6 +56,7 @@ EXTERN_CVAR (Bool, vid_forceddraw) CVAR(Int, win_x, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Int, win_y, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CVAR(Bool, win_maximized, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) extern HWND Window; @@ -382,6 +383,8 @@ void I_SaveWindowedPos () win_x = wrect.left; win_y = wrect.top; } + + win_maximized = IsZoomed(Window) == TRUE; } } @@ -409,6 +412,9 @@ void I_RestoreWindowedPos () KeepWindowOnScreen (winx, winy, winw, winh, scrwidth, scrheight); } MoveWindow (Window, winx, winy, winw, winh, TRUE); + + if (win_maximized && !Args->CheckParm("-0")) + ShowWindow(Window, SW_MAXIMIZE); } extern int NewWidth, NewHeight, NewBits, DisplayBits; diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 0c27e8cf0..d3fd31882 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 c109c8524..c8fcf7b6b 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;