diff --git a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp index 1524f72a591..698475ef628 100644 --- a/src/Layers/xrRenderPC_GL/xrRender_GL.cpp +++ b/src/Layers/xrRenderPC_GL/xrRender_GL.cpp @@ -65,6 +65,20 @@ class RGLRendererModule final : public RendererModule #endif xrRender_initconsole(); } + + void ClearEnv() override + { + modes.clear(); + + if (GEnv.Render == &RImplementation) + { + GEnv.Render = nullptr; + GEnv.RenderFactory = nullptr; + GEnv.DU = nullptr; + GEnv.UIRender = nullptr; + GEnv.DRender = nullptr; + } + } } static s_rgl_module; extern "C" diff --git a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp index b68691348c0..4ba5a90d49a 100644 --- a/src/Layers/xrRenderPC_R4/xrRender_R4.cpp +++ b/src/Layers/xrRenderPC_R4/xrRender_R4.cpp @@ -101,6 +101,20 @@ class R4RendererModule final : public RendererModule #endif xrRender_initconsole(); } + + void ClearEnv() override + { + modes.clear(); + + if (GEnv.Render == &RImplementation) + { + GEnv.Render = nullptr; + GEnv.RenderFactory = nullptr; + GEnv.DU = nullptr; + GEnv.UIRender = nullptr; + GEnv.DRender = nullptr; + } + } } static s_r4_module; extern "C" diff --git a/src/xrEngine/EngineAPI.cpp b/src/xrEngine/EngineAPI.cpp index b599d2205a0..2b0b3ee1b28 100644 --- a/src/xrEngine/EngineAPI.cpp +++ b/src/xrEngine/EngineAPI.cpp @@ -101,8 +101,10 @@ void CEngineAPI::SelectRenderer() } } - // Ask current renderer to setup GEnv + CloseUnusedLibraries(); R_ASSERT2(selectedRenderer, "Can't setup renderer"); + + // Ask current renderer to setup GEnv selectedRenderer->SetupEnv(selected_mode); Log("Selected renderer:", selected_mode); @@ -121,8 +123,6 @@ void CEngineAPI::Initialize(GameModule* game) R_ASSERT(pCreate); R_ASSERT(pDestroy); } - - CloseUnusedLibraries(); } void CEngineAPI::Destroy() @@ -132,19 +132,28 @@ void CEngineAPI::Destroy() if (gameModule) gameModule->finalize(); + selectedRenderer = nullptr; + CloseUnusedLibraries(); + pCreate = nullptr; pDestroy = nullptr; XRC.r_clear_compact(); } -void CEngineAPI::CloseUnusedLibraries() +void CEngineAPI::CloseUnusedLibraries() const { ZoneScoped; - for (RendererDesc& desc : g_render_modules) + for (auto& [_, handle, module] : g_render_modules) { - if (desc.module != selectedRenderer) - desc.handle = nullptr; + if (!handle) + continue; + if (module == selectedRenderer) + continue; + + module->ClearEnv(); + module = nullptr; + handle = nullptr; } } diff --git a/src/xrEngine/EngineAPI.h b/src/xrEngine/EngineAPI.h index f2207f41d69..790a72b1455 100644 --- a/src/xrEngine/EngineAPI.h +++ b/src/xrEngine/EngineAPI.h @@ -55,6 +55,7 @@ class XR_NOVTABLE RendererModule virtual const xr_vector& ObtainSupportedModes() = 0; virtual bool CheckGameRequirements() = 0; virtual void SetupEnv(pcstr mode) = 0; + virtual void ClearEnv() = 0; }; class ENGINE_API CEngineAPI @@ -65,7 +66,7 @@ class ENGINE_API CEngineAPI RendererModule* selectedRenderer{}; void SelectRenderer(); - void CloseUnusedLibraries(); + void CloseUnusedLibraries() const; public: Factory_Create* pCreate; diff --git a/src/xrEngine/Render.cpp b/src/xrEngine/Render.cpp index 27248ae10d7..605aed454fc 100644 --- a/src/xrEngine/Render.cpp +++ b/src/xrEngine/Render.cpp @@ -2,8 +2,16 @@ #include "Render.h" // resources -IRender_Light::~IRender_Light() { GEnv.Render->light_destroy(this); } -IRender_Glow::~IRender_Glow() { GEnv.Render->glow_destroy(this); } +IRender_Light::~IRender_Light() +{ + if (GEnv.Render) + GEnv.Render->light_destroy(this); +} +IRender_Glow::~IRender_Glow() +{ + if (GEnv.Render) + GEnv.Render->glow_destroy(this); +} IRender::ScopedContext::ScopedContext(RenderContext context) {