]> git.lizzy.rs Git - minetest.git/commitdiff
Release shadow mapping resources when not needed (#12497)
authorx2048 <codeforsmile@gmail.com>
Sat, 9 Jul 2022 20:26:39 +0000 (22:26 +0200)
committerGitHub <noreply@github.com>
Sat, 9 Jul 2022 20:26:39 +0000 (22:26 +0200)
src/client/clientmap.cpp
src/client/content_cao.cpp
src/client/shadows/dynamicshadowsrender.cpp
src/client/shadows/dynamicshadowsrender.h
src/client/wieldmesh.cpp

index 38ba1daad2df308e0df0a8a6a09e2c259722c0cf..c5ba98ff6e103745eb56e3d4ebe7de4a2cd09c01 100644 (file)
@@ -472,7 +472,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                        // pass the shadow map texture to the buffer texture
                        ShadowRenderer *shadow = m_rendering_engine->get_shadow_renderer();
                        if (shadow && shadow->is_active()) {
-                               auto &layer = material.TextureLayer[3];
+                               auto &layer = material.TextureLayer[ShadowRenderer::TEXTURE_LAYER_SHADOW];
                                layer.Texture = shadow->get_texture();
                                layer.TextureWrapU = video::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE;
                                layer.TextureWrapV = video::E_TEXTURE_CLAMP::ETC_CLAMP_TO_EDGE;
@@ -485,6 +485,7 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
                        }
                        driver->setMaterial(material);
                        ++material_swaps;
+                       material.TextureLayer[ShadowRenderer::TEXTURE_LAYER_SHADOW].Texture = nullptr;
                }
 
                v3f block_wpos = intToFloat(descriptor.m_pos * MAP_BLOCKSIZE, BS);
index 32c1bb4a8e33354678d88e765b6e0571ef4af82f..3126ee5e87e6174a750e68a0fb0a286aeefd30df 100644 (file)
@@ -1318,12 +1318,6 @@ void GenericCAO::updateTextures(std::string mod)
        m_previous_texture_modifier = m_current_texture_modifier;
        m_current_texture_modifier = mod;
 
