mirror of
https://github.com/OpenMW/openmw.git
synced 2025-07-04 18:11:34 +00:00
Merge branch 'shadow-uniform-thread-safety' into 'master'
Shadow uniform thread safety Closes #5026 See merge request OpenMW/openmw!284
This commit is contained in:
commit
a740b77b3d
2 changed files with 47 additions and 45 deletions
|
@ -749,7 +749,8 @@ MWShadowTechnique::ViewDependentData::ViewDependentData(MWShadowTechnique* vdsm)
|
||||||
_viewDependentShadowMap(vdsm)
|
_viewDependentShadowMap(vdsm)
|
||||||
{
|
{
|
||||||
OSG_INFO<<"ViewDependentData::ViewDependentData()"<<this<<std::endl;
|
OSG_INFO<<"ViewDependentData::ViewDependentData()"<<this<<std::endl;
|
||||||
_stateset = new osg::StateSet;
|
for (auto& perFrameStateset : _stateset)
|
||||||
|
perFrameStateset = new osg::StateSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWShadowTechnique::ViewDependentData::releaseGLObjects(osg::State* state) const
|
void MWShadowTechnique::ViewDependentData::releaseGLObjects(osg::State* state) const
|
||||||
|
@ -1343,9 +1344,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
||||||
std::string validRegionUniformName = "validRegionMatrix" + std::to_string(sm_i);
|
std::string validRegionUniformName = "validRegionMatrix" + std::to_string(sm_i);
|
||||||
osg::ref_ptr<osg::Uniform> validRegionUniform;
|
osg::ref_ptr<osg::Uniform> validRegionUniform;
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(_accessUniformsAndProgramMutex);
|
for (auto uniform : _uniforms[cv.getTraversalNumber() % 2])
|
||||||
|
|
||||||
for (auto uniform : _uniforms)
|
|
||||||
{
|
{
|
||||||
if (uniform->getName() == validRegionUniformName)
|
if (uniform->getName() == validRegionUniformName)
|
||||||
validRegionUniform = uniform;
|
validRegionUniform = uniform;
|
||||||
|
@ -1354,7 +1353,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
||||||
if (!validRegionUniform)
|
if (!validRegionUniform)
|
||||||
{
|
{
|
||||||
validRegionUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, validRegionUniformName);
|
validRegionUniform = new osg::Uniform(osg::Uniform::FLOAT_MAT4, validRegionUniformName);
|
||||||
_uniforms.push_back(validRegionUniform);
|
_uniforms[cv.getTraversalNumber() % 2].push_back(validRegionUniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
validRegionUniform->set(validRegionMatrix);
|
validRegionUniform->set(validRegionMatrix);
|
||||||
|
@ -1400,7 +1399,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
||||||
|
|
||||||
if (numValidShadows>0)
|
if (numValidShadows>0)
|
||||||
{
|
{
|
||||||
decoratorStateGraph->setStateSet(selectStateSetForRenderingShadow(*vdd));
|
decoratorStateGraph->setStateSet(selectStateSetForRenderingShadow(*vdd, cv.getTraversalNumber()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// OSG_NOTICE<<"End of shadow setup Projection matrix "<<*cv.getProjectionMatrix()<<std::endl;
|
// OSG_NOTICE<<"End of shadow setup Projection matrix "<<*cv.getProjectionMatrix()<<std::endl;
|
||||||
|
@ -1467,8 +1466,6 @@ void MWShadowTechnique::createShaders()
|
||||||
|
|
||||||
unsigned int _baseTextureUnit = 0;
|
unsigned int _baseTextureUnit = 0;
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(_accessUniformsAndProgramMutex);
|
|
||||||
|
|
||||||
_shadowCastingStateSet = new osg::StateSet;
|
_shadowCastingStateSet = new osg::StateSet;
|
||||||
|
|
||||||
ShadowSettings* settings = getShadowedScene()->getShadowSettings();
|
ShadowSettings* settings = getShadowedScene()->getShadowSettings();
|
||||||
|
@ -1501,15 +1498,20 @@ void MWShadowTechnique::createShaders()
|
||||||
_shadowCastingStateSet->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
_shadowCastingStateSet->setMode(GL_POLYGON_OFFSET_FILL, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
|
||||||
|
|
||||||
|
|
||||||
_uniforms.clear();
|
|
||||||
osg::ref_ptr<osg::Uniform> baseTextureSampler = new osg::Uniform("baseTexture",(int)_baseTextureUnit);
|
osg::ref_ptr<osg::Uniform> baseTextureSampler = new osg::Uniform("baseTexture",(int)_baseTextureUnit);
|
||||||
_uniforms.push_back(baseTextureSampler.get());
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Uniform> baseTextureUnit = new osg::Uniform("baseTextureUnit",(int)_baseTextureUnit);
|
osg::ref_ptr<osg::Uniform> baseTextureUnit = new osg::Uniform("baseTextureUnit",(int)_baseTextureUnit);
|
||||||
_uniforms.push_back(baseTextureUnit.get());
|
|
||||||
|
|
||||||
_uniforms.push_back(new osg::Uniform("maximumShadowMapDistance", (float)settings->getMaximumShadowMapDistance()));
|
osg::ref_ptr<osg::Uniform> maxDistance = new osg::Uniform("maximumShadowMapDistance", (float)settings->getMaximumShadowMapDistance());
|
||||||
_uniforms.push_back(new osg::Uniform("shadowFadeStart", (float)_shadowFadeStart));
|
osg::ref_ptr<osg::Uniform> fadeStart = new osg::Uniform("shadowFadeStart", (float)_shadowFadeStart);
|
||||||
|
|
||||||
|
for (auto& perFrameUniformList : _uniforms)
|
||||||
|
{
|
||||||
|
perFrameUniformList.clear();
|
||||||
|
perFrameUniformList.push_back(baseTextureSampler);
|
||||||
|
perFrameUniformList.push_back(baseTextureUnit.get());
|
||||||
|
perFrameUniformList.push_back(maxDistance);
|
||||||
|
perFrameUniformList.push_back(fadeStart);
|
||||||
|
}
|
||||||
|
|
||||||
for(unsigned int sm_i=0; sm_i<settings->getNumShadowMapsPerLight(); ++sm_i)
|
for(unsigned int sm_i=0; sm_i<settings->getNumShadowMapsPerLight(); ++sm_i)
|
||||||
{
|
{
|
||||||
|
@ -1517,14 +1519,16 @@ void MWShadowTechnique::createShaders()
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
sstr<<"shadowTexture"<<sm_i;
|
sstr<<"shadowTexture"<<sm_i;
|
||||||
osg::ref_ptr<osg::Uniform> shadowTextureSampler = new osg::Uniform(sstr.str().c_str(),(int)(settings->getBaseShadowTextureUnit()+sm_i));
|
osg::ref_ptr<osg::Uniform> shadowTextureSampler = new osg::Uniform(sstr.str().c_str(),(int)(settings->getBaseShadowTextureUnit()+sm_i));
|
||||||
_uniforms.push_back(shadowTextureSampler.get());
|
for (auto& perFrameUniformList : _uniforms)
|
||||||
|
perFrameUniformList.push_back(shadowTextureSampler.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
sstr<<"shadowTextureUnit"<<sm_i;
|
sstr<<"shadowTextureUnit"<<sm_i;
|
||||||
osg::ref_ptr<osg::Uniform> shadowTextureUnit = new osg::Uniform(sstr.str().c_str(),(int)(settings->getBaseShadowTextureUnit()+sm_i));
|
osg::ref_ptr<osg::Uniform> shadowTextureUnit = new osg::Uniform(sstr.str().c_str(),(int)(settings->getBaseShadowTextureUnit()+sm_i));
|
||||||
_uniforms.push_back(shadowTextureUnit.get());
|
for (auto& perFrameUniformList : _uniforms)
|
||||||
|
perFrameUniformList.push_back(shadowTextureUnit.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2974,24 +2978,20 @@ void MWShadowTechnique::cullShadowCastingScene(osgUtil::CullVisitor* cv, osg::Ca
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::StateSet* MWShadowTechnique::selectStateSetForRenderingShadow(ViewDependentData& vdd) const
|
osg::StateSet* MWShadowTechnique::selectStateSetForRenderingShadow(ViewDependentData& vdd, unsigned int traversalNumber) const
|
||||||
{
|
{
|
||||||
OSG_INFO<<" selectStateSetForRenderingShadow() "<<vdd.getStateSet()<<std::endl;
|
OSG_INFO<<" selectStateSetForRenderingShadow() "<<vdd.getStateSet(traversalNumber)<<std::endl;
|
||||||
|
|
||||||
osg::ref_ptr<osg::StateSet> stateset = vdd.getStateSet();
|
osg::ref_ptr<osg::StateSet> stateset = vdd.getStateSet(traversalNumber);
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock(_accessUniformsAndProgramMutex);
|
stateset->clear();
|
||||||
|
|
||||||
vdd.getStateSet()->clear();
|
stateset->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON);
|
||||||
|
|
||||||
vdd.getStateSet()->setTextureAttributeAndModes(0, _fallbackBaseTexture.get(), osg::StateAttribute::ON);
|
for(const auto& uniform : _uniforms[traversalNumber % 2])
|
||||||
|
|
||||||
for(Uniforms::const_iterator itr=_uniforms.begin();
|
|
||||||
itr!=_uniforms.end();
|
|
||||||
++itr)
|
|
||||||
{
|
{
|
||||||
OSG_INFO<<"addUniform("<<(*itr)->getName()<<")"<<std::endl;
|
OSG_INFO<<"addUniform("<<uniform->getName()<<")"<<std::endl;
|
||||||
stateset->addUniform(itr->get());
|
stateset->addUniform(uniform);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_program.valid())
|
if (_program.valid())
|
||||||
|
@ -3047,7 +3047,7 @@ osg::StateSet* MWShadowTechnique::selectStateSetForRenderingShadow(ViewDependent
|
||||||
stateset->setTextureMode(sd._textureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
|
stateset->setTextureMode(sd._textureUnit,GL_TEXTURE_GEN_Q,osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vdd.getStateSet();
|
return stateset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MWShadowTechnique::resizeGLObjectBuffers(unsigned int /*maxSize*/)
|
void MWShadowTechnique::resizeGLObjectBuffers(unsigned int /*maxSize*/)
|
||||||
|
@ -3104,12 +3104,12 @@ SceneUtil::MWShadowTechnique::DebugHUD::DebugHUD(int numberOfShadowMapsPerLight)
|
||||||
fragmentShader = new osg::Shader(osg::Shader::FRAGMENT, debugFrustumFragmentShaderSource);
|
fragmentShader = new osg::Shader(osg::Shader::FRAGMENT, debugFrustumFragmentShaderSource);
|
||||||
frustumProgram->addShader(fragmentShader);
|
frustumProgram->addShader(fragmentShader);
|
||||||
|
|
||||||
for (int i = 0; i < 2; ++i)
|
for (auto& frustumGeometry : mFrustumGeometries)
|
||||||
{
|
{
|
||||||
mFrustumGeometries.emplace_back(new osg::Geometry());
|
frustumGeometry = new osg::Geometry();
|
||||||
mFrustumGeometries[i]->setCullingActive(false);
|
frustumGeometry->setCullingActive(false);
|
||||||
|
|
||||||
mFrustumGeometries[i]->getOrCreateStateSet()->setAttributeAndModes(frustumProgram, osg::StateAttribute::ON);
|
frustumGeometry->getOrCreateStateSet()->setAttributeAndModes(frustumProgram, osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<osg::DrawElementsUShort> frustumDrawElements = new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP);
|
osg::ref_ptr<osg::DrawElementsUShort> frustumDrawElements = new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP);
|
||||||
|
@ -3146,11 +3146,13 @@ void SceneUtil::MWShadowTechnique::DebugHUD::draw(osg::ref_ptr<osg::Texture2D> t
|
||||||
if (shadowMapNumber > mDebugCameras.size())
|
if (shadowMapNumber > mDebugCameras.size())
|
||||||
addAnotherShadowMap();
|
addAnotherShadowMap();
|
||||||
|
|
||||||
mFrustumUniforms[shadowMapNumber]->set(matrix);
|
osg::ref_ptr<osg::StateSet> stateSet = new osg::StateSet();
|
||||||
|
|
||||||
osg::ref_ptr<osg::StateSet> stateSet = mDebugGeometry[shadowMapNumber]->getOrCreateStateSet();
|
|
||||||
stateSet->setTextureAttributeAndModes(sDebugTextureUnit, texture, osg::StateAttribute::ON);
|
stateSet->setTextureAttributeAndModes(sDebugTextureUnit, texture, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
auto frustumUniform = mFrustumUniforms[cv.getTraversalNumber() % 2][shadowMapNumber];
|
||||||
|
frustumUniform->set(matrix);
|
||||||
|
stateSet->addUniform(frustumUniform);
|
||||||
|
|
||||||
// Some of these calls may be superfluous.
|
// Some of these calls may be superfluous.
|
||||||
unsigned int traversalMask = cv.getTraversalMask();
|
unsigned int traversalMask = cv.getTraversalMask();
|
||||||
cv.setTraversalMask(mDebugGeometry[shadowMapNumber]->getNodeMask());
|
cv.setTraversalMask(mDebugGeometry[shadowMapNumber]->getNodeMask());
|
||||||
|
@ -3205,6 +3207,6 @@ void SceneUtil::MWShadowTechnique::DebugHUD::addAnotherShadowMap()
|
||||||
mFrustumTransforms[shadowMapNumber]->setCullingActive(false);
|
mFrustumTransforms[shadowMapNumber]->setCullingActive(false);
|
||||||
mDebugCameras[shadowMapNumber]->addChild(mFrustumTransforms[shadowMapNumber]);
|
mDebugCameras[shadowMapNumber]->addChild(mFrustumTransforms[shadowMapNumber]);
|
||||||
|
|
||||||
mFrustumUniforms.push_back(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "transform"));
|
for(auto& uniformVector : mFrustumUniforms)
|
||||||
mFrustumTransforms[shadowMapNumber]->getOrCreateStateSet()->addUniform(mFrustumUniforms[shadowMapNumber]);
|
uniformVector.push_back(new osg::Uniform(osg::Uniform::FLOAT_MAT4, "transform"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#ifndef COMPONENTS_SCENEUTIL_MWSHADOWTECHNIQUE_H
|
#ifndef COMPONENTS_SCENEUTIL_MWSHADOWTECHNIQUE_H
|
||||||
#define COMPONENTS_SCENEUTIL_MWSHADOWTECHNIQUE_H 1
|
#define COMPONENTS_SCENEUTIL_MWSHADOWTECHNIQUE_H 1
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <osg/Camera>
|
#include <osg/Camera>
|
||||||
|
@ -191,7 +192,7 @@ namespace SceneUtil {
|
||||||
|
|
||||||
ShadowDataList& getShadowDataList() { return _shadowDataList; }
|
ShadowDataList& getShadowDataList() { return _shadowDataList; }
|
||||||
|
|
||||||
osg::StateSet* getStateSet() { return _stateset.get(); }
|
osg::StateSet* getStateSet(unsigned int traversalNumber) { return _stateset[traversalNumber % 2].get(); }
|
||||||
|
|
||||||
virtual void releaseGLObjects(osg::State* = 0) const;
|
virtual void releaseGLObjects(osg::State* = 0) const;
|
||||||
|
|
||||||
|
@ -200,7 +201,7 @@ namespace SceneUtil {
|
||||||
|
|
||||||
MWShadowTechnique* _viewDependentShadowMap;
|
MWShadowTechnique* _viewDependentShadowMap;
|
||||||
|
|
||||||
osg::ref_ptr<osg::StateSet> _stateset;
|
std::array<osg::ref_ptr<osg::StateSet>, 2> _stateset;
|
||||||
|
|
||||||
LightDataList _lightDataList;
|
LightDataList _lightDataList;
|
||||||
ShadowDataList _shadowDataList;
|
ShadowDataList _shadowDataList;
|
||||||
|
@ -230,7 +231,7 @@ namespace SceneUtil {
|
||||||
|
|
||||||
virtual void cullShadowCastingScene(osgUtil::CullVisitor* cv, osg::Camera* camera) const;
|
virtual void cullShadowCastingScene(osgUtil::CullVisitor* cv, osg::Camera* camera) const;
|
||||||
|
|
||||||
virtual osg::StateSet* selectStateSetForRenderingShadow(ViewDependentData& vdd) const;
|
virtual osg::StateSet* selectStateSetForRenderingShadow(ViewDependentData& vdd, unsigned int traversalNumber) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual ~MWShadowTechnique();
|
virtual ~MWShadowTechnique();
|
||||||
|
@ -247,8 +248,7 @@ namespace SceneUtil {
|
||||||
osg::ref_ptr<osg::Texture2D> _fallbackShadowMapTexture;
|
osg::ref_ptr<osg::Texture2D> _fallbackShadowMapTexture;
|
||||||
|
|
||||||
typedef std::vector< osg::ref_ptr<osg::Uniform> > Uniforms;
|
typedef std::vector< osg::ref_ptr<osg::Uniform> > Uniforms;
|
||||||
mutable std::mutex _accessUniformsAndProgramMutex;
|
std::array<Uniforms, 2> _uniforms;
|
||||||
Uniforms _uniforms;
|
|
||||||
osg::ref_ptr<osg::Program> _program;
|
osg::ref_ptr<osg::Program> _program;
|
||||||
|
|
||||||
bool _enableShadows;
|
bool _enableShadows;
|
||||||
|
@ -282,8 +282,8 @@ namespace SceneUtil {
|
||||||
osg::ref_ptr<osg::Program> mDebugProgram;
|
osg::ref_ptr<osg::Program> mDebugProgram;
|
||||||
std::vector<osg::ref_ptr<osg::Node>> mDebugGeometry;
|
std::vector<osg::ref_ptr<osg::Node>> mDebugGeometry;
|
||||||
std::vector<osg::ref_ptr<osg::Group>> mFrustumTransforms;
|
std::vector<osg::ref_ptr<osg::Group>> mFrustumTransforms;
|
||||||
std::vector<osg::ref_ptr<osg::Uniform>> mFrustumUniforms;
|
std::array<std::vector<osg::ref_ptr<osg::Uniform>>, 2> mFrustumUniforms;
|
||||||
std::vector<osg::ref_ptr<osg::Geometry>> mFrustumGeometries;
|
std::array<osg::ref_ptr<osg::Geometry>, 2> mFrustumGeometries;
|
||||||
};
|
};
|
||||||
|
|
||||||
osg::ref_ptr<DebugHUD> _debugHud;
|
osg::ref_ptr<DebugHUD> _debugHud;
|
||||||
|
|
Loading…
Reference in a new issue