mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:53:51 +00:00
Double-buffer shader water stateset (bug #5026)
This commit is contained in:
parent
213525c372
commit
d805886de7
6 changed files with 63 additions and 45 deletions
|
@ -34,6 +34,7 @@
|
||||||
Bug #4764: Data race in osg ParticleSystem
|
Bug #4764: Data race in osg ParticleSystem
|
||||||
Bug #4765: Data race in ChunkManager -> Array::setBinding
|
Bug #4765: Data race in ChunkManager -> Array::setBinding
|
||||||
Bug #4774: Guards are ignorant of an invisible player that tries to attack them
|
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 #5101: Hostile followers travel with the player
|
||||||
Bug #5108: Savegame bloating due to inefficient fog textures format
|
Bug #5108: Savegame bloating due to inefficient fog textures format
|
||||||
Bug #5165: Active spells should use real time intead of timestamps
|
Bug #5165: Active spells should use real time intead of timestamps
|
||||||
|
|
|
@ -370,7 +370,6 @@ namespace MWRender
|
||||||
|
|
||||||
mSky.reset(new SkyManager(sceneRoot, resourceSystem->getSceneManager()));
|
mSky.reset(new SkyManager(sceneRoot, resourceSystem->getSceneManager()));
|
||||||
mSky->setCamera(mViewer->getCamera());
|
mSky->setCamera(mViewer->getCamera());
|
||||||
mSky->setRainIntensityUniform(mWater->getRainIntensityUniform());
|
|
||||||
|
|
||||||
source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON);
|
source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
@ -658,6 +657,9 @@ namespace MWRender
|
||||||
|
|
||||||
mUnrefQueue->flush(mWorkQueue.get());
|
mUnrefQueue->flush(mWorkQueue.get());
|
||||||
|
|
||||||
|
float rainIntensity = mSky->getEffectFade();
|
||||||
|
mWater->setRainIntensity(rainIntensity);
|
||||||
|
|
||||||
if (!paused)
|
if (!paused)
|
||||||
{
|
{
|
||||||
mEffectManager->update(dt);
|
mEffectManager->update(dt);
|
||||||
|
|
|
@ -1113,7 +1113,6 @@ private:
|
||||||
SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager)
|
SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneManager)
|
||||||
: mSceneManager(sceneManager)
|
: mSceneManager(sceneManager)
|
||||||
, mCamera(nullptr)
|
, mCamera(nullptr)
|
||||||
, mRainIntensityUniform(nullptr)
|
|
||||||
, mAtmosphereNightRoll(0.f)
|
, mAtmosphereNightRoll(0.f)
|
||||||
, mCreated(false)
|
, mCreated(false)
|
||||||
, mIsStorm(false)
|
, mIsStorm(false)
|
||||||
|
@ -1163,11 +1162,6 @@ SkyManager::SkyManager(osg::Group* parentNode, Resource::SceneManager* sceneMana
|
||||||
mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot);
|
mUnderwaterSwitch = new UnderwaterSwitchCallback(skyroot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkyManager::setRainIntensityUniform(osg::Uniform *uniform)
|
|
||||||
{
|
|
||||||
mRainIntensityUniform = uniform;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SkyManager::create()
|
void SkyManager::create()
|
||||||
{
|
{
|
||||||
assert(!mCreated);
|
assert(!mCreated);
|
||||||
|
@ -1576,30 +1570,21 @@ bool SkyManager::isEnabled()
|
||||||
return mEnabled;
|
return mEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SkyManager::hasRain()
|
bool SkyManager::hasRain() const
|
||||||
{
|
{
|
||||||
return mRainNode != nullptr;
|
return mRainNode != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float SkyManager::getEffectFade() const
|
||||||
|
{
|
||||||
|
if (mEnabled && !mIsStorm && (hasRain() || mParticleNode))
|
||||||
|
return mEffectFade;
|
||||||
|
|
||||||
|
return 0.f;
|
||||||
|
}
|
||||||
|
|
||||||
void SkyManager::update(float duration)
|
void SkyManager::update(float duration)
|
||||||
{
|
{
|
||||||
if (!mEnabled)
|
|
||||||
{
|
|
||||||
if (mRainIntensityUniform)
|
|
||||||
mRainIntensityUniform->set(0.f);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mRainIntensityUniform)
|
|
||||||
{
|
|
||||||
float rainIntensity = 0.f;
|
|
||||||
if (!mIsStorm && (hasRain() || mParticleNode))
|
|
||||||
rainIntensity = mEffectFade;
|
|
||||||
|
|
||||||
mRainIntensityUniform->set(rainIntensity);
|
|
||||||
}
|
|
||||||
|
|
||||||
switchUnderwaterRain();
|
switchUnderwaterRain();
|
||||||
|
|
||||||
if (mIsStorm)
|
if (mIsStorm)
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
#include <osg/Vec4f>
|
#include <osg/Vec4f>
|
||||||
#include <osg/Uniform>
|
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
|
@ -157,7 +156,9 @@ namespace MWRender
|
||||||
|
|
||||||
bool isEnabled();
|
bool isEnabled();
|
||||||
|
|
||||||
bool hasRain();
|
bool hasRain() const;
|
||||||
|
|
||||||
|
float getEffectFade() const;
|
||||||
|
|
||||||
void setRainSpeed(float speed);
|
void setRainSpeed(float speed);
|
||||||
|
|
||||||
|
@ -180,8 +181,6 @@ namespace MWRender
|
||||||
|
|
||||||
void setCamera(osg::Camera *camera);
|
void setCamera(osg::Camera *camera);
|
||||||
|
|
||||||
void setRainIntensityUniform(osg::Uniform *uniform);
|
|
||||||
|
|
||||||
float getBaseWindSpeed() const;
|
float getBaseWindSpeed() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -196,7 +195,6 @@ namespace MWRender
|
||||||
Resource::SceneManager* mSceneManager;
|
Resource::SceneManager* mSceneManager;
|
||||||
|
|
||||||
osg::Camera *mCamera;
|
osg::Camera *mCamera;
|
||||||
osg::Uniform *mRainIntensityUniform;
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Group> mRootNode;
|
osg::ref_ptr<osg::Group> mRootNode;
|
||||||
osg::ref_ptr<osg::Group> mEarlyRenderBinRoot;
|
osg::ref_ptr<osg::Group> mEarlyRenderBinRoot;
|
||||||
|
|
|
@ -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<osg::Uniform> rainIntensityUniform = new osg::Uniform("rainIntensity", 0.0f);
|
||||||
|
stateset->addUniform(rainIntensityUniform.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
void apply(osg::StateSet* stateset, osg::NodeVisitor* /*nv*/) override
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Uniform> rainIntensityUniform = stateset->getUniform("rainIntensity");
|
||||||
|
if (rainIntensityUniform != nullptr)
|
||||||
|
rainIntensityUniform->set(mRainIntensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
float mRainIntensity;
|
||||||
|
};
|
||||||
|
|
||||||
osg::ref_ptr<osg::Image> readPngImage (const std::string& file)
|
osg::ref_ptr<osg::Image> readPngImage (const std::string& file)
|
||||||
{
|
{
|
||||||
// use boost in favor of osgDB::readImage, to handle utf-8 path issues on Windows
|
// 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,
|
Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem *resourceSystem,
|
||||||
osgUtil::IncrementalCompileOperation *ico, const std::string& resourcePath)
|
osgUtil::IncrementalCompileOperation *ico, const std::string& resourcePath)
|
||||||
: mParent(parent)
|
: mRainIntensityUpdater(nullptr)
|
||||||
|
, mParent(parent)
|
||||||
, mSceneRoot(sceneRoot)
|
, mSceneRoot(sceneRoot)
|
||||||
, mResourceSystem(resourceSystem)
|
, mResourceSystem(resourceSystem)
|
||||||
, mResourcePath(resourcePath)
|
, mResourcePath(resourcePath)
|
||||||
|
@ -463,8 +495,6 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem
|
||||||
|
|
||||||
setHeight(mTop);
|
setHeight(mTop);
|
||||||
|
|
||||||
mRainIntensityUniform = new osg::Uniform("rainIntensity",(float) 0.0);
|
|
||||||
|
|
||||||
updateWaterMaterial();
|
updateWaterMaterial();
|
||||||
|
|
||||||
if (ico)
|
if (ico)
|
||||||
|
@ -494,11 +524,6 @@ void Water::setCullCallback(osg::Callback* callback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Uniform *Water::getRainIntensityUniform()
|
|
||||||
{
|
|
||||||
return mRainIntensityUniform.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Water::updateWaterMaterial()
|
void Water::updateWaterMaterial()
|
||||||
{
|
{
|
||||||
if (mReflection)
|
if (mReflection)
|
||||||
|
@ -556,6 +581,8 @@ void Water::createSimpleWaterStateSet(osg::Node* node, float alpha)
|
||||||
osg::ref_ptr<osg::StateSet> stateset = SceneUtil::createSimpleWaterStateSet(alpha, MWRender::RenderBin_Water);
|
osg::ref_ptr<osg::StateSet> stateset = SceneUtil::createSimpleWaterStateSet(alpha, MWRender::RenderBin_Water);
|
||||||
|
|
||||||
node->setStateSet(stateset);
|
node->setStateSet(stateset);
|
||||||
|
node->setUpdateCallback(nullptr);
|
||||||
|
mRainIntensityUpdater = nullptr;
|
||||||
|
|
||||||
// Add animated textures
|
// Add animated textures
|
||||||
std::vector<osg::ref_ptr<osg::Texture2D> > textures;
|
std::vector<osg::ref_ptr<osg::Texture2D> > textures;
|
||||||
|
@ -639,15 +666,15 @@ void Water::createShaderWaterStateSet(osg::Node* node, Reflection* reflection, R
|
||||||
|
|
||||||
shaderStateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
shaderStateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
|
||||||
|
|
||||||
shaderStateset->addUniform(mRainIntensityUniform.get());
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Program> program (new osg::Program);
|
osg::ref_ptr<osg::Program> program (new osg::Program);
|
||||||
program->addShader(vertexShader);
|
program->addShader(vertexShader);
|
||||||
program->addShader(fragmentShader);
|
program->addShader(fragmentShader);
|
||||||
shaderStateset->setAttributeAndModes(program, osg::StateAttribute::ON);
|
shaderStateset->setAttributeAndModes(program, osg::StateAttribute::ON);
|
||||||
|
|
||||||
node->setStateSet(shaderStateset);
|
node->setStateSet(shaderStateset);
|
||||||
node->setUpdateCallback(nullptr);
|
|
||||||
|
mRainIntensityUpdater = new RainIntensityUpdater();
|
||||||
|
node->setUpdateCallback(mRainIntensityUpdater);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Water::processChangedSettings(const Settings::CategorySettingVector& settings)
|
void Water::processChangedSettings(const Settings::CategorySettingVector& settings)
|
||||||
|
@ -730,6 +757,12 @@ void Water::setHeight(const float height)
|
||||||
mRefraction->setWaterLevel(mTop);
|
mRefraction->setWaterLevel(mTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Water::setRainIntensity(float rainIntensity)
|
||||||
|
{
|
||||||
|
if (mRainIntensityUpdater)
|
||||||
|
mRainIntensityUpdater->setRainIntensity(rainIntensity);
|
||||||
|
}
|
||||||
|
|
||||||
void Water::update(float dt)
|
void Water::update(float dt)
|
||||||
{
|
{
|
||||||
mSimulation->update(dt);
|
mSimulation->update(dt);
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
#include <osg/Uniform>
|
|
||||||
#include <osg/Camera>
|
#include <osg/Camera>
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
@ -46,11 +45,12 @@ namespace MWRender
|
||||||
class Refraction;
|
class Refraction;
|
||||||
class Reflection;
|
class Reflection;
|
||||||
class RippleSimulation;
|
class RippleSimulation;
|
||||||
|
class RainIntensityUpdater;
|
||||||
|
|
||||||
/// Water rendering
|
/// Water rendering
|
||||||
class Water
|
class Water
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Uniform> mRainIntensityUniform;
|
osg::ref_ptr<RainIntensityUpdater> mRainIntensityUpdater;
|
||||||
|
|
||||||
osg::ref_ptr<osg::Group> mParent;
|
osg::ref_ptr<osg::Group> mParent;
|
||||||
osg::ref_ptr<osg::Group> mSceneRoot;
|
osg::ref_ptr<osg::Group> mSceneRoot;
|
||||||
|
@ -112,6 +112,7 @@ namespace MWRender
|
||||||
|
|
||||||
void changeCell(const MWWorld::CellStore* store);
|
void changeCell(const MWWorld::CellStore* store);
|
||||||
void setHeight(const float height);
|
void setHeight(const float height);
|
||||||
|
void setRainIntensity(const float rainIntensity);
|
||||||
|
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
|
|
||||||
|
@ -119,8 +120,6 @@ namespace MWRender
|
||||||
osg::Camera *getRefractionCamera();
|
osg::Camera *getRefractionCamera();
|
||||||
|
|
||||||
void processChangedSettings(const Settings::CategorySettingVector& settings);
|
void processChangedSettings(const Settings::CategorySettingVector& settings);
|
||||||
|
|
||||||
osg::Uniform *getRainIntensityUniform();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue