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));
stateset->setAttribute(defaultMat);
SceneUtil::ShadowManager::disableShadowsForStateSet(Settings::shadows(), *stateset);
SceneUtil::ShadowManager::instance().disableShadowsForStateSet(*stateset);
// assign large value to effectively turn off fog
// shaders don't respect glDisable(GL_FOG)

@ -763,7 +763,7 @@ namespace MWRender
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
SceneUtil::configureStateSetSunOverride(static_cast<SceneUtil::LightManager*>(mSceneRoot), light, stateset);

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

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

@ -13,6 +13,16 @@ namespace SceneUtil
{
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(
const Settings::ShadowsCategory& settings, Shader::ShaderManager& shaderManager)
{
@ -75,15 +85,11 @@ namespace SceneUtil
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;
const int numberOfShadowMapsPerLight = settings.mNumberOfShadowMaps;
int baseShadowTextureUnit = 8 - numberOfShadowMapsPerLight;
osg::ref_ptr<osg::Image> fakeShadowMapImage = new osg::Image();
fakeShadowMapImage->allocateImage(1, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT);
*(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->setShadowComparison(true);
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,
osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
stateset.addUniform(
new osg::Uniform(("shadowTexture" + std::to_string(i - baseShadowTextureUnit)).c_str(), i));
stateset.addUniform(
new osg::Uniform(("shadowTextureUnit" + std::to_string(i - baseShadowTextureUnit)).c_str(), i));
stateset.addUniform(new osg::Uniform(
("shadowTexture" + std::to_string(i - mShadowSettings->getBaseShadowTextureUnit())).c_str(), i));
stateset.addUniform(new osg::Uniform(
("shadowTextureUnit" + std::to_string(i - mShadowSettings->getBaseShadowTextureUnit())).c_str(), i));
}
}
@ -111,6 +118,9 @@ namespace SceneUtil
, mOutdoorShadowCastingMask(outdoorShadowCastingMask)
, mIndoorShadowCastingMask(indoorShadowCastingMask)
{
if (sInstance)
throw std::logic_error("A ShadowManager already exists");
mShadowedScene->setShadowTechnique(mShadowTechnique);
if (Stereo::getStereo())
@ -127,6 +137,8 @@ namespace SceneUtil
mShadowTechnique->setWorldMask(worldMask);
enableOutdoorMode();
sInstance = this;
}
ShadowManager::~ShadowManager()
@ -135,7 +147,7 @@ namespace SceneUtil
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)
return getShadowsDisabledDefines();

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

Loading…
Cancel
Save