-       video::ITexture *shadow_texture = nullptr;
-       if (auto shadow = RenderingEngine::get_shadow_renderer())
-               shadow_texture = shadow->get_texture();
-
-       const u32 TEXTURE_LAYER_SHADOW = 3;
-
        if (m_spritenode) {
                if (m_prop.visual == "sprite") {
                        std::string texturestring = "no_texture.png";
@@ -1334,7 +1328,6 @@ void GenericCAO::updateTextures(std::string mod)
                        m_spritenode->getMaterial(0).MaterialTypeParam = 0.5f;
                        m_spritenode->setMaterialTexture(0,
                                        tsrc->getTextureForMesh(texturestring));
-                       m_spritenode->setMaterialTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
 
                        // This allows setting per-material colors. However, until a real lighting
                        // system is added, the code below will have no effect. Once MineTest
@@ -1370,7 +1363,6 @@ void GenericCAO::updateTextures(std::string mod)
                                material.MaterialType = m_material_type;
                                material.MaterialTypeParam = 0.5f;
                                material.TextureLayer[0].Texture = texture;
-                               material.TextureLayer[TEXTURE_LAYER_SHADOW].Texture = shadow_texture;
                                material.setFlag(video::EMF_LIGHTING, true);
                                material.setFlag(video::EMF_BILINEAR_FILTER, false);
                                material.setFlag(video::EMF_BACK_FACE_CULLING, m_prop.backface_culling);
@@ -1421,7 +1413,6 @@ void GenericCAO::updateTextures(std::string mod)
                                material.setFlag(video::EMF_BILINEAR_FILTER, false);
                                material.setTexture(0,
                                                tsrc->getTextureForMesh(texturestring));
-                               material.setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
                                material.getTextureMatrix(0).makeIdentity();
 
                                // This allows setting per-material colors. However, until a real lighting
@@ -1448,7 +1439,6 @@ void GenericCAO::updateTextures(std::string mod)
                                auto& material = m_meshnode->getMaterial(0);
                                material.setTexture(0,
                                                tsrc->getTextureForMesh(tname));
-                               material.setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
 
                                // This allows setting per-material colors. However, until a real lighting
                                // system is added, the code below will have no effect. Once MineTest
@@ -1473,7 +1463,6 @@ void GenericCAO::updateTextures(std::string mod)
                                auto& material = m_meshnode->getMaterial(1);
                                material.setTexture(0,
                                                tsrc->getTextureForMesh(tname));
-                               material.setTexture(TEXTURE_LAYER_SHADOW, shadow_texture);
 
                                // This allows setting per-material colors. However, until a real lighting
                                // system is added, the code below will have no effect. Once MineTest
index b8ceeb6239e48eaef04d6d31926a1aced79bc2e3..944deb801ff8e82737b9c22e6be4f8c75cb44bd9 100644 (file)
@@ -70,31 +70,45 @@ ShadowRenderer::~ShadowRenderer()
                delete m_shadow_mix_cb;
        m_shadow_node_array.clear();
        m_light_list.clear();
+}
 
-       if (shadowMapTextureDynamicObjects)
+void ShadowRenderer::disable()
+{
+       m_shadows_enabled = false;
+       if (shadowMapTextureFinal) {
+               m_driver->setRenderTarget(shadowMapTextureFinal, true, true,
+                       video::SColor(255, 255, 255, 255));
+               m_driver->setRenderTarget(0, false, false);
+       }
+
+       if (shadowMapTextureDynamicObjects) {
                m_driver->removeTexture(shadowMapTextureDynamicObjects);
+               shadowMapTextureDynamicObjects = nullptr;
+       }
 
-       if (shadowMapTextureFinal)
+       if (shadowMapTextureFinal) {
                m_driver->removeTexture(shadowMapTextureFinal);
+               shadowMapTextureFinal = nullptr;
+       }
 
-       if (shadowMapTextureColors)
+       if (shadowMapTextureColors) {
                m_driver->removeTexture(shadowMapTextureColors);
+               shadowMapTextureColors = nullptr;
+       }
 
-       if (shadowMapClientMap)
+       if (shadowMapClientMap) {
                m_driver->removeTexture(shadowMapClientMap);
+               shadowMapClientMap = nullptr;
+       }
 
-       if (shadowMapClientMapFuture)
+       if (shadowMapClientMapFuture) {
                m_driver->removeTexture(shadowMapClientMapFuture);
-}
-
-void ShadowRenderer::disable()
-{
-       m_shadows_enabled = false;
-       if (shadowMapTextureFinal) {
-               m_driver->setRenderTarget(shadowMapTextureFinal, true, true,
-                       video::SColor(255, 255, 255, 255));
-               m_driver->setRenderTarget(0, true, true);
+               shadowMapClientMapFuture = nullptr;
        }
+
+       for (auto node : m_shadow_node_array)
+               if (node.shadowMode & E_SHADOW_MODE::ESM_RECEIVE)
+                       node.node->setMaterialTexture(TEXTURE_LAYER_SHADOW, nullptr);
 }
 
 void ShadowRenderer::initialize()
@@ -163,11 +177,18 @@ void ShadowRenderer::setShadowIntensity(float shadow_intensity)
 void ShadowRenderer::addNodeToShadowList(
                scene::ISceneNode *node, E_SHADOW_MODE shadowMode)
 {
-       m_shadow_node_array.emplace_back(NodeToApply(node, shadowMode));
+       if (!node)
+               return;
+       m_shadow_node_array.emplace_back(node, shadowMode);
+       if (shadowMode == ESM_RECEIVE || shadowMode == ESM_BOTH)
+               node->setMaterialTexture(TEXTURE_LAYER_SHADOW, shadowMapTextureFinal);
 }
 
 void ShadowRenderer::removeNodeFromShadowList(scene::ISceneNode *node)
 {
+       if (!node)
+               return;
+       node->setMaterialTexture(TEXTURE_LAYER_SHADOW, nullptr);
        for (auto it = m_shadow_node_array.begin(); it != m_shadow_node_array.end();) {
                if (it->node == node) {
                        it = m_shadow_node_array.erase(it);
@@ -235,6 +256,10 @@ void ShadowRenderer::updateSMTextures()
                        std::string("shadowmap_final_") + itos(m_shadow_map_texture_size),
                        frt, true);
                assert(shadowMapTextureFinal != nullptr);
+
+               for (auto &node : m_shadow_node_array)
+                       if (node.shadowMode == ESM_RECEIVE || node.shadowMode == ESM_BOTH)
+                               node.node->setMaterialTexture(TEXTURE_LAYER_SHADOW, shadowMapTextureFinal);
        }
 
        if (!m_shadow_node_array.empty() && !m_light_list.empty()) {
@@ -322,6 +347,7 @@ void ShadowRenderer::update(video::ITexture *outputTarget)
                return;
        }
 
+
        if (!m_shadow_node_array.empty() && !m_light_list.empty()) {
 
                for (DirectionalLight &light : m_light_list) {
index 2e3b58f6f9e90d6fbd6e73caa7d6d584cd621c94..bd27f6f20046da5e6f1b6dd76481aecb7c871be8 100644 (file)
@@ -51,6 +51,8 @@ struct NodeToApply
 class ShadowRenderer
 {
 public:
+       static const int TEXTURE_LAYER_SHADOW = 3;
+
        ShadowRenderer(IrrlichtDevice *device, Client *client);
 
        ~ShadowRenderer();
index 25b34357386892c61d7e6ce4c6acd641f220ca80..0a89e2aa2dcbb0612da0822b5dcadd3af8e04cd1 100644 (file)
@@ -556,10 +556,6 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh)
        if (m_shadow) {
                // Add mesh to shadow caster
                m_shadow->addNodeToShadowList(m_meshnode);
-
-               // Set shadow texture
-               for (u32 i = 0; i < m_meshnode->getMaterialCount(); i++)
-                       m_meshnode->setMaterialTexture(3, m_shadow->get_texture());
        }
 }