Affect correct texture units when disabling shadows for stateset

Knowing which are right required making the function non-static, so the shadow manager had to become a singleton as the results of passing it around to where it's needed were hellish.

I'm seeing a bunch of OpenGL errors when actually using this, so I'll investigate whether they're happening on master.
I'm hesitant to look into it too much, though, as I'm affected by https://gitlab.com/OpenMW/openmw/-/issues/7811, and also have the Windows setting enabled that turns driver timeouts into a BSOD so a kernel dump is collected that I can send to AMD.
fix-osga-rotate-wildly
AnyOldName3 10 months ago
parent e88e92d3aa
commit 535c5e328a

@ -247,7 +247,7 @@ namespace MWRender
defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f)); defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f));
stateset->setAttribute(defaultMat); stateset->setAttribute(defaultMat);
SceneUtil::ShadowManager::disableShadowsForStateSet(Settings::shadows(), *stateset); SceneUtil::ShadowManager::instance().disableShadowsForStateSet(*stateset);
// 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)

@ -763,7 +763,7 @@ namespace MWRender
lightSource->setStateSetModes(*stateset, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); lightSource->setStateSetModes(*stateset, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
SceneUtil::ShadowManager::disableShadowsForStateSet(Settings::shadows(), *stateset); SceneUtil::ShadowManager::instance().disableShadowsForStateSet(*stateset);
// override sun for local map // override sun for local map
SceneUtil::configureStateSetSunOverride(static_cast<SceneUtil::LightManager*>(mSceneRoot), light, stateset); SceneUtil::configureStateSetSunOverride(static_cast<SceneUtil::LightManager*>(mSceneRoot), light, stateset);

@ -220,7 +220,7 @@ namespace
camera->setNodeMask(MWRender::Mask_RenderToTexture); camera->setNodeMask(MWRender::Mask_RenderToTexture);
camera->setCullMask(MWRender::Mask_Sky); camera->setCullMask(MWRender::Mask_Sky);
camera->addChild(mEarlyRenderBinRoot); camera->addChild(mEarlyRenderBinRoot);
SceneUtil::ShadowManager::disableShadowsForStateSet(Settings::shadows(), *camera->getOrCreateStateSet()); SceneUtil::ShadowManager::instance().disableShadowsForStateSet(*camera->getOrCreateStateSet());
} }
private: private:
@ -274,7 +274,7 @@ namespace MWRender
if (!mSceneManager->getForceShaders()) if (!mSceneManager->getForceShaders())
skyroot->getOrCreateStateSet()->setAttributeAndModes(new osg::Program(), skyroot->getOrCreateStateSet()->setAttributeAndModes(new osg::Program(),
osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON); osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
SceneUtil::ShadowManager::disableShadowsForStateSet(Settings::shadows(), *skyroot->getOrCreateStateSet()); SceneUtil::ShadowManager::instance().disableShadowsForStateSet(*skyroot->getOrCreateStateSet());
parentNode->addChild(skyroot); parentNode->addChild(skyroot);
mEarlyRenderBinRoot = new osg::Group; mEarlyRenderBinRoot = new osg::Group;

@ -276,8 +276,7 @@ namespace MWRender
camera->setNodeMask(Mask_RenderToTexture); camera->setNodeMask(Mask_RenderToTexture);
if (Settings::water().mRefractionScale != 1) // TODO: to be removed with issue #5709 if (Settings::water().mRefractionScale != 1) // TODO: to be removed with issue #5709
SceneUtil::ShadowManager::disableShadowsForStateSet( SceneUtil::ShadowManager::instance().disableShadowsForStateSet(*camera->getOrCreateStateSet());
Settings::shadows(), *camera->getOrCreateStateSet());
} }
void apply(osg::Camera* camera) override void apply(osg::Camera* camera) override
@ -353,7 +352,7 @@ namespace MWRender
camera->addChild(mClipCullNode); camera->addChild(mClipCullNode);
camera->setNodeMask(Mask_RenderToTexture); camera->setNodeMask(Mask_RenderToTexture);
SceneUtil::ShadowManager::disableShadowsForStateSet(Settings::shadows(), *camera->getOrCreateStateSet()); SceneUtil::ShadowManager::instance().disableShadowsForStateSet(*camera->getOrCreateStateSet());
} }
void apply(osg::Camera* camera) override void apply(osg::Camera* camera) override

