From d280d10e2930e8aaedee07222a64122607720b06 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Fri, 14 Nov 2025 15:23:10 +0100 Subject: [PATCH] Check shadow map initialization more carefully --- src/client/shadows/dynamicshadowsrender.cpp | 65 ++++++++++++--------- src/client/shadows/dynamicshadowsrender.h | 5 +- src/script/lua_api/l_menu_common.cpp | 3 +- 3 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/client/shadows/dynamicshadowsrender.cpp b/src/client/shadows/dynamicshadowsrender.cpp index 27e3e10d1..db9d5aa9c 100644 --- a/src/client/shadows/dynamicshadowsrender.cpp +++ b/src/client/shadows/dynamicshadowsrender.cpp @@ -21,8 +21,8 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) : m_time_day(0.0f), m_force_update_shadow_map(false), m_current_frame(0), m_perspective_bias_xy(0.8f), m_perspective_bias_z(0.5f) { - m_shadows_supported = true; // assume shadows supported. We will check actual support in initialize - m_shadows_enabled = true; + m_shadows_supported = true; // we will check actual support in initialize() + m_shadows_enabled = false; m_shadow_strength_gamma = g_settings->getFloat("shadow_strength_gamma"); if (std::isnan(m_shadow_strength_gamma)) @@ -112,20 +112,38 @@ void ShadowRenderer::preInit(IWritableShaderSource *shsrc) } } -void ShadowRenderer::initialize() +bool ShadowRenderer::initialize() { + m_shadows_supported = ShadowRenderer::isSupported(m_driver); + if (!m_shadows_supported) + return false; + + /* Set up texture formats */ + auto &fmt1 = m_texture_format; + auto &fmt2 = m_texture_format_color; + + if (m_shadow_map_texture_32bit && m_driver->queryTextureFormat(video::ECF_R32F)) + fmt1 = video::ECF_R32F; + else if (m_driver->queryTextureFormat(video::ECF_R16F)) + fmt1 = video::ECF_R16F; + + if (m_shadow_map_texture_32bit && m_driver->queryTextureFormat(video::ECF_G32R32F)) + fmt2 = video::ECF_G32R32F; + else if (m_driver->queryTextureFormat(video::ECF_G16R16F)) + fmt2 = video::ECF_G16R16F; + + infostream << "ShadowRenderer: color format = " << video::ColorFormatName(fmt1) + << " or " << video::ColorFormatName(fmt2) << std::endl; + + // Note: this is just a sanity check since the version checks in isSupported() + // should already guarantee availability + if (fmt1 == video::ECF_UNKNOWN || fmt2 == video::ECF_UNKNOWN) + m_shadows_supported = false; + if (!m_shadows_supported) + return false; + createShaders(); - - - m_texture_format = m_shadow_map_texture_32bit - ? video::ECOLOR_FORMAT::ECF_R32F - : video::ECOLOR_FORMAT::ECF_R16F; - - m_texture_format_color = m_shadow_map_texture_32bit - ? video::ECOLOR_FORMAT::ECF_G32R32F - : video::ECOLOR_FORMAT::ECF_G16R16F; - - m_shadows_enabled &= m_shadows_supported; + return true; } @@ -228,7 +246,7 @@ void ShadowRenderer::updateSMTextures() assert(shadowMapTextureColors != nullptr); } - // The merge all shadowmaps texture + // Then merge all shadowmap textures if (!shadowMapTextureFinal) { video::ECOLOR_FORMAT frt; if (m_shadow_map_texture_32bit) { @@ -580,21 +598,16 @@ std::unique_ptr createShadowRenderer(IrrlichtDevice *device, Cli if (!g_settings->getBool("enable_dynamic_shadows")) return nullptr; - // disable if unsupported - if (!ShadowRenderer::isSupported(device)) { - warningstream << "Shadows: disabled dynamic shadows due to being unsupported" << std::endl; - g_settings->setBool("enable_dynamic_shadows", false); - return nullptr; + auto renderer = std::make_unique(device, client); + if (!renderer->initialize()) { + warningstream << "Disabling dynamic shadows due to being unsupported." << std::endl; + renderer.reset(); } - - auto shadow_renderer = std::make_unique(device, client); - shadow_renderer->initialize(); - return shadow_renderer; + return renderer; } -bool ShadowRenderer::isSupported(IrrlichtDevice *device) +bool ShadowRenderer::isSupported(video::IVideoDriver *driver) { - auto driver = device->getVideoDriver(); const video::E_DRIVER_TYPE type = driver->getDriverType(); v2s32 glver = driver->getLimits().GLVersion; diff --git a/src/client/shadows/dynamicshadowsrender.h b/src/client/shadows/dynamicshadowsrender.h index 87d31a7a3..f3226c638 100644 --- a/src/client/shadows/dynamicshadowsrender.h +++ b/src/client/shadows/dynamicshadowsrender.h @@ -51,7 +51,8 @@ public: // the shaders are dealt with. static void preInit(IWritableShaderSource *shsrc); - void initialize(); + /// @return shadows supported? + bool initialize(); /// Adds a directional light shadow map (Usually just one (the sun) except in /// Tattoine ). @@ -92,7 +93,7 @@ public: f32 getPerspectiveBiasXY() { return m_perspective_bias_xy; } f32 getPerspectiveBiasZ() { return m_perspective_bias_z; } - static bool isSupported(IrrlichtDevice *device); + static bool isSupported(video::IVideoDriver *driver); private: video::ITexture *getSMTexture(const std::string &shadow_map_name, diff --git a/src/script/lua_api/l_menu_common.cpp b/src/script/lua_api/l_menu_common.cpp index 7fc06b447..6f8bb2bbb 100644 --- a/src/script/lua_api/l_menu_common.cpp +++ b/src/script/lua_api/l_menu_common.cpp @@ -31,7 +31,8 @@ int ModApiMenuCommon::l_get_active_driver(lua_State *L) int ModApiMenuCommon::l_driver_supports_shadows(lua_State *L) { - lua_pushboolean(L, ShadowRenderer::isSupported(RenderingEngine::get_raw_device())); + auto *device = RenderingEngine::get_raw_device(); + lua_pushboolean(L, ShadowRenderer::isSupported(device->getVideoDriver())); return 1; }