mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-01 09:45:33 +00:00
shareable shadow maps
This commit is contained in:
parent
49b78ef463
commit
d923c3f77a
2 changed files with 116 additions and 0 deletions
|
@ -900,6 +900,75 @@ MWShadowTechnique::ViewDependentData* MWShadowTechnique::getViewDependentData(os
|
||||||
return vdd.release();
|
return vdd.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWShadowTechnique::ViewDependentData* MWShadowTechnique::getSharedVdd(const SharedShadowMapConfig& config)
|
||||||
|
{
|
||||||
|
auto it = _viewDependentDataShareMap.find(config._id);
|
||||||
|
if (it != _viewDependentDataShareMap.end())
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MWShadowTechnique::addSharedVdd(const SharedShadowMapConfig& config, ViewDependentData* vdd)
|
||||||
|
{
|
||||||
|
_viewDependentDataShareMap[config._id] = vdd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SceneUtil::MWShadowTechnique::shareShadowMap(osgUtil::CullVisitor& cv, ViewDependentData* lhs, ViewDependentData* rhs)
|
||||||
|
{
|
||||||
|
// Prepare for rendering shadows using the shadow map owned by rhs.
|
||||||
|
|
||||||
|
// To achieve this i first copy all data that is not specific to this cv's camera and thus read-only,
|
||||||
|
// trusting openmw and osg won't overwrite that data before this frame is done rendering.
|
||||||
|
// This works due to the double buffering of CullVisitors by osg, but also requires that cull passes are serialized (relative to one another).
|
||||||
|
// Then initialize new copies of the data that will be written with view-specific data
|
||||||
|
// (the stateset and the texgens).
|
||||||
|
|
||||||
|
lhs->_viewDependentShadowMap = rhs->_viewDependentShadowMap;
|
||||||
|
lhs->_stateset->clear();
|
||||||
|
lhs->_lightDataList = rhs->_lightDataList;
|
||||||
|
lhs->_numValidShadows = rhs->_numValidShadows;
|
||||||
|
|
||||||
|
ShadowDataList& sdl = lhs->getShadowDataList();
|
||||||
|
ShadowDataList previous_sdl;
|
||||||
|
previous_sdl.swap(sdl);
|
||||||
|
for (auto rhs_sd : rhs->getShadowDataList())
|
||||||
|
{
|
||||||
|
osg::ref_ptr<ShadowData> lhs_sd;
|
||||||
|
|
||||||
|
if (previous_sdl.empty())
|
||||||
|
{
|
||||||
|
OSG_INFO << "Create new ShadowData" << std::endl;
|
||||||
|
lhs_sd = new ShadowData(lhs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OSG_INFO << "Taking ShadowData from from of previous_sdl" << std::endl;
|
||||||
|
lhs_sd = previous_sdl.front();
|
||||||
|
previous_sdl.erase(previous_sdl.begin());
|
||||||
|
}
|
||||||
|
lhs_sd->_camera = rhs_sd->_camera;
|
||||||
|
lhs_sd->_textureUnit = rhs_sd->_textureUnit;
|
||||||
|
lhs_sd->_texture = rhs_sd->_texture;
|
||||||
|
sdl.push_back(lhs_sd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cv.pushStateSet(_shadowRecievingPlaceholderStateSet.get());
|
||||||
|
osg::ref_ptr<osgUtil::StateGraph> decoratorStateGraph = cv.getCurrentStateGraph();
|
||||||
|
cullShadowReceivingScene(&cv);
|
||||||
|
cv.popStateSet();
|
||||||
|
|
||||||
|
for (auto sd : sdl)
|
||||||
|
{
|
||||||
|
assignTexGenSettings(&cv, sd->_camera, sd->_textureUnit, sd->_texgen.get());
|
||||||
|
}
|
||||||
|
if (lhs->numValidShadows() > 0)
|
||||||
|
{
|
||||||
|
decoratorStateGraph->setStateSet(selectStateSetForRenderingShadow(*lhs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MWShadowTechnique::update(osg::NodeVisitor& nv)
|
void MWShadowTechnique::update(osg::NodeVisitor& nv)
|
||||||
{
|
{
|
||||||
OSG_INFO<<"MWShadowTechnique::update(osg::NodeVisitor& "<<&nv<<")"<<std::endl;
|
OSG_INFO<<"MWShadowTechnique::update(osg::NodeVisitor& "<<&nv<<")"<<std::endl;
|
||||||
|
@ -925,6 +994,29 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
||||||
|
|
||||||
ViewDependentData* vdd = getViewDependentData(&cv);
|
ViewDependentData* vdd = getViewDependentData(&cv);
|
||||||
|
|
||||||
|
// Use shared shadow map if applicable
|
||||||
|
auto* sharedConfig = dynamic_cast<SharedShadowMapConfig*>(cv.getCurrentCamera()->getUserData());
|
||||||
|
if (sharedConfig)
|
||||||
|
{
|
||||||
|
if (sharedConfig->_master)
|
||||||
|
{
|
||||||
|
addSharedVdd(*sharedConfig, vdd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto* sharedVdd = getSharedVdd(*sharedConfig);
|
||||||
|
if (sharedVdd)
|
||||||
|
{
|
||||||
|
OSG_INFO << "Using shared shadow map" << std::endl;
|
||||||
|
return shareShadowMap(cv, vdd, sharedVdd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OSG_INFO << "Warning, view configured to reuse shared shadow map but no shadow map has been shared. Shadows will be generated instead." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!vdd)
|
if (!vdd)
|
||||||
{
|
{
|
||||||
OSG_INFO<<"Warning, now ViewDependentData created, unable to create shadows."<<std::endl;
|
OSG_INFO<<"Warning, now ViewDependentData created, unable to create shadows."<<std::endl;
|
||||||
|
@ -1397,6 +1489,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
|
||||||
_debugHud->draw(sd->_texture, sm_i, camera->getViewMatrix() * camera->getProjectionMatrix(), cv);
|
_debugHud->draw(sd->_texture, sm_i, camera->getViewMatrix() * camera->getProjectionMatrix(), cv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vdd->setNumValidShadows(numValidShadows);
|
||||||
|
|
||||||
if (numValidShadows>0)
|
if (numValidShadows>0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -141,6 +141,17 @@ namespace SceneUtil {
|
||||||
// forward declare
|
// forward declare
|
||||||
class ViewDependentData;
|
class ViewDependentData;
|
||||||
|
|
||||||
|
/// Configuration of shadow maps shared by multiple views
|
||||||
|
struct SharedShadowMapConfig : public osg::Referenced
|
||||||
|
{
|
||||||
|
virtual ~SharedShadowMapConfig() {}
|
||||||
|
|
||||||
|
/// String identifier of the shared shadow map
|
||||||
|
std::string _id;
|
||||||
|
|
||||||
|
bool _master;
|
||||||
|
};
|
||||||
|
|
||||||
struct LightData : public osg::Referenced
|
struct LightData : public osg::Referenced
|
||||||
{
|
{
|
||||||
LightData(ViewDependentData* vdd);
|
LightData(ViewDependentData* vdd);
|
||||||
|
@ -195,7 +206,12 @@ namespace SceneUtil {
|
||||||
|
|
||||||
virtual void releaseGLObjects(osg::State* = 0) const;
|
virtual void releaseGLObjects(osg::State* = 0) const;
|
||||||
|
|
||||||
|
unsigned int numValidShadows(void) const { return _numValidShadows; }
|
||||||
|
|
||||||
|
void setNumValidShadows(unsigned int numValidShadows) { _numValidShadows = numValidShadows; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
friend class MWShadowTechnique;
|
||||||
virtual ~ViewDependentData() {}
|
virtual ~ViewDependentData() {}
|
||||||
|
|
||||||
MWShadowTechnique* _viewDependentShadowMap;
|
MWShadowTechnique* _viewDependentShadowMap;
|
||||||
|
@ -204,11 +220,16 @@ namespace SceneUtil {
|
||||||
|
|
||||||
LightDataList _lightDataList;
|
LightDataList _lightDataList;
|
||||||
ShadowDataList _shadowDataList;
|
ShadowDataList _shadowDataList;
|
||||||
|
|
||||||
|
unsigned int _numValidShadows;
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ViewDependentData* createViewDependentData(osgUtil::CullVisitor* cv);
|
virtual ViewDependentData* createViewDependentData(osgUtil::CullVisitor* cv);
|
||||||
|
|
||||||
ViewDependentData* getViewDependentData(osgUtil::CullVisitor* cv);
|
ViewDependentData* getViewDependentData(osgUtil::CullVisitor* cv);
|
||||||
|
ViewDependentData* getSharedVdd(const SharedShadowMapConfig& config);
|
||||||
|
void addSharedVdd(const SharedShadowMapConfig& config, ViewDependentData* vdd);
|
||||||
|
void shareShadowMap(osgUtil::CullVisitor& cv, ViewDependentData* lhs, ViewDependentData* rhs);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -237,7 +258,9 @@ namespace SceneUtil {
|
||||||
|
|
||||||
typedef std::map< osgUtil::CullVisitor*, osg::ref_ptr<ViewDependentData> > ViewDependentDataMap;
|
typedef std::map< osgUtil::CullVisitor*, osg::ref_ptr<ViewDependentData> > ViewDependentDataMap;
|
||||||
mutable std::mutex _viewDependentDataMapMutex;
|
mutable std::mutex _viewDependentDataMapMutex;
|
||||||
|
typedef std::map< std::string, osg::ref_ptr<ViewDependentData> > ViewDependentDataShareMap;
|
||||||
ViewDependentDataMap _viewDependentDataMap;
|
ViewDependentDataMap _viewDependentDataMap;
|
||||||
|
ViewDependentDataShareMap _viewDependentDataShareMap;
|
||||||
|
|
||||||
osg::ref_ptr<osg::StateSet> _shadowRecievingPlaceholderStateSet;
|
osg::ref_ptr<osg::StateSet> _shadowRecievingPlaceholderStateSet;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue