1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-27 12:35:46 +00:00

99 lines
4.3 KiB
C++
Raw Normal View History

#include "shadow.hpp"
#include <osgShadow/ShadowedScene>
#include <osg/CullFace>
#include <osg/Geode>
#include <osg/io_utils>
#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
2017-12-27 02:32:17 +00:00
#include <components/settings/settings.hpp>
2017-11-08 01:44:49 +00:00
namespace SceneUtil
{
using namespace osgShadow;
2018-02-26 22:27:09 +00:00
void ShadowManager::setupShadowSettings(int castsShadowMask)
2017-12-27 02:32:17 +00:00
{
if (!Settings::Manager::getBool("enable shadows", "Shadows"))
2018-02-26 22:27:09 +00:00
{
mShadowTechnique->disableShadows();
2017-12-27 02:32:17 +00:00
return;
2018-02-26 22:27:09 +00:00
}
else
mShadowTechnique->enableShadows();
osg::ref_ptr<osgShadow::ShadowSettings> settings = mShadowedScene->getShadowSettings();
2017-12-27 02:32:17 +00:00
settings->setLightNum(0);
settings->setCastsShadowTraversalMask(castsShadowMask);
settings->setReceivesShadowTraversalMask(~0u);
int numberOfShadowMapsPerLight = Settings::Manager::getInt("number of shadow maps", "Shadows");
settings->setNumShadowMapsPerLight(numberOfShadowMapsPerLight);
settings->setBaseShadowTextureUnit(8 - numberOfShadowMapsPerLight);
settings->setMinimumShadowMapNearFarRatio(Settings::Manager::getFloat("minimum lispsm near far ratio", "Shadows"));
2017-12-27 02:32:17 +00:00
if (Settings::Manager::getBool("compute tight scene bounds", "Shadows"))
settings->setComputeNearFarModeOverride(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
int mapres = Settings::Manager::getInt("shadow map resolution", "Shadows");
settings->setTextureSize(osg::Vec2s(mapres, mapres));
2018-02-26 22:27:09 +00:00
if (Settings::Manager::getBool("enable debug hud", "Shadows"))
mShadowTechnique->enableDebugHUD();
else
mShadowTechnique->disableDebugHUD();
2017-12-27 02:32:17 +00:00
}
void ShadowManager::disableShadowsForStateSet(osg::ref_ptr<osg::StateSet> stateset)
{
2017-12-27 02:32:17 +00:00
int numberOfShadowMapsPerLight = Settings::Manager::getInt("number of shadow maps", "Shadows");
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();
osg::ref_ptr<osg::Texture> fakeShadowMapTexture = new osg::Texture2D(fakeShadowMapImage);
fakeShadowMapTexture->setShadowComparison(true);
fakeShadowMapTexture->setShadowCompareFunc(osg::Texture::ShadowCompareFunc::ALWAYS);
for (int i = baseShadowTextureUnit; i < baseShadowTextureUnit + numberOfShadowMapsPerLight; ++i)
stateset->setTextureAttributeAndModes(i, fakeShadowMapTexture, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
}
2018-02-26 22:27:09 +00:00
ShadowManager::ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode) : enableShadows(Settings::Manager::getBool("enable shadows", "Shadows")),
2017-12-27 02:32:17 +00:00
numberOfShadowMapsPerLight(Settings::Manager::getInt("number of shadow maps", "Shadows")),
baseShadowTextureUnit(8 - numberOfShadowMapsPerLight),
2018-02-26 22:27:09 +00:00
mShadowedScene(new osgShadow::ShadowedScene),
mShadowTechnique(new MWShadowTechnique)
{
2018-02-26 22:27:09 +00:00
mShadowedScene->setShadowTechnique(mShadowTechnique);
mShadowedScene->addChild(sceneRoot);
rootNode->addChild(mShadowedScene);
}
Shader::ShaderManager::DefineMap ShadowManager::getShadowDefines()
{
if (!enableShadows)
return getShadowsDisabledDefines();
Shader::ShaderManager::DefineMap definesWithShadows;
definesWithShadows.insert(std::make_pair(std::string("shadows_enabled"), std::string("1")));
for (int i = 0; i < numberOfShadowMapsPerLight; ++i)
definesWithShadows["shadow_texture_unit_list"] += std::to_string(i) + ",";
// remove extra comma
definesWithShadows["shadow_texture_unit_list"] = definesWithShadows["shadow_texture_unit_list"].substr(0, definesWithShadows["shadow_texture_unit_list"].length() - 1);
return definesWithShadows;
}
Shader::ShaderManager::DefineMap ShadowManager::getShadowsDisabledDefines()
{
Shader::ShaderManager::DefineMap definesWithShadows;
definesWithShadows.insert(std::make_pair(std::string("shadows_enabled"), std::string("0")));
definesWithShadows["shadow_texture_unit_list"] = "";
return definesWithShadows;
}
}