diff --git a/source/ps/GameSetup/GameSetup.cpp b/source/ps/GameSetup/GameSetup.cpp index 190ad36261..3ffbf6cf96 100644 --- a/source/ps/GameSetup/GameSetup.cpp +++ b/source/ps/GameSetup/GameSetup.cpp @@ -593,11 +593,11 @@ static void InitRenderer() // create renderer new CRenderer; - g_RenderingOptions.ReadConfig(); - // create terrain related stuff new CTerrainTextureManager; + g_RenderingOptions.ReadConfigAndSetupHooks(); + g_Renderer.Open(g_xres, g_yres); // Setup lighting environment. Since the Renderer accesses the @@ -695,6 +695,8 @@ void Shutdown(int flags) TIMER_END(L"shutdown Renderer"); } + g_RenderingOptions.ClearHooks(); + g_Profiler2.ShutdownGPU(); // Free cursors before shutting down SDL, as they may depend on SDL. diff --git a/source/renderer/PostprocManager.cpp b/source/renderer/PostprocManager.cpp index cb9525f8c6..8d49830942 100644 --- a/source/renderer/PostprocManager.cpp +++ b/source/renderer/PostprocManager.cpp @@ -591,7 +591,7 @@ void CPostprocManager::SetPostEffect(const CStrW& name) void CPostprocManager::UpdateAntiAliasingTechnique() { - if (!g_RenderingOptions.GetPreferGLSL()) + if (!g_RenderingOptions.GetPreferGLSL() || !m_IsInitialized) return; CStr newAAName; @@ -651,7 +651,7 @@ void CPostprocManager::UpdateAntiAliasingTechnique() void CPostprocManager::UpdateSharpeningTechnique() { - if (!g_RenderingOptions.GetPreferGLSL()) + if (!g_RenderingOptions.GetPreferGLSL() || !m_IsInitialized) return; CStr newSharpName; diff --git a/source/renderer/RenderingOptions.cpp b/source/renderer/RenderingOptions.cpp index d7ffbd98e9..0eb6f7fb79 100755 --- a/source/renderer/RenderingOptions.cpp +++ b/source/renderer/RenderingOptions.cpp @@ -33,7 +33,16 @@ class CRenderingOptions::ConfigHooks public: std::vector::iterator begin() { return hooks.begin(); } std::vector::iterator end() { return hooks.end(); } - void insert(CConfigDB::hook_t&& hook) { return hooks.emplace_back(std::move(hook)); } + template + void Setup(CStr8 name, T& variable) + { + hooks.emplace_back(g_ConfigDB.RegisterHookAndCall(name, [name, &variable]() { CFG_GET_VAL(name, variable); })); + } + void Setup(CStr8 name, std::function hook) + { + hooks.emplace_back(g_ConfigDB.RegisterHookAndCall(name, hook)); + } + void clear() { hooks.clear(); } private: std::vector hooks; }; @@ -95,89 +104,78 @@ CRenderingOptions::CRenderingOptions() : m_ConfigHooks(new ConfigHooks()) CRenderingOptions::~CRenderingOptions() { - // This is currently irrelevant since CConfigDB is deleted before CRenderingOptions - // (as only the latter is a static variable), but the check is a good idea regardless. - if (!CConfigDB::IsInitialised()) - return; - for (CConfigDB::hook_t& hook : *m_ConfigHooks) - g_ConfigDB.UnregisterHook(std::move(hook)); + ClearHooks(); } -template -void CRenderingOptions::SetupConfig(CStr8 name, T& variable) +void CRenderingOptions::ReadConfigAndSetupHooks() { - m_ConfigHooks->insert(g_ConfigDB.RegisterHookAndCall(name, [name, &variable]() { CFG_GET_VAL(name, variable); })); -} - -void CRenderingOptions::SetupConfig(CStr8 name, std::function hook) -{ - m_ConfigHooks->insert(g_ConfigDB.RegisterHookAndCall(name, hook)); -} - -void CRenderingOptions::ReadConfig() -{ - SetupConfig("preferglsl", [this]() { - bool enabled; - CFG_GET_VAL("preferglsl", enabled); - SetPreferGLSL(enabled); - }); - - SetupConfig("shadowquality", []() { - g_Renderer.GetShadowMap().RecreateTexture(); - }); - - SetupConfig("shadows", [this]() { - bool enabled; - CFG_GET_VAL("shadows", enabled); - SetShadows(enabled); - }); - SetupConfig("shadowpcf", [this]() { - bool enabled; - CFG_GET_VAL("shadowpcf", enabled); - SetShadowPCF(enabled); - }); - - SetupConfig("antialiasing", []() { - g_Renderer.GetPostprocManager().UpdateAntiAliasingTechnique(); - }); - - SetupConfig("sharpness", []() { - g_Renderer.GetPostprocManager().UpdateSharpnessFactor(); - }); - - SetupConfig("sharpening", []() { - g_Renderer.GetPostprocManager().UpdateSharpeningTechnique(); - }); - - SetupConfig("postproc", m_PostProc); - SetupConfig("smoothlos", m_SmoothLOS); - - SetupConfig("renderpath", [this]() { + m_ConfigHooks->Setup("renderpath", [this]() { CStr renderPath; CFG_GET_VAL("renderpath", renderPath); SetRenderPath(RenderPathEnum::FromString(renderPath)); }); - SetupConfig("watereffects", m_WaterEffects); - SetupConfig("waterfancyeffects", m_WaterFancyEffects); - SetupConfig("waterrealdepth", m_WaterRealDepth); - SetupConfig("waterrefraction", m_WaterRefraction); - SetupConfig("waterreflection", m_WaterReflection); - SetupConfig("watershadows", m_WaterShadows); + m_ConfigHooks->Setup("preferglsl", [this]() { + bool enabled; + CFG_GET_VAL("preferglsl", enabled); + SetPreferGLSL(enabled); + }); - SetupConfig("particles", m_Particles); - SetupConfig("fog", [this]() { + m_ConfigHooks->Setup("shadowquality", []() { + if (CRenderer::IsInitialised()) + g_Renderer.GetShadowMap().RecreateTexture(); + }); + + m_ConfigHooks->Setup("shadows", [this]() { + bool enabled; + CFG_GET_VAL("shadows", enabled); + SetShadows(enabled); + }); + m_ConfigHooks->Setup("shadowpcf", [this]() { + bool enabled; + CFG_GET_VAL("shadowpcf", enabled); + SetShadowPCF(enabled); + }); + + m_ConfigHooks->Setup("postproc", m_PostProc); + + m_ConfigHooks->Setup("antialiasing", []() { + if (CRenderer::IsInitialised()) + g_Renderer.GetPostprocManager().UpdateAntiAliasingTechnique(); + }); + + m_ConfigHooks->Setup("sharpness", []() { + if (CRenderer::IsInitialised()) + g_Renderer.GetPostprocManager().UpdateSharpnessFactor(); + }); + + m_ConfigHooks->Setup("sharpening", []() { + if (CRenderer::IsInitialised()) + g_Renderer.GetPostprocManager().UpdateSharpeningTechnique(); + }); + + m_ConfigHooks->Setup("smoothlos", m_SmoothLOS); + + m_ConfigHooks->Setup("watereffects", m_WaterEffects); + m_ConfigHooks->Setup("waterfancyeffects", m_WaterFancyEffects); + m_ConfigHooks->Setup("waterrealdepth", m_WaterRealDepth); + m_ConfigHooks->Setup("waterrefraction", m_WaterRefraction); + m_ConfigHooks->Setup("waterreflection", m_WaterReflection); + m_ConfigHooks->Setup("watershadows", m_WaterShadows); + + m_ConfigHooks->Setup("particles", m_Particles); + m_ConfigHooks->Setup("fog", [this]() { bool enabled; CFG_GET_VAL("fog", enabled); SetFog(enabled); }); - SetupConfig("silhouettes", m_Silhouettes); - SetupConfig("showsky", m_ShowSky); + m_ConfigHooks->Setup("silhouettes", m_Silhouettes); + m_ConfigHooks->Setup("showsky", m_ShowSky); - SetupConfig("novbo", m_NoVBO); + m_ConfigHooks->Setup("novbo", m_NoVBO); - SetupConfig("forcealphatest", m_ForceAlphaTest); - SetupConfig("gpuskinning", [this]() { + m_ConfigHooks->Setup("forcealphatest", m_ForceAlphaTest); + m_ConfigHooks->Setup("gpuskinning", [this]() { bool enabled; CFG_GET_VAL("gpuskinning", enabled); if (enabled && !m_PreferGLSL) @@ -186,25 +184,36 @@ void CRenderingOptions::ReadConfig() m_GPUSkinning = true; }); - SetupConfig("renderactors", m_RenderActors); + m_ConfigHooks->Setup("renderactors", m_RenderActors); +} + +void CRenderingOptions::ClearHooks() +{ + if (CConfigDB::IsInitialised()) + for (CConfigDB::hook_t& hook : *m_ConfigHooks) + g_ConfigDB.UnregisterHook(std::move(hook)); + m_ConfigHooks->clear(); } void CRenderingOptions::SetShadows(bool value) { m_Shadows = value; - g_Renderer.MakeShadersDirty(); + if (CRenderer::IsInitialised()) + g_Renderer.MakeShadersDirty(); } void CRenderingOptions::SetShadowPCF(bool value) { m_ShadowPCF = value; - g_Renderer.MakeShadersDirty(); + if (CRenderer::IsInitialised()) + g_Renderer.MakeShadersDirty(); } void CRenderingOptions::SetFog(bool value) { m_Fog = value; - g_Renderer.MakeShadersDirty(); + if (CRenderer::IsInitialised()) + g_Renderer.MakeShadersDirty(); } void CRenderingOptions::SetPreferGLSL(bool value) @@ -218,6 +227,8 @@ void CRenderingOptions::SetPreferGLSL(bool value) CFG_GET_VAL("gpuskinning", m_GPUSkinning); m_PreferGLSL = value; + if (!CRenderer::IsInitialised()) + return; g_Renderer.MakeShadersDirty(); g_Renderer.RecomputeSystemShaderDefines(); } @@ -226,5 +237,6 @@ void CRenderingOptions::SetPreferGLSL(bool value) void CRenderingOptions::SetRenderPath(RenderPath value) { m_RenderPath = value; - g_Renderer.SetRenderPath(m_RenderPath); + if (CRenderer::IsInitialised()) + g_Renderer.SetRenderPath(m_RenderPath); } diff --git a/source/renderer/RenderingOptions.h b/source/renderer/RenderingOptions.h index 121c45b3ca..f09252a7de 100755 --- a/source/renderer/RenderingOptions.h +++ b/source/renderer/RenderingOptions.h @@ -19,6 +19,9 @@ * Keeps track of the settings used for rendering. * Ideally this header file should remain very quick to parse, * so avoid including other headers here unless absolutely necessary. + * + * Lifetime concerns: g_RenderingOptions always exists, but hooks are tied to the configDB's lifetime + * an the renderer may or may not actually exist. */ #ifndef INCLUDED_RENDERINGOPTIONS @@ -55,7 +58,8 @@ public: CRenderingOptions(); ~CRenderingOptions(); - void ReadConfig(); + void ReadConfigAndSetupHooks(); + void ClearHooks(); #define OPTION_DEFAULT_SETTER(NAME, TYPE) \ public: void Set##NAME(TYPE value) { m_##NAME = value; }\ @@ -113,18 +117,6 @@ OPTION_CUSTOM_SETTER(NAME, TYPE); OPTION_GETTER(NAME, TYPE); OPTION_DEF(NAME, TY #undef OPTION_WITH_SIDE_EFFECT private: - /** - * Registers a config hook for config variable @name that updates @variable. - * Also immediately updates variable with the value of the config. - */ - template - void SetupConfig(CStr8 name, T& variable); - /** - * Registers a config hook for config variable @name. - * Also immediately triggers the hook. - */ - void SetupConfig(CStr8 name, std::function hook); - class ConfigHooks; std::unique_ptr m_ConfigHooks; // Hide this via PImpl to avoid including ConfigDB.h here. };