@ -13,6 +13,16 @@ namespace SceneUtil
{ {
using namespace osgShadow; using namespace osgShadow;
ShadowManager* ShadowManager::sInstance = nullptr;
const ShadowManager& ShadowManager::instance()
{
if (sInstance)
return *sInstance;
else
throw std::logic_error("No ShadowManager exists yet");
}
void ShadowManager::setupShadowSettings( void ShadowManager::setupShadowSettings(
const Settings::ShadowsCategory& settings, Shader::ShaderManager& shaderManager) const Settings::ShadowsCategory& settings, Shader::ShaderManager& shaderManager)
{ {
@ -75,15 +85,11 @@ namespace SceneUtil
mShadowTechnique->disableDebugHUD(); mShadowTechnique->disableDebugHUD();
} }
void ShadowManager::disableShadowsForStateSet(const Settings::ShadowsCategory& settings, osg::StateSet& stateset) void ShadowManager::disableShadowsForStateSet(osg::StateSet& stateset) const
{ {
if (!settings.mEnableShadows) if (!mEnableShadows)
return; return;
const int numberOfShadowMapsPerLight = settings.mNumberOfShadowMaps;
int baseShadowTextureUnit = 8 - numberOfShadowMapsPerLight;
osg::ref_ptr<osg::Image> fakeShadowMapImage = new osg::Image(); osg::ref_ptr<osg::Image> fakeShadowMapImage = new osg::Image();
fakeShadowMapImage->allocateImage(1, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT); fakeShadowMapImage->allocateImage(1, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT);
*(float*)fakeShadowMapImage->data() = std::numeric_limits<float>::infinity(); *(float*)fakeShadowMapImage->data() = std::numeric_limits<float>::infinity();
@ -92,14 +98,15 @@ namespace SceneUtil
fakeShadowMapTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); fakeShadowMapTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
fakeShadowMapTexture->setShadowComparison(true); fakeShadowMapTexture->setShadowComparison(true);
fakeShadowMapTexture->setShadowCompareFunc(osg::Texture::ShadowCompareFunc::ALWAYS); fakeShadowMapTexture->setShadowCompareFunc(osg::Texture::ShadowCompareFunc::ALWAYS);
for (int i = baseShadowTextureUnit; i < baseShadowTextureUnit + numberOfShadowMapsPerLight; ++i) for (int i = mShadowSettings->getBaseShadowTextureUnit();
i < mShadowSettings->getBaseShadowTextureUnit() + mShadowSettings->getNumShadowMapsPerLight(); ++i)
{ {
stateset.setTextureAttributeAndModes(i, fakeShadowMapTexture, stateset.setTextureAttributeAndModes(i, fakeShadowMapTexture,
osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED); osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
stateset.addUniform( stateset.addUniform(new osg::Uniform(
new osg::Uniform(("shadowTexture" + std::to_string(i - baseShadowTextureUnit)).c_str(), i)); ("shadowTexture" + std::to_string(i - mShadowSettings->getBaseShadowTextureUnit())).c_str(), i));
stateset.addUniform( stateset.addUniform(new osg::Uniform(
new osg::Uniform(("shadowTextureUnit" + std::to_string(i - baseShadowTextureUnit)).c_str(), i)); ("shadowTextureUnit" + std::to_string(i - mShadowSettings->getBaseShadowTextureUnit())).c_str(), i));
} }
} }
@ -111,6 +118,9 @@ namespace SceneUtil
, mOutdoorShadowCastingMask(outdoorShadowCastingMask) , mOutdoorShadowCastingMask(outdoorShadowCastingMask)
, mIndoorShadowCastingMask(indoorShadowCastingMask) , mIndoorShadowCastingMask(indoorShadowCastingMask)
{ {
if (sInstance)
throw std::logic_error("A ShadowManager already exists");
mShadowedScene->setShadowTechnique(mShadowTechnique); mShadowedScene->setShadowTechnique(mShadowTechnique);
if (Stereo::getStereo()) if (Stereo::getStereo())
@ -127,6 +137,8 @@ namespace SceneUtil
mShadowTechnique->setWorldMask(worldMask); mShadowTechnique->setWorldMask(worldMask);
enableOutdoorMode(); enableOutdoorMode();
sInstance = this;
} }
ShadowManager::~ShadowManager() ShadowManager::~ShadowManager()
@ -135,7 +147,7 @@ namespace SceneUtil
Stereo::Manager::instance().setShadowTechnique(nullptr); Stereo::Manager::instance().setShadowTechnique(nullptr);
} }
Shader::ShaderManager::DefineMap ShadowManager::getShadowDefines(const Settings::ShadowsCategory& settings) Shader::ShaderManager::DefineMap ShadowManager::getShadowDefines(const Settings::ShadowsCategory& settings) const
{ {
if (!mEnableShadows) if (!mEnableShadows)
return getShadowsDisabledDefines(); return getShadowsDisabledDefines();

@ -26,10 +26,10 @@ namespace SceneUtil
class ShadowManager class ShadowManager
{ {
public: public:
static void disableShadowsForStateSet(const Settings::ShadowsCategory& settings, osg::StateSet& stateset);
static Shader::ShaderManager::DefineMap getShadowsDisabledDefines(); static Shader::ShaderManager::DefineMap getShadowsDisabledDefines();
static const ShadowManager& instance();
explicit ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, explicit ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode,
unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, unsigned int worldMask, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, unsigned int worldMask,
const Settings::ShadowsCategory& settings, Shader::ShaderManager& shaderManager); const Settings::ShadowsCategory& settings, Shader::ShaderManager& shaderManager);
@ -37,13 +37,17 @@ namespace SceneUtil
void setupShadowSettings(const Settings::ShadowsCategory& settings, Shader::ShaderManager& shaderManager); void setupShadowSettings(const Settings::ShadowsCategory& settings, Shader::ShaderManager& shaderManager);
Shader::ShaderManager::DefineMap getShadowDefines(const Settings::ShadowsCategory& settings); void disableShadowsForStateSet(osg::StateSet& stateset) const;
Shader::ShaderManager::DefineMap getShadowDefines(const Settings::ShadowsCategory& settings) const;
void enableIndoorMode(const Settings::ShadowsCategory& settings); void enableIndoorMode(const Settings::ShadowsCategory& settings);
void enableOutdoorMode(); void enableOutdoorMode();
protected: protected:
static ShadowManager* sInstance;
bool mEnableShadows; bool mEnableShadows;
osg::ref_ptr<osgShadow::ShadowedScene> mShadowedScene; osg::ref_ptr<osgShadow::ShadowedScene> mShadowedScene;

Loading…
Cancel
Save