diff --git a/src/client/game.cpp b/src/client/game.cpp index 6714b1bcb..296b0ce8d 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -372,13 +372,6 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter { Sky *m_sky; Client *m_client; - bool *m_force_fog_off; - f32 *m_fog_range; - bool m_fog_enabled; - CachedPixelShaderSetting m_fog_color{"fogColor"}; - CachedPixelShaderSetting m_fog_distance{"fogDistance"}; - CachedPixelShaderSetting - m_fog_shading_parameter{"fogShadingParameter"}; CachedVertexShaderSetting m_animation_timer_vertex{"animationTimer"}; CachedPixelShaderSetting m_animation_timer_pixel{"animationTimer"}; CachedVertexShaderSetting @@ -425,11 +418,16 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter CachedPixelShaderSetting m_volumetric_light_strength_pixel{"volumetricLightStrength"}; + static constexpr std::array SETTING_CALLBACKS = { + "exposure_compensation", + "bloom_intensity", + "bloom_strength_factor", + "bloom_radius" + }; + public: void onSettingsChange(const std::string &name) { - if (name == "enable_fog") - m_fog_enabled = g_settings->getBool("enable_fog"); if (name == "exposure_compensation") m_user_exposure_compensation = g_settings->getFloat("exposure_compensation", -1.0f, 1.0f); if (name == "bloom_intensity") @@ -447,20 +445,13 @@ public: void setSky(Sky *sky) { m_sky = sky; } - GameGlobalShaderConstantSetter(Sky *sky, bool *force_fog_off, - f32 *fog_range, Client *client) : + GameGlobalShaderConstantSetter(Sky *sky, Client *client) : m_sky(sky), - m_client(client), - m_force_fog_off(force_fog_off), - m_fog_range(fog_range) + m_client(client) { - g_settings->registerChangedCallback("enable_fog", settingsCallback, this); - g_settings->registerChangedCallback("exposure_compensation", settingsCallback, this); - g_settings->registerChangedCallback("bloom_intensity", settingsCallback, this); - g_settings->registerChangedCallback("bloom_strength_factor", settingsCallback, this); - g_settings->registerChangedCallback("bloom_radius", settingsCallback, this); - g_settings->registerChangedCallback("saturation", settingsCallback, this); - m_fog_enabled = g_settings->getBool("enable_fog"); + for (auto &name : SETTING_CALLBACKS) + g_settings->registerChangedCallback(name, settingsCallback, this); + m_user_exposure_compensation = g_settings->getFloat("exposure_compensation", -1.0f, 1.0f); m_bloom_enabled = g_settings->getBool("enable_bloom"); m_bloom_intensity = g_settings->getFloat("bloom_intensity", 0.01f, 1.0f); @@ -471,23 +462,12 @@ public: ~GameGlobalShaderConstantSetter() { - g_settings->deregisterChangedCallback("enable_fog", settingsCallback, this); + for (auto &name : SETTING_CALLBACKS) + g_settings->deregisterChangedCallback(name, settingsCallback, this); } void onSetConstants(video::IMaterialRendererServices *services) override { - video::SColorf fogcolorf(m_sky->getFogColor()); - m_fog_color.set(fogcolorf, services); - - float fog_distance = 10000 * BS; - if (m_fog_enabled && !*m_force_fog_off) - fog_distance = *m_fog_range; - - float fog_shading_parameter = 1.0 / ( 1.0 - m_sky->getFogStart()); - - m_fog_distance.set(&fog_distance, services); - m_fog_shading_parameter.set(&fog_shading_parameter, services); - u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio(); video::SColorf sunlight; get_sunlight_color(&sunlight, daynight_ratio); @@ -611,17 +591,11 @@ public: class GameGlobalShaderConstantSetterFactory : public IShaderConstantSetterFactory { - Sky *m_sky; - bool *m_force_fog_off; - f32 *m_fog_range; + Sky *m_sky = nullptr; Client *m_client; std::vector created_nosky; public: - GameGlobalShaderConstantSetterFactory(bool *force_fog_off, - f32 *fog_range, Client *client) : - m_sky(NULL), - m_force_fog_off(force_fog_off), - m_fog_range(fog_range), + GameGlobalShaderConstantSetterFactory(Client *client) : m_client(client) {} @@ -635,8 +609,7 @@ public: virtual IShaderConstantSetter* create() { - auto *scs = new GameGlobalShaderConstantSetter( - m_sky, m_force_fog_off, m_fog_range, m_client); + auto *scs = new GameGlobalShaderConstantSetter(m_sky, m_client); if (!m_sky) created_nosky.push_back(scs); return scs; @@ -1456,10 +1429,12 @@ bool Game::createClient(const GameStartData &start_data) return false; } - auto *scsf = new GameGlobalShaderConstantSetterFactory( - &m_flags.force_fog_off, &runData.fog_range, client); + auto *scsf = new GameGlobalShaderConstantSetterFactory(client); shader_src->addShaderConstantSetterFactory(scsf); + shader_src->addShaderConstantSetterFactory( + new FogShaderConstantSetterFactory()); + ShadowRenderer::preInit(shader_src); // Update cached textures, meshes and materials diff --git a/src/client/renderingengine.cpp b/src/client/renderingengine.cpp index 22b55ec6b..59c1a086f 100644 --- a/src/client/renderingengine.cpp +++ b/src/client/renderingengine.cpp @@ -44,7 +44,7 @@ RenderingEngine *RenderingEngine::s_singleton = nullptr; const video::SColor RenderingEngine::MENU_SKY_COLOR = video::SColor(255, 140, 186, 250); const float RenderingEngine::BASE_BLOOM_STRENGTH = 1.0f; -/* Helper stuff */ +/* Helper classes */ void FpsControl::reset() { @@ -85,6 +85,47 @@ void FpsControl::limit(IrrlichtDevice *device, f32 *dtime, bool assume_paused) last_time = time; } +class FogShaderConstantSetter : public IShaderConstantSetter +{ + CachedPixelShaderSetting m_fog_color{"fogColor"}; + CachedPixelShaderSetting m_fog_distance{"fogDistance"}; + CachedPixelShaderSetting m_fog_shading_parameter{"fogShadingParameter"}; + +public: + void onSetConstants(video::IMaterialRendererServices *services) override + { + auto *driver = RenderingEngine::get_video_driver(); + assert(driver); + + video::SColor fog_color(0); + video::E_FOG_TYPE fog_type = video::EFT_FOG_LINEAR; + f32 fog_start = 0; + f32 fog_end = 0; + f32 fog_density = 0; + bool fog_pixelfog = false; + bool fog_rangefog = false; + driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density, + fog_pixelfog, fog_rangefog); + + video::SColorf fog_colorf(fog_color); + m_fog_color.set(fog_colorf, services); + + m_fog_distance.set(&fog_end, services); + + float parameter = 0; + if (fog_end > 0) + parameter = 1.0f / (1.0f - fog_start / fog_end); + m_fog_shading_parameter.set(¶meter, services); + } +}; + +IShaderConstantSetter *FogShaderConstantSetterFactory::create() +{ + return new FogShaderConstantSetter(); +} + +/* Other helpers */ + static gui::GUISkin *createSkin(gui::IGUIEnvironment *environment, gui::EGUI_SKIN_TYPE type, video::IVideoDriver *driver) { diff --git a/src/client/renderingengine.h b/src/client/renderingengine.h index 629843ac9..e787af488 100644 --- a/src/client/renderingengine.h +++ b/src/client/renderingengine.h @@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include #include "irrlichttypes_extrabloated.h" #include "debug.h" +#include "client/shader.h" #include "client/render/core.h" // include the shadow mapper classes too #include "client/shadows/dynamicshadowsrender.h" @@ -46,6 +47,8 @@ class RenderingCore; // Instead of a mechanism to disable fog we just set it to be really far away #define FOG_RANGE_ALL (100000 * BS) +/* Helpers */ + struct FpsControl { FpsControl() : last_time(0), busy_time(0), sleep_time(0) {} @@ -59,6 +62,16 @@ struct FpsControl { u64 last_time, busy_time, sleep_time; }; +// Populates fogColor, fogDistance, fogShadingParameter with values from Irrlicht +class FogShaderConstantSetterFactory : public IShaderConstantSetterFactory +{ +public: + FogShaderConstantSetterFactory() {}; + virtual IShaderConstantSetter *create(); +}; + +/* Rendering engine class */ + class RenderingEngine { public: