mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-29 17:15:34 +00:00
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.
This commit is contained in:
parent
e88e92d3aa
commit
535c5e328a
6 changed files with 37 additions and 22 deletions
|
@ -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…
Reference in a new issue