mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 06:53:52 +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();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
OSG_INFO<<"MWShadowTechnique::update(osg::NodeVisitor& "<<&nv<<")"<<std::endl;
|
||||
|
@ -925,6 +994,29 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
vdd->setNumValidShadows(numValidShadows);
|
||||
|
||||
if (numValidShadows>0)
|
||||
{
|
||||
|
|
|
@ -141,6 +141,17 @@ namespace SceneUtil {
|
|||
// forward declare
|
||||
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
|
||||
{
|
||||
LightData(ViewDependentData* vdd);
|
||||
|
@ -195,7 +206,12 @@ namespace SceneUtil {
|
|||
|
||||
virtual void releaseGLObjects(osg::State* = 0) const;
|
||||
|
||||
unsigned int numValidShadows(void) const { return _numValidShadows; }
|
||||
|
||||
void setNumValidShadows(unsigned int numValidShadows) { _numValidShadows = numValidShadows; }
|
||||
|
||||
protected:
|
||||
friend class MWShadowTechnique;
|
||||
virtual ~ViewDependentData() {}
|
||||
|
||||
MWShadowTechnique* _viewDependentShadowMap;
|
||||
|
@ -204,11 +220,16 @@ namespace SceneUtil {
|
|||
|
||||
LightDataList _lightDataList;
|
||||
ShadowDataList _shadowDataList;
|
||||
|
||||
unsigned int _numValidShadows;
|
||||
};
|
||||
|
||||
virtual ViewDependentData* createViewDependentData(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;
|
||||
mutable std::mutex _viewDependentDataMapMutex;
|
||||
typedef std::map< std::string, osg::ref_ptr<ViewDependentData> > ViewDependentDataShareMap;
|
||||
ViewDependentDataMap _viewDependentDataMap;
|
||||
ViewDependentDataShareMap _viewDependentDataShareMap;
|
||||
|
||||
osg::ref_ptr<osg::StateSet> _shadowRecievingPlaceholderStateSet;
|
||||
|
||||
|
|
Loading…
Reference in a new issue