1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-04-10 06:44:29 +00:00

Merge branch 'improved_toggleworld' into 'master'

Improved toggle world (#6364)

See merge request OpenMW/openmw!1320
This commit is contained in:
psi29a 2021-10-27 18:00:56 +00:00
commit fb3675d523
4 changed files with 61 additions and 15 deletions

View File

@ -753,12 +753,12 @@ namespace MWRender
else if (mode == Render_Scene) else if (mode == Render_Scene)
{ {
unsigned int mask = mViewer->getCamera()->getCullMask(); unsigned int mask = mViewer->getCamera()->getCullMask();
bool enabled = mask&Mask_Scene; bool enabled = !(mask&sToggleWorldMask);
enabled = !enabled;
if (enabled) if (enabled)
mask |= Mask_Scene; mask |= sToggleWorldMask;
else else
mask &= ~Mask_Scene; mask &= ~sToggleWorldMask;
mWater->showWorld(enabled);
mViewer->getCamera()->setCullMask(mask); mViewer->getCamera()->setCullMask(mask);
return enabled; return enabled;
} }

View File

@ -58,6 +58,9 @@ namespace MWRender
Mask_Groundcover = (1<<20), Mask_Groundcover = (1<<20),
}; };
// Defines masks to remove when using ToggleWorld command
constexpr static unsigned int sToggleWorldMask = Mask_Debug | Mask_Actor | Mask_Terrain | Mask_Object | Mask_Static | Mask_Groundcover;
} }
#endif #endif

View File

