diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e4b70780..58a09429b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Bug #4764: Data race in osg ParticleSystem Bug #4765: Data race in ChunkManager -> Array::setBinding Bug #4774: Guards are ignorant of an invisible player that tries to attack them + Bug #5026: Data races with rain intensity uniform set by sky and used by water Bug #5101: Hostile followers travel with the player Bug #5108: Savegame bloating due to inefficient fog textures format Bug #5165: Active spells should use real time intead of timestamps diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index a3aee5c0f..452104642 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -370,7 +370,6 @@ namespace MWRender mSky.reset(new SkyManager(sceneRoot, resourceSystem->getSceneManager())); mSky->setCamera(mViewer->getCamera()); - mSky->setRainIntensityUniform(mWater->getRainIntensityUniform()); source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON); @@ -658,6 +657,9 @@ namespace MWRender mUnrefQueue->flush(mWorkQueue.get()); + float rainIntensity = mSky->getEffectFade(); + mWater->setRainIntensity(rainIntensity); + if (!paused) { mEffectManager->update(dt); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 389944000..d6b1f9066 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -1113,7 +1113,6 @@ private: SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager) : mSceneManager(sceneManager) , mCamera(nullptr) - , mRainIntensityUniform(nullptr) , mAtmosphereNightRoll(0.f) , mCreated(false) , mIsStorm(false) @@ -1163,11 +1162,6 @@ SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneMana mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot); } -void SkyManager::setRainIntensityUniform(osg::Uniform *uniform) -{ - mRainIntensityUniform = uniform; -} - void SkyManager::create() { assert(!mCreated); @@ -1576,30 +1570,21 @@ bool SkyManager::isEnabled() return mEnabled; } -bool SkyManager::hasRain() +bool SkyManager::hasRain() const { return mRainNode != nullptr; } -void SkyManager::update(float duration) +float SkyManager::getEffectFade() const { - if (!mEnabled) - { - if (mRainIntensityUniform) - mRainIntensityUniform->set(0.f); - - return; - } - - if (mRainIntensityUniform) - { - float rainIntensity = 0.f; - if (!mIsStorm && (hasRain() || mParticleNode)) - rainIntensity = mEffectFade; + if (mEnabled && !mIsStorm && (hasRain() || mParticleNode)) + return mEffectFade; - mRainIntensityUniform->set(rainIntensity); - } + return 0.f; +} +void SkyManager::update(float duration) +{ switchUnderwaterRain(); if (mIsStorm) diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index f32c40192..081221398 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -7,7 +7,6 @@ #include #include -#include namespace osg { @@ -157,7 +156,9 @@ namespace MWRender bool isEnabled(); - bool hasRain(); + bool hasRain() const; + + float getEffectFade() const; void setRainSpeed(float speed); @@ -180,8 +181,6 @@ namespace MWRender void setCamera(osg::Camera *camera); - void setRainIntensityUniform(osg::Uniform *uniform); - float getBaseWindSpeed() const; private: @@ -196,7 +195,6 @@ namespace MWRender Resource::SceneManager* mSceneManager; osg::Camera *mCamera; - osg::Uniform *mRainIntensityUniform; osg::ref_ptr mRootNode; osg::ref_ptr mEarlyRenderBinRoot; diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 1cc5a3cb7..af24a8648 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -208,6 +208,37 @@ public: } }; +class RainIntensityUpdater : public SceneUtil::StateSetUpdater +{ +public: + RainIntensityUpdater() + : mRainIntensity(0.f) + { + } + + void setRainIntensity(float rainIntensity) + { + mRainIntensity = rainIntensity; + } + +protected: + void setDefaults(osg::StateSet* stateset) override + { + osg::ref_ptr rainIntensityUniform = new osg::Uniform("rainIntensity", 0.0f); + stateset->addUniform(rainIntensityUniform.get()); + } + + void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override + { + osg::ref_ptr rainIntensityUniform = stateset->getUniform("rainIntensity"); + if (rainIntensityUniform != nullptr) + rainIntensityUniform->set(mRainIntensity); + } + +private: + float mRainIntensity; +}; + osg::ref_ptr readPngImage (const std::string& file) { // use boost in favor of osgDB::readImage, to handle utf-8 path issues on Windows @@ -431,7 +462,8 @@ public: Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem, osgUtil::IncrementalCompileOperation *ico, const std::string& resourcePath) - : mParent(parent) + : mRainIntensityUpdater(nullptr) + , mParent(parent) , mSceneRoot(sceneRoot) , mResourceSystem(resourceSystem) , mResourcePath(resourcePath) @@ -463,8 +495,6 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem setHeight(mTop); - mRainIntensityUniform = new osg::Uniform("rainIntensity",(float) 0.0); - updateWaterMaterial(); if (ico) @@ -494,11 +524,6 @@ void Water::setCullCallback(osg::Callback* callback) } } -osg::Uniform *Water::getRainIntensityUniform() -{ - return mRainIntensityUniform.get(); -} - void Water::updateWaterMaterial() { if (mReflection) @@ -556,6 +581,8 @@ void Water::createSimpleWaterStateSet(osg::Node* node, float alpha) osg::ref_ptr stateset = SceneUtil::createSimpleWaterStateSet(alpha, MWRender::RenderBin_Water); node->setStateSet(stateset); + node->setUpdateCallback(nullptr); + mRainIntensityUpdater = nullptr; // Add animated textures std::vector > textures; @@ -639,15 +666,15 @@ void Water::createShaderWaterStateSet(osg::Node* node, Reflection* reflection, R shaderStateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); - shaderStateset->addUniform(mRainIntensityUniform.get()); - osg::ref_ptr program (new osg::Program); program->addShader(vertexShader); program->addShader(fragmentShader); shaderStateset->setAttributeAndModes(program, osg::StateAttribute::ON); node->setStateSet(shaderStateset); - node->setUpdateCallback(nullptr); + + mRainIntensityUpdater = new RainIntensityUpdater(); + node->setUpdateCallback(mRainIntensityUpdater); } void Water::processChangedSettings(const Settings::CategorySettingVector& settings) @@ -730,6 +757,12 @@ void Water::setHeight(const float height) mRefraction->setWaterLevel(mTop); } +void Water::setRainIntensity(float rainIntensity) +{ + if (mRainIntensityUpdater) + mRainIntensityUpdater->setRainIntensity(rainIntensity); +} + void Water::update(float dt) { mSimulation->update(dt); diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 3787ef426..ec7dc95db 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -6,7 +6,6 @@ #include #include -#include #include #include @@ -46,11 +45,12 @@ namespace MWRender class Refraction; class Reflection; class RippleSimulation; + class RainIntensityUpdater; /// Water rendering class Water { - osg::ref_ptr mRainIntensityUniform; + osg::ref_ptr mRainIntensityUpdater; osg::ref_ptr mParent; osg::ref_ptr mSceneRoot; @@ -112,6 +112,7 @@ namespace MWRender void changeCell(const MWWorld::CellStore* store); void setHeight(const float height); + void setRainIntensity(const float rainIntensity); void update(float dt); @@ -119,8 +120,6 @@ namespace MWRender osg::Camera *getRefractionCamera(); void processChangedSettings(const Settings::CategorySettingVector& settings); - - osg::Uniform *getRainIntensityUniform(); }; }