From 8da4530957f1e64b031c513486cceeba311a8044 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 1 Nov 2015 22:09:02 +0100 Subject: [PATCH] Use INI-imported underwater fog settings (Fixes #2907, Fixes #1511) --- apps/openmw/mwrender/renderingmanager.cpp | 17 +++++--- apps/openmw/mwrender/renderingmanager.hpp | 6 ++- apps/openmw/mwworld/weather.cpp | 53 ++++++++++++++++++++++- apps/openmw/mwworld/weather.hpp | 7 +++ 4 files changed, 76 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index da81b23b1a..e1c0ea666a 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -31,6 +31,8 @@ #include +#include "../mwworld/fallback.hpp" + #include "sky.hpp" #include "effectmanager.hpp" #include "npcanimation.hpp" @@ -199,6 +201,10 @@ namespace MWRender updateProjectionMatrix(); mStateUpdater->setFogEnd(mViewDistance); + mUnderwaterColor = fallback->getFallbackColour("Water_UnderwaterColor"); + mUnderwaterWeight = fallback->getFallbackFloat("Water_UnderwaterColorWeight"); + mUnderwaterIndoorFog = fallback->getFallbackFloat("Water_UnderwaterIndoorFog"); + mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("near", mNearClip)); mRootNode->getOrCreateStateSet()->addUniform(new osg::Uniform("far", mViewDistance)); } @@ -349,13 +355,14 @@ namespace MWRender { osg::Vec4f color = SceneUtil::colourFromRGB(cell->mAmbi.mFog); - configureFog (cell->mAmbi.mFogDensity, color); + configureFog (cell->mAmbi.mFogDensity, mUnderwaterIndoorFog, color); } - void RenderingManager::configureFog(float fogDepth, const osg::Vec4f &color) + void RenderingManager::configureFog(float fogDepth, float underwaterFog, const osg::Vec4f &color) { mFogDepth = fogDepth; mFogColor = color; + mUnderwaterFog = underwaterFog; } SkyManager* RenderingManager::getSkyManager() @@ -378,9 +385,9 @@ namespace MWRender mCamera->getPosition(focal, cameraPos); if (mWater->isUnderwater(cameraPos)) { - setFogColor(osg::Vec4f(0.090195f, 0.115685f, 0.12745f, 1.f)); - mStateUpdater->setFogStart(0.f); - mStateUpdater->setFogEnd(1000); + setFogColor(mUnderwaterColor * mUnderwaterWeight + mFogColor * (1.f-mUnderwaterWeight)); + mStateUpdater->setFogStart(mViewDistance * (1 - mUnderwaterFog)); + mStateUpdater->setFogEnd(mViewDistance); } else { diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 1ddab73387..3e17ef4137 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -79,7 +79,7 @@ namespace MWRender void configureAmbient(const ESM::Cell* cell); void configureFog(const ESM::Cell* cell); - void configureFog(float fogDepth, const osg::Vec4f& colour); + void configureFog(float fogDepth, float underwaterFog, const osg::Vec4f& colour); void addCell(const MWWorld::CellStore* store); void removeCell(const MWWorld::CellStore* store); @@ -192,6 +192,10 @@ namespace MWRender osg::ref_ptr mStateUpdater; float mFogDepth; + osg::Vec4f mUnderwaterColor; + float mUnderwaterWeight; + float mUnderwaterFog; + float mUnderwaterIndoorFog; osg::Vec4f mFogColor; osg::Vec4f mAmbientColor; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 5008d8fbfc..8920c17b41 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -438,6 +438,10 @@ WeatherManager::WeatherManager(MWRender::RenderingManager& rendering, const MWWo , mDayEnd(mSunsetTime) , mHoursBetweenWeatherChanges(fallback.getFallbackFloat("Weather_Hours_Between_Weather_Changes")) , mRainSpeed(fallback.getFallbackFloat("Weather_Precip_Gravity")) + , mUnderwaterSunriseFog(fallback.getFallbackFloat("Water_UnderwaterSunriseFog")) + , mUnderwaterDayFog(fallback.getFallbackFloat("Water_UnderwaterDayFog")) + , mUnderwaterSunsetFog(fallback.getFallbackFloat("Water_UnderwaterSunsetFog")) + , mUnderwaterNightFog(fallback.getFallbackFloat("Water_UnderwaterNightFog")) , mWeatherSettings() , mMasser("Masser", fallback) , mSecunda("Secunda", fallback) @@ -624,6 +628,53 @@ void WeatherManager::update(float duration, bool paused) mRendering.setSunDirection( final * -1 ); } + // TODO: use pre/post sunset/sunrise time values in [Weather] section + // TODO: factor out the time of day interpolation code to reuse for calculateWeatherResult() + float gameHour = time.getHour(); + float underwaterFog; + // night + if (gameHour <= mNightEnd || gameHour >= mNightStart + 1) + underwaterFog = mUnderwaterNightFog; + // sunrise + else if (gameHour >= mNightEnd && gameHour <= mDayStart + 1) + { + if (gameHour <= mSunriseTime) + { + // fade in + float advance = mSunriseTime - gameHour; + float factor = advance / 0.5f; + underwaterFog = lerp(mUnderwaterSunriseFog, mUnderwaterNightFog, factor); + } + else //if (gameHour >= 6) + { + // fade out + float advance = gameHour - mSunriseTime; + float factor = advance / 3.f; + underwaterFog = lerp(mUnderwaterSunriseFog, mUnderwaterDayFog, factor); + } + } + // day + else if (gameHour >= mDayStart + 1 && gameHour <= mDayEnd - 1) + underwaterFog = mUnderwaterDayFog; + // sunset + else if (gameHour >= mDayEnd - 1 && gameHour <= mNightStart + 1) + { + if (gameHour <= mDayEnd + 1) + { + // fade in + float advance = (mDayEnd + 1) - gameHour; + float factor = (advance / 2); + underwaterFog = lerp(mUnderwaterSunsetFog, mUnderwaterDayFog, factor); + } + else //if (gameHour >= 19) + { + // fade out + float advance = gameHour - (mDayEnd + 1); + float factor = advance / 2.f; + underwaterFog = lerp(mUnderwaterSunsetFog, mUnderwaterNightFog, factor); + } + } + float peakHour = mSunriseTime + (mSunsetTime - mSunriseTime) / 2; if (time.getHour() < mSunriseTime || time.getHour() > mSunsetTime) mRendering.getSkyManager()->setGlareTimeOfDayFade(0); @@ -635,7 +686,7 @@ void WeatherManager::update(float duration, bool paused) mRendering.getSkyManager()->setMasserState(mMasser.calculateState(time)); mRendering.getSkyManager()->setSecundaState(mSecunda.calculateState(time)); - mRendering.configureFog(mResult.mFogDepth, mResult.mFogColor); + mRendering.configureFog(mResult.mFogDepth, underwaterFog, mResult.mFogColor); mRendering.setAmbientColour(mResult.mAmbientColor); mRendering.setSunColour(mResult.mSunColor); diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 7ce7c1bf84..a1a7d30774 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -249,6 +249,13 @@ namespace MWWorld float mDayEnd; float mHoursBetweenWeatherChanges; float mRainSpeed; + + // underwater fog not really related to weather, but we handle it here because it's convenient + float mUnderwaterSunriseFog; + float mUnderwaterDayFog; + float mUnderwaterSunsetFog; + float mUnderwaterNightFog; + std::vector mWeatherSettings; MoonModel mMasser; MoonModel mSecunda;