Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Release shadow mapping resources when not needed (#12497)
  • Loading branch information
x2048 committed Jul 9, 2022
1 parent b15393c commit 7c26111
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 31 deletions.
3 changes: 2 additions & 1 deletion src/client/clientmap.cpp
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
11 changes: 0 additions & 11 deletions src/client/content_cao.cpp
Expand Up @@ -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";
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
56 changes: 41 additions & 15 deletions src/client/shadows/dynamicshadowsrender.cpp
Expand Up @@ -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()
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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()) {
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions src/client/shadows/dynamicshadowsrender.h
Expand Up @@ -51,6 +51,8 @@ struct NodeToApply
class ShadowRenderer
{
public:
static const int TEXTURE_LAYER_SHADOW = 3;

ShadowRenderer(IrrlichtDevice *device, Client *client);

~ShadowRenderer();
Expand Down
4 changes: 0 additions & 4 deletions src/client/wieldmesh.cpp
Expand Up @@ -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());
}
}

Expand Down

0 comments on commit 7c26111

Please sign in to comment.