aboutsummaryrefslogtreecommitdiff
path: root/src/client/shadows/dynamicshadowsrender.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/shadows/dynamicshadowsrender.cpp')
-rw-r--r--src/client/shadows/dynamicshadowsrender.cpp95
1 files changed, 69 insertions, 26 deletions
diff --git a/src/client/shadows/dynamicshadowsrender.cpp b/src/client/shadows/dynamicshadowsrender.cpp
index 528415aaf..24adb21e2 100644
--- a/src/client/shadows/dynamicshadowsrender.cpp
+++ b/src/client/shadows/dynamicshadowsrender.cpp
@@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/
#include <cstring>
+#include <cmath>
#include "client/shadows/dynamicshadowsrender.h"
#include "client/shadows/shadowsScreenQuad.h"
#include "client/shadows/shadowsshadercallbacks.h"
@@ -33,9 +34,13 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) :
m_device(device), m_smgr(device->getSceneManager()),
m_driver(device->getVideoDriver()), m_client(client), m_current_frame(0)
{
+ m_shadows_supported = true; // assume shadows supported. We will check actual support in initialize
m_shadows_enabled = true;
- m_shadow_strength = g_settings->getFloat("shadow_strength");
+ m_shadow_strength_gamma = g_settings->getFloat("shadow_strength_gamma");
+ if (std::isnan(m_shadow_strength_gamma))
+ m_shadow_strength_gamma = 1.0f;
+ m_shadow_strength_gamma = core::clamp(m_shadow_strength_gamma, 0.1f, 10.0f);
m_shadow_map_max_distance = g_settings->getFloat("shadow_map_max_distance");
@@ -49,6 +54,9 @@ ShadowRenderer::ShadowRenderer(IrrlichtDevice *device, Client *client) :
ShadowRenderer::~ShadowRenderer()
{
+ // call to disable releases dynamically allocated resources
+ disable();
+
if (m_shadow_depth_cb)
delete m_shadow_depth_cb;
if (m_shadow_mix_cb)
@@ -72,15 +80,25 @@ ShadowRenderer::~ShadowRenderer()
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);
+ }
+}
+
void ShadowRenderer::initialize()
{
auto *gpu = m_driver->getGPUProgrammingServices();
// we need glsl
- if (m_shadows_enabled && gpu && m_driver->queryFeature(video::EVDF_ARB_GLSL)) {
+ if (m_shadows_supported && gpu && m_driver->queryFeature(video::EVDF_ARB_GLSL)) {
createShaders();
} else {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
warningstream << "Shadows: GLSL Shader not supported on this system."
<< std::endl;
@@ -94,6 +112,8 @@ void ShadowRenderer::initialize()
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;
}
@@ -124,6 +144,16 @@ f32 ShadowRenderer::getMaxShadowFar() const
return 0.0f;
}
+void ShadowRenderer::setShadowIntensity(float shadow_intensity)
+{
+ m_shadow_strength = pow(shadow_intensity, 1.0f / m_shadow_strength_gamma);
+ if (m_shadow_strength > 1E-2)
+ enable();
+ else
+ disable();
+}
+
+
void ShadowRenderer::addNodeToShadowList(
scene::ISceneNode *node, E_SHADOW_MODE shadowMode)
{
@@ -153,6 +183,7 @@ void ShadowRenderer::updateSMTextures()
shadowMapTextureDynamicObjects = getSMTexture(
std::string("shadow_dynamic_") + itos(m_shadow_map_texture_size),
m_texture_format, true);
+ assert(shadowMapTextureDynamicObjects != nullptr);
}
if (!shadowMapClientMap) {
@@ -161,6 +192,7 @@ void ShadowRenderer::updateSMTextures()
std::string("shadow_clientmap_") + itos(m_shadow_map_texture_size),
m_shadow_map_colored ? m_texture_format_color : m_texture_format,
true);
+ assert(shadowMapClientMap != nullptr);
}
if (!shadowMapClientMapFuture && m_map_shadow_update_frames > 1) {
@@ -168,6 +200,7 @@ void ShadowRenderer::updateSMTextures()
std::string("shadow_clientmap_bb_") + itos(m_shadow_map_texture_size),
m_shadow_map_colored ? m_texture_format_color : m_texture_format,
true);
+ assert(shadowMapClientMapFuture != nullptr);
}
if (m_shadow_map_colored && !shadowMapTextureColors) {
@@ -175,6 +208,7 @@ void ShadowRenderer::updateSMTextures()
std::string("shadow_colored_") + itos(m_shadow_map_texture_size),
m_shadow_map_colored ? m_texture_format_color : m_texture_format,
true);
+ assert(shadowMapTextureColors != nullptr);
}
// The merge all shadowmaps texture
@@ -194,6 +228,7 @@ void ShadowRenderer::updateSMTextures()
shadowMapTextureFinal = getSMTexture(
std::string("shadowmap_final_") + itos(m_shadow_map_texture_size),
frt, true);
+ assert(shadowMapTextureFinal != nullptr);
}
if (!m_shadow_node_array.empty() && !m_light_list.empty()) {
@@ -270,6 +305,10 @@ void ShadowRenderer::update(video::ITexture *outputTarget)
updateSMTextures();
+ if (shadowMapTextureFinal == nullptr) {
+ return;
+ }
+
if (!m_shadow_node_array.empty() && !m_light_list.empty()) {
for (DirectionalLight &light : m_light_list) {
@@ -307,19 +346,23 @@ void ShadowRenderer::drawDebug()
/* this code just shows shadows textures in screen and in ONLY for debugging*/
#if 0
// this is debug, ignore for now.
- m_driver->draw2DImage(shadowMapTextureFinal,
- core::rect<s32>(0, 50, 128, 128 + 50),
- core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
+ if (shadowMapTextureFinal)
+ m_driver->draw2DImage(shadowMapTextureFinal,
+ core::rect<s32>(0, 50, 128, 128 + 50),
+ core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
- m_driver->draw2DImage(shadowMapClientMap,
- core::rect<s32>(0, 50 + 128, 128, 128 + 50 + 128),
- core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
- m_driver->draw2DImage(shadowMapTextureDynamicObjects,
- core::rect<s32>(0, 128 + 50 + 128, 128,
- 128 + 50 + 128 + 128),
- core::rect<s32>({0, 0}, shadowMapTextureDynamicObjects->getSize()));
+ if (shadowMapClientMap)
+ m_driver->draw2DImage(shadowMapClientMap,
+ core::rect<s32>(0, 50 + 128, 128, 128 + 50 + 128),
+ core::rect<s32>({0, 0}, shadowMapTextureFinal->getSize()));
+
+ if (shadowMapTextureDynamicObjects)
+ m_driver->draw2DImage(shadowMapTextureDynamicObjects,
+ core::rect<s32>(0, 128 + 50 + 128, 128,
+ 128 + 50 + 128 + 128),
+ core::rect<s32>({0, 0}, shadowMapTextureDynamicObjects->getSize()));
- if (m_shadow_map_colored) {
+ if (m_shadow_map_colored && shadowMapTextureColors) {
m_driver->draw2DImage(shadowMapTextureColors,
core::rect<s32>(128,128 + 50 + 128 + 128,
@@ -469,13 +512,13 @@ void ShadowRenderer::createShaders()
if (depth_shader == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl");
if (depth_shader_vs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping vs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl");
if (depth_shader_fs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping fs shader not found." << std::endl;
return;
}
@@ -490,7 +533,7 @@ void ShadowRenderer::createShaders()
if (depth_shader == -1) {
// upsi, something went wrong loading shader.
delete m_shadow_depth_cb;
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling shadow mapping shader." << std::endl;
return;
}
@@ -506,13 +549,13 @@ void ShadowRenderer::createShaders()
if (depth_shader_entities == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_vertex.glsl");
if (depth_shader_vs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping vs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_fragment.glsl");
if (depth_shader_fs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping fs shader not found." << std::endl;
return;
}
@@ -525,7 +568,7 @@ void ShadowRenderer::createShaders()
if (depth_shader_entities == -1) {
// upsi, something went wrong loading shader.
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling shadow mapping shader (dynamic)." << std::endl;
return;
}
@@ -539,14 +582,14 @@ void ShadowRenderer::createShaders()
if (mixcsm_shader == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass2_vertex.glsl");
if (depth_shader_vs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error cascade shadow mapping fs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass2_fragment.glsl");
if (depth_shader_fs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error cascade shadow mapping fs shader not found." << std::endl;
return;
}
@@ -565,7 +608,7 @@ void ShadowRenderer::createShaders()
// upsi, something went wrong loading shader.
delete m_shadow_mix_cb;
delete m_screen_quad;
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling cascade shadow mapping shader." << std::endl;
return;
}
@@ -579,13 +622,13 @@ void ShadowRenderer::createShaders()
if (m_shadow_map_colored && depth_shader_trans == -1) {
std::string depth_shader_vs = getShaderPath("shadow_shaders", "pass1_trans_vertex.glsl");
if (depth_shader_vs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping vs shader not found." << std::endl;
return;
}
std::string depth_shader_fs = getShaderPath("shadow_shaders", "pass1_trans_fragment.glsl");
if (depth_shader_fs.empty()) {
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error shadow mapping fs shader not found." << std::endl;
return;
}
@@ -601,7 +644,7 @@ void ShadowRenderer::createShaders()
// upsi, something went wrong loading shader.
delete m_shadow_depth_trans_cb;
m_shadow_map_colored = false;
- m_shadows_enabled = false;
+ m_shadows_supported = false;
errorstream << "Error compiling colored shadow mapping shader." << std::endl;
return;
}