@ -260,6 +260,7 @@ class Refraction : public SceneUtil::RTTNode
public: public:
Refraction(uint32_t rttSize) Refraction(uint32_t rttSize)
: RTTNode(rttSize, rttSize, 1, false) : RTTNode(rttSize, rttSize, 1, false)
, mNodeMask(Refraction::sDefaultCullMask)
{ {
mClipCullNode = new ClipCullNode; mClipCullNode = new ClipCullNode;
} }
@ -273,8 +274,6 @@ public:
camera->addCullCallback(new InheritViewPointCallback); camera->addCullCallback(new InheritViewPointCallback);
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
camera->setCullMask(Mask_Effect | Mask_Scene | Mask_Object | Mask_Static | Mask_Terrain | Mask_Actor | Mask_ParticleSystem | Mask_Sky | Mask_Sun | Mask_Player | Mask_Lighting | Mask_Groundcover);
// No need for fog here, we are already applying fog on the water surface itself as well as underwater fog // No need for fog here, we are already applying fog on the water surface itself as well as underwater fog
// assign large value to effectively turn off fog // assign large value to effectively turn off fog
// shaders don't respect glDisable(GL_FOG) // shaders don't respect glDisable(GL_FOG)
@ -293,6 +292,7 @@ public:
void apply(osg::Camera* camera) override void apply(osg::Camera* camera) override
{ {
camera->setViewMatrix(mViewMatrix); camera->setViewMatrix(mViewMatrix);
camera->setCullMask(mNodeMask);
} }
void setScene(osg::Node* scene) void setScene(osg::Node* scene)
@ -314,10 +314,22 @@ public:
mClipCullNode->setPlane(osg::Plane(osg::Vec3d(0, 0, -1), osg::Vec3d(0, 0, waterLevel))); mClipCullNode->setPlane(osg::Plane(osg::Vec3d(0, 0, -1), osg::Vec3d(0, 0, waterLevel)));
} }
void showWorld(bool show)
{
if (show)
mNodeMask = Refraction::sDefaultCullMask;
else
mNodeMask = Refraction::sDefaultCullMask & ~sToggleWorldMask;
}
private: private:
osg::ref_ptr<ClipCullNode> mClipCullNode; osg::ref_ptr<ClipCullNode> mClipCullNode;
osg::ref_ptr<osg::Node> mScene; osg::ref_ptr<osg::Node> mScene;
osg::Matrix mViewMatrix{ osg::Matrix::identity() }; osg::Matrix mViewMatrix{ osg::Matrix::identity() };
unsigned int mNodeMask;
static constexpr unsigned int sDefaultCullMask = Mask_Effect | Mask_Scene | Mask_Object | Mask_Static | Mask_Terrain | Mask_Actor | Mask_ParticleSystem | Mask_Sky | Mask_Sun | Mask_Player | Mask_Lighting | Mask_Groundcover;
}; };
class Reflection : public SceneUtil::RTTNode class Reflection : public SceneUtil::RTTNode
@ -357,15 +369,8 @@ public:
void setInterior(bool isInterior) void setInterior(bool isInterior)
{ {
int reflectionDetail = Settings::Manager::getInt("reflection detail", "Water"); mInterior = isInterior;
reflectionDetail = std::min(5, std::max(isInterior ? 2 : 0, reflectionDetail)); mNodeMask = calcNodeMask();
unsigned int extraMask = 0;
if(reflectionDetail >= 1) extraMask |= Mask_Terrain;
if(reflectionDetail >= 2) extraMask |= Mask_Static;
if(reflectionDetail >= 3) extraMask |= Mask_Effect | Mask_ParticleSystem | Mask_Object;
if(reflectionDetail >= 4) extraMask |= Mask_Player | Mask_Actor;
if(reflectionDetail >= 5) extraMask |= Mask_Groundcover;
mNodeMask = Mask_Scene | Mask_Sky | Mask_Lighting | extraMask;
} }
void setWaterLevel(float waterLevel) void setWaterLevel(float waterLevel)
@ -382,11 +387,34 @@ public:
mClipCullNode->addChild(scene); mClipCullNode->addChild(scene);
} }
void showWorld(bool show)
{
if (show)
mNodeMask = calcNodeMask();
else
mNodeMask = calcNodeMask() & ~sToggleWorldMask;
}
private: private:
unsigned int calcNodeMask()
{
int reflectionDetail = Settings::Manager::getInt("reflection detail", "Water");
reflectionDetail = std::min(5, std::max(mInterior ? 2 : 0, reflectionDetail));
unsigned int extraMask = 0;
if(reflectionDetail >= 1) extraMask |= Mask_Terrain;
if(reflectionDetail >= 2) extraMask |= Mask_Static;
if(reflectionDetail >= 3) extraMask |= Mask_Effect | Mask_ParticleSystem | Mask_Object;
if(reflectionDetail >= 4) extraMask |= Mask_Player | Mask_Actor;
if(reflectionDetail >= 5) extraMask |= Mask_Groundcover;
return Mask_Scene | Mask_Sky | Mask_Lighting | extraMask;
}
osg::ref_ptr<ClipCullNode> mClipCullNode; osg::ref_ptr<ClipCullNode> mClipCullNode;
osg::ref_ptr<osg::Node> mScene; osg::ref_ptr<osg::Node> mScene;
osg::Node::NodeMask mNodeMask; osg::Node::NodeMask mNodeMask;
osg::Matrix mViewMatrix{ osg::Matrix::identity() }; osg::Matrix mViewMatrix{ osg::Matrix::identity() };
bool mInterior;
}; };
/// DepthClampCallback enables GL_DEPTH_CLAMP for the current draw, if supported. /// DepthClampCallback enables GL_DEPTH_CLAMP for the current draw, if supported.
@ -422,6 +450,7 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem
, mToggled(true) , mToggled(true)
, mTop(0) , mTop(0)
, mInterior(false) , mInterior(false)
, mShowWorld(true)
, mCullCallback(nullptr) , mCullCallback(nullptr)
, mShaderWaterStateSetUpdater(nullptr) , mShaderWaterStateSetUpdater(nullptr)
{ {
@ -519,6 +548,8 @@ void Water::updateWaterMaterial()
mParent->addChild(mRefraction); mParent->addChild(mRefraction);
} }
showWorld(mShowWorld);
createShaderWaterStateSet(mWaterNode, mReflection, mRefraction); createShaderWaterStateSet(mWaterNode, mReflection, mRefraction);
} }
else else
@ -812,4 +843,13 @@ void Water::clearRipples()
mSimulation->clear(); mSimulation->clear();
} }
void Water::showWorld(bool show)
{
if (mReflection)
mReflection->showWorld(show);
if (mRefraction)
mRefraction->showWorld(show);
mShowWorld = show;
}
} }

View File

@ -71,6 +71,7 @@ namespace MWRender
bool mToggled; bool mToggled;
float mTop; float mTop;
bool mInterior; bool mInterior;
bool mShowWorld;
osg::Callback* mCullCallback; osg::Callback* mCullCallback;
osg::ref_ptr<osg::Callback> mShaderWaterStateSetUpdater; osg::ref_ptr<osg::Callback> mShaderWaterStateSetUpdater;
@ -124,6 +125,8 @@ namespace MWRender
osg::Vec3d getPosition() const; osg::Vec3d getPosition() const;
void processChangedSettings(const Settings::CategorySettingVector& settings); void processChangedSettings(const Settings::CategorySettingVector& settings);
void showWorld(bool show);
}; };
} }