From a4c15ad402b958cb0ebea18d5edf7a3f4cfe140e Mon Sep 17 00:00:00 2001 From: Alex Booher Date: Sat, 21 Sep 2024 21:33:59 -0600 Subject: [PATCH 1/6] fix: sun flash and glare disappear while underwater --- apps/openmw/mwrender/sky.cpp | 8 ++++++++ apps/openmw/mwrender/sky.hpp | 1 + apps/openmw/mwrender/skyutil.cpp | 35 ++++++++++++++++++++++++-------- apps/openmw/mwrender/skyutil.hpp | 5 +++-- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index c45fadc74f..1dce3c2ddb 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -549,6 +549,7 @@ namespace MWRender return; switchUnderwaterRain(); + switchUnderwaterSun(); if (mIsStorm && mParticleNode) { @@ -646,6 +647,13 @@ namespace MWRender mRainParticleSystem->setFrozen(freeze); } + void SkyManager::switchUnderwaterSun() { + if (!mSun) + return; + bool underwater = mUnderwaterSwitch->isUnderwater(); + mSun->setUnderwater(underwater); + } + void SkyManager::setWeather(const WeatherResult& weather) { if (!mCreated) diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 4ec357056e..1f668bf955 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -120,6 +120,7 @@ namespace MWRender void createRain(); void destroyRain(); void switchUnderwaterRain(); + void switchUnderwaterSun(); void updateRainParameters(); Resource::SceneManager* mSceneManager; diff --git a/apps/openmw/mwrender/skyutil.cpp b/apps/openmw/mwrender/skyutil.cpp index faa0566016..5cc7e41acc 100644 --- a/apps/openmw/mwrender/skyutil.cpp +++ b/apps/openmw/mwrender/skyutil.cpp @@ -130,28 +130,37 @@ namespace MWRender osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal) : mOcclusionQueryVisiblePixels(std::move(oqnVisible)) , mOcclusionQueryTotalPixels(std::move(oqnTotal)) + , mUnderwater(false) { } + void OcclusionCallback::setUnderwater(bool underwater) + { + mUnderwater = underwater; + } + float OcclusionCallback::getVisibleRatio(osg::Camera* camera) { int visible = mOcclusionQueryVisiblePixels->getQueryGeometry()->getNumPixels(camera); int total = mOcclusionQueryTotalPixels->getQueryGeometry()->getNumPixels(camera); float visibleRatio = 0.f; - if (total > 0) - visibleRatio = static_cast(visible) / static_cast(total); + if (!mUnderwater) + { + if (total > 0) + visibleRatio = static_cast(visible) / static_cast(total); - float dt = MWBase::Environment::get().getFrameDuration(); + float dt = MWBase::Environment::get().getFrameDuration(); - float lastRatio = mLastRatio[osg::observer_ptr(camera)]; + float lastRatio = mLastRatio[osg::observer_ptr(camera)]; - float change = dt * 10; + float change = dt * 5; - if (visibleRatio > lastRatio) - visibleRatio = std::min(visibleRatio, lastRatio + change); - else - visibleRatio = std::max(visibleRatio, lastRatio - change); + if (visibleRatio > lastRatio) + visibleRatio = std::min(visibleRatio, lastRatio + change); + else + visibleRatio = std::max(visibleRatio, lastRatio - change); + } mLastRatio[osg::observer_ptr(camera)] = visibleRatio; @@ -829,6 +838,14 @@ namespace MWRender mSunFlashCallback->setGlareView(ratio); } + void Sun::setUnderwater(bool underwater) + { + if (mSunFlashCallback) + mSunFlashCallback->setUnderwater(underwater); + if (mSunGlareCallback) + mSunGlareCallback->setUnderwater(underwater); + } + void Sun::setDirection(const osg::Vec3f& direction) { osg::Vec3f normalizedDirection = direction / direction.length(); diff --git a/apps/openmw/mwrender/skyutil.hpp b/apps/openmw/mwrender/skyutil.hpp index da038e6c58..76450c75b2 100644 --- a/apps/openmw/mwrender/skyutil.hpp +++ b/apps/openmw/mwrender/skyutil.hpp @@ -113,6 +113,7 @@ namespace MWRender public: OcclusionCallback( osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal); + void setUnderwater(bool underwater); protected: float getVisibleRatio(osg::Camera* camera); @@ -120,7 +121,7 @@ namespace MWRender private: osg::ref_ptr mOcclusionQueryVisiblePixels; osg::ref_ptr mOcclusionQueryTotalPixels; - + bool mUnderwater; std::map, float> mLastRatio; }; @@ -249,7 +250,7 @@ namespace MWRender void setColor(const osg::Vec4f& color); void adjustTransparency(const float ratio) override; - + void setUnderwater(bool underwater); void setDirection(const osg::Vec3f& direction); void setGlareTimeOfDayFade(float val); void setSunglare(bool enabled); From 8a0e8112477ec54c4315a4ffcf62810ea7acbd0d Mon Sep 17 00:00:00 2001 From: Alex Booher Date: Sat, 21 Sep 2024 22:56:42 -0600 Subject: [PATCH 2/6] chore: formatting --- apps/openmw/mwrender/sky.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 4b1abce66e..9378c5b803 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -648,7 +648,8 @@ namespace MWRender mRainParticleSystem->setFrozen(freeze); } - void SkyManager::switchUnderwaterSun() { + void SkyManager::switchUnderwaterSun() + { if (!mSun) return; bool underwater = mUnderwaterSwitch->isUnderwater(); From bc5afd3e9c129fe7ca266c97917438dcab1eaaf9 Mon Sep 17 00:00:00 2001 From: Alexander Booher Date: Sun, 22 Sep 2024 22:11:59 -0600 Subject: [PATCH 3/6] refactor: keep OcclusionCallback base class generic --- apps/openmw/mwrender/skyutil.cpp | 69 ++++++++++++++++++++++---------- apps/openmw/mwrender/skyutil.hpp | 18 +++++++-- 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/apps/openmw/mwrender/skyutil.cpp b/apps/openmw/mwrender/skyutil.cpp index 2b0c68c2cb..28373a4ba9 100644 --- a/apps/openmw/mwrender/skyutil.cpp +++ b/apps/openmw/mwrender/skyutil.cpp @@ -130,28 +130,16 @@ namespace MWRender osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal) : mOcclusionQueryVisiblePixels(std::move(oqnVisible)) , mOcclusionQueryTotalPixels(std::move(oqnTotal)) - , mUnderwater(false) { } - void OcclusionCallback::setUnderwater(bool underwater) + float OcclusionCallback::getVisibleRatio(osg::Camera* camera, bool smooth) { - mUnderwater = underwater; - } + float visibleRatio = updateVisibleRatio(camera); + float dt = MWBase::Environment::get().getFrameDuration(); - float OcclusionCallback::getVisibleRatio(osg::Camera* camera) - { - int visible = mOcclusionQueryVisiblePixels->getQueryGeometry()->getNumPixels(camera); - int total = mOcclusionQueryTotalPixels->getQueryGeometry()->getNumPixels(camera); - - float visibleRatio = 0.f; - if (!mUnderwater) + if (smooth) { - if (total > 0) - visibleRatio = static_cast(visible) / static_cast(total); - - float dt = MWBase::Environment::get().getFrameDuration(); - float lastRatio = mLastRatio[osg::observer_ptr(camera)]; float change = dt * 5; @@ -163,26 +151,63 @@ namespace MWRender } mLastRatio[osg::observer_ptr(camera)] = visibleRatio; + return visibleRatio; + } + + float OcclusionCallback::updateVisibleRatio(osg::Camera* camera) + { + int visible = mOcclusionQueryVisiblePixels->getQueryGeometry()->getNumPixels(camera); + int total = mOcclusionQueryTotalPixels->getQueryGeometry()->getNumPixels(camera); + float visibleRatio = 0.f; + + if (total > 0) + visibleRatio = static_cast(visible) / static_cast(total); return visibleRatio; } + SunOcclusionCallback::SunOcclusionCallback( + osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal) + : OcclusionCallback(oqnVisible, oqnTotal) + , mUnderwater(false) + { + } + + float SunOcclusionCallback::updateVisibleRatio(osg::Camera* camera) + { + if (mUnderwater) + { + return 0.0f; + } + return OcclusionCallback::updateVisibleRatio(camera); + } + + void SunOcclusionCallback::setUnderwater(bool underwater) + { + mUnderwater = underwater; + } + + bool SunOcclusionCallback::isUnderwater() + { + return mUnderwater; + } + /// SunFlashCallback handles fading/scaling of a node depending on occlusion query result. Must be attached as a /// cull callback. - class SunFlashCallback : public OcclusionCallback, + class SunFlashCallback : public SunOcclusionCallback, public SceneUtil::NodeCallback { public: SunFlashCallback( osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal) - : OcclusionCallback(std::move(oqnVisible), std::move(oqnTotal)) + : SunOcclusionCallback(std::move(oqnVisible), std::move(oqnTotal)) , mGlareView(1.f) { } void operator()(osg::Node* node, osgUtil::CullVisitor* cv) { - float visibleRatio = getVisibleRatio(cv->getCurrentCamera()); + float visibleRatio = getVisibleRatio(cv->getCurrentCamera(), !isUnderwater()); osg::ref_ptr stateset; @@ -241,13 +266,13 @@ namespace MWRender /// SunGlareCallback controls a full-screen glare effect depending on occlusion query result and the angle between /// sun and camera. Must be attached as a cull callback to the node above the glare node. - class SunGlareCallback : public OcclusionCallback, + class SunGlareCallback : public SunOcclusionCallback, public SceneUtil::NodeCallback { public: SunGlareCallback(osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal, osg::ref_ptr sunTransform) - : OcclusionCallback(std::move(oqnVisible), std::move(oqnTotal)) + : SunOcclusionCallback(std::move(oqnVisible), std::move(oqnTotal)) , mSunTransform(std::move(sunTransform)) , mTimeOfDayFade(1.f) , mGlareView(1.f) @@ -267,7 +292,7 @@ namespace MWRender void operator()(osg::Node* node, osgUtil::CullVisitor* cv) { float angleRadians = getAngleToSunInRadians(*cv->getCurrentRenderStage()->getInitialViewMatrix()); - float visibleRatio = getVisibleRatio(cv->getCurrentCamera()); + float visibleRatio = getVisibleRatio(cv->getCurrentCamera(), !isUnderwater()); const float angleMaxRadians = osg::DegreesToRadians(mSunGlareFaderAngleMax); diff --git a/apps/openmw/mwrender/skyutil.hpp b/apps/openmw/mwrender/skyutil.hpp index 76450c75b2..e3e29d2c30 100644 --- a/apps/openmw/mwrender/skyutil.hpp +++ b/apps/openmw/mwrender/skyutil.hpp @@ -113,18 +113,30 @@ namespace MWRender public: OcclusionCallback( osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal); - void setUnderwater(bool underwater); + float getVisibleRatio(osg::Camera* camera, bool smooth); protected: - float getVisibleRatio(osg::Camera* camera); + virtual float updateVisibleRatio(osg::Camera* camera); private: osg::ref_ptr mOcclusionQueryVisiblePixels; osg::ref_ptr mOcclusionQueryTotalPixels; - bool mUnderwater; std::map, float> mLastRatio; }; + class SunOcclusionCallback : public OcclusionCallback + { + public: + SunOcclusionCallback( + osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal); + virtual float updateVisibleRatio(osg::Camera* camera) override; + void setUnderwater(bool underwater); + bool isUnderwater(); + + private: + bool mUnderwater; + }; + class AtmosphereUpdater : public SceneUtil::StateSetUpdater { public: From d635892b90addce5d92112258b476a8fa4d4e716 Mon Sep 17 00:00:00 2001 From: Alexander Booher Date: Sun, 22 Sep 2024 22:12:34 -0600 Subject: [PATCH 4/6] chore: add bug entry to changelog, add name to authors --- AUTHORS.md | 1 + CHANGELOG.md | 1 + 2 files changed, 2 insertions(+) diff --git a/AUTHORS.md b/AUTHORS.md index e5caf5fa58..c2de5a8f56 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -23,6 +23,7 @@ Programmers Aleksandar Jovanov Alex Haddad (rainChu) Alex McKibben + Alexander Booher (Sleepy_wade) alexanderkjall Alexander Nadeau (wareya) Alexander Olofsson (Ananace) diff --git a/CHANGELOG.md b/CHANGELOG.md index aef21779d0..c8a32c863d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -187,6 +187,7 @@ Bug #8048: Actors can generate negative collision extents and have no collision Bug #8063: menu_background.bik video with audio freezes the game forever Bug #8064: Lua move360 script doesn't respect the enableZoom/disableZoom Camera interface setting + Bug #8083: Sun glare visible when underwater Bug #8085: Don't search in scripts or shaders directories for "Select directories you wish to add" menu in launcher Bug #8097: GetEffect doesn't detect 0 magnitude spells Bug #8124: Normal weapon resistance is applied twice for NPCs From 734781abf608cf09538581b0b11bd5b6691371f0 Mon Sep 17 00:00:00 2001 From: Alexander Booher Date: Sun, 22 Sep 2024 22:25:23 -0600 Subject: [PATCH 5/6] fix: virtual destructors for classes that inherit from OcclusionCallback --- apps/openmw/mwrender/skyutil.cpp | 6 ++++++ apps/openmw/mwrender/skyutil.hpp | 1 + 2 files changed, 7 insertions(+) diff --git a/apps/openmw/mwrender/skyutil.cpp b/apps/openmw/mwrender/skyutil.cpp index 28373a4ba9..e37a3d1033 100644 --- a/apps/openmw/mwrender/skyutil.cpp +++ b/apps/openmw/mwrender/skyutil.cpp @@ -173,6 +173,8 @@ namespace MWRender { } + SunOcclusionCallback::~SunOcclusionCallback() {} + float SunOcclusionCallback::updateVisibleRatio(osg::Camera* camera) { if (mUnderwater) @@ -205,6 +207,8 @@ namespace MWRender { } + virtual ~SunFlashCallback() {} + void operator()(osg::Node* node, osgUtil::CullVisitor* cv) { float visibleRatio = getVisibleRatio(cv->getCurrentCamera(), !isUnderwater()); @@ -289,6 +293,8 @@ namespace MWRender mColor[i] = std::min(1.f, mColor[i]); } + virtual ~SunGlareCallback() {} + void operator()(osg::Node* node, osgUtil::CullVisitor* cv) { float angleRadians = getAngleToSunInRadians(*cv->getCurrentRenderStage()->getInitialViewMatrix()); diff --git a/apps/openmw/mwrender/skyutil.hpp b/apps/openmw/mwrender/skyutil.hpp index e3e29d2c30..71e9a02f41 100644 --- a/apps/openmw/mwrender/skyutil.hpp +++ b/apps/openmw/mwrender/skyutil.hpp @@ -129,6 +129,7 @@ namespace MWRender public: SunOcclusionCallback( osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal); + virtual ~SunOcclusionCallback(); virtual float updateVisibleRatio(osg::Camera* camera) override; void setUnderwater(bool underwater); bool isUnderwater(); From 115e6a2edaa57503ae35e99109775cb81b479e94 Mon Sep 17 00:00:00 2001 From: Alexander Booher Date: Sun, 22 Sep 2024 22:32:35 -0600 Subject: [PATCH 6/6] fix: virtual destructor for OcclusionCallback as well --- apps/openmw/mwrender/skyutil.cpp | 2 ++ apps/openmw/mwrender/skyutil.hpp | 1 + 2 files changed, 3 insertions(+) diff --git a/apps/openmw/mwrender/skyutil.cpp b/apps/openmw/mwrender/skyutil.cpp index e37a3d1033..95ca1fcf6c 100644 --- a/apps/openmw/mwrender/skyutil.cpp +++ b/apps/openmw/mwrender/skyutil.cpp @@ -154,6 +154,8 @@ namespace MWRender return visibleRatio; } + OcclusionCallback::~OcclusionCallback() {} + float OcclusionCallback::updateVisibleRatio(osg::Camera* camera) { int visible = mOcclusionQueryVisiblePixels->getQueryGeometry()->getNumPixels(camera); diff --git a/apps/openmw/mwrender/skyutil.hpp b/apps/openmw/mwrender/skyutil.hpp index 71e9a02f41..5fabdd8cd0 100644 --- a/apps/openmw/mwrender/skyutil.hpp +++ b/apps/openmw/mwrender/skyutil.hpp @@ -114,6 +114,7 @@ namespace MWRender OcclusionCallback( osg::ref_ptr oqnVisible, osg::ref_ptr oqnTotal); float getVisibleRatio(osg::Camera* camera, bool smooth); + virtual ~OcclusionCallback(); protected: virtual float updateVisibleRatio(osg::Camera* camera);