mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 05:49:56 +00:00
e197f5318b
conversion from 'const float' to 'int', possible loss of data conversion from 'double' to 'int', possible loss of data conversion from 'float' to 'int', possible loss of data
187 lines
7.5 KiB
C++
187 lines
7.5 KiB
C++
#include "shadows.hpp"
|
|
|
|
#include <components/settings/settings.hpp>
|
|
#include <openengine/ogre/renderer.hpp>
|
|
|
|
#include <OgreSceneManager.h>
|
|
#include <OgreColourValue.h>
|
|
#include <OgreShadowCameraSetupLiSPSM.h>
|
|
#include <OgreShadowCameraSetupPSSM.h>
|
|
#include <OgreHardwarePixelBuffer.h>
|
|
#include <OgreCamera.h>
|
|
#include <OgreRenderTexture.h>
|
|
#include <OgreViewport.h>
|
|
|
|
#include <extern/shiny/Main/Factory.hpp>
|
|
|
|
#include "renderconst.hpp"
|
|
|
|
using namespace Ogre;
|
|
using namespace MWRender;
|
|
|
|
Shadows::Shadows(OEngine::Render::OgreRenderer* rend) :
|
|
mRendering(rend), mSceneMgr(rend->getScene()), mPSSMSetup(NULL),
|
|
mShadowFar(1000), mFadeStart(0.9f)
|
|
{
|
|
recreate();
|
|
}
|
|
|
|
void Shadows::recreate()
|
|
{
|
|
bool enabled = Settings::Manager::getBool("enabled", "Shadows");
|
|
|
|
bool split = Settings::Manager::getBool("split", "Shadows");
|
|
|
|
sh::Factory::getInstance ().setGlobalSetting ("shadows", enabled && !split ? "true" : "false");
|
|
sh::Factory::getInstance ().setGlobalSetting ("shadows_pssm", enabled && split ? "true" : "false");
|
|
|
|
if (!enabled)
|
|
{
|
|
mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
|
|
return;
|
|
}
|
|
|
|
int texsize = Settings::Manager::getInt("texture size", "Shadows");
|
|
mSceneMgr->setShadowTextureSize(texsize);
|
|
|
|
mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED);
|
|
|
|
// no point light shadows, i'm afraid. might revisit this with Deferred Shading
|
|
mSceneMgr->setShadowTextureCountPerLightType(Light::LT_POINT, 0);
|
|
|
|
mSceneMgr->setShadowTextureCountPerLightType(Light::LT_DIRECTIONAL, split ? 3 : 1);
|
|
mSceneMgr->setShadowTextureCount(split ? 3 : 1);
|
|
|
|
mSceneMgr->setShadowTextureSelfShadow(true);
|
|
mSceneMgr->setShadowCasterRenderBackFaces(true);
|
|
mSceneMgr->setShadowTextureCasterMaterial("openmw_shadowcaster_default");
|
|
mSceneMgr->setShadowTexturePixelFormat(PF_FLOAT32_R);
|
|
mSceneMgr->setShadowDirectionalLightExtrusionDistance(1000000);
|
|
|
|
mShadowFar = Settings::Manager::getFloat(split ? "split shadow distance" : "shadow distance", "Shadows");
|
|
mSceneMgr->setShadowFarDistance(mShadowFar);
|
|
|
|
mFadeStart = Settings::Manager::getFloat("fade start", "Shadows");
|
|
|
|
ShadowCameraSetupPtr shadowCameraSetup;
|
|
if (split)
|
|
{
|
|
mPSSMSetup = new PSSMShadowCameraSetup();
|
|
|
|
// Make sure to keep this in sync with the camera's near clip distance!
|
|
mPSSMSetup->setSplitPadding(mRendering->getCamera()->getNearClipDistance());
|
|
|
|
mPSSMSetup->calculateSplitPoints(3, mRendering->getCamera()->getNearClipDistance(), mShadowFar);
|
|
|
|
const Real adjustFactors[3] = {64, 64, 64};
|
|
for (int i=0; i < 3; ++i)
|
|
{
|
|
mPSSMSetup->setOptimalAdjustFactor(i, adjustFactors[i]);
|
|
/*if (i==0)
|
|
mSceneMgr->setShadowTextureConfig(i, texsize, texsize, Ogre::PF_FLOAT32_R);
|
|
else if (i ==1)
|
|
mSceneMgr->setShadowTextureConfig(i, texsize/2, texsize/2, Ogre::PF_FLOAT32_R);
|
|
else if (i ==2)
|
|
mSceneMgr->setShadowTextureConfig(i, texsize/4, texsize/4, Ogre::PF_FLOAT32_R);*/
|
|
}
|
|
|
|
// Populate from split point 1, not 0, since split 0 isn't useful (usually 0)
|
|
const PSSMShadowCameraSetup::SplitPointList& splitPointList = getPSSMSetup()->getSplitPoints();
|
|
sh::Vector3* splitPoints = new sh::Vector3(splitPointList[1], splitPointList[2], splitPointList[3]);
|
|
|
|
sh::Factory::getInstance ().setSharedParameter ("pssmSplitPoints", sh::makeProperty<sh::Vector3>(splitPoints));
|
|
|
|
shadowCameraSetup = ShadowCameraSetupPtr(mPSSMSetup);
|
|
}
|
|
else
|
|
{
|
|
LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup();
|
|
lispsmSetup->setOptimalAdjustFactor(64);
|
|
//lispsmSetup->setCameraLightDirectionThreshold(Degree(0));
|
|
//lispsmSetup->setUseAggressiveFocusRegion(false);
|
|
shadowCameraSetup = ShadowCameraSetupPtr(lispsmSetup);
|
|
}
|
|
mSceneMgr->setShadowCameraSetup(shadowCameraSetup);
|
|
|
|
sh::Vector4* shadowFar_fadeStart = new sh::Vector4(mShadowFar, mFadeStart * mShadowFar, 0, 0);
|
|
sh::Factory::getInstance ().setSharedParameter ("shadowFar_fadeStart", sh::makeProperty<sh::Vector4>(shadowFar_fadeStart));
|
|
|
|
// Set visibility mask for the shadow render textures
|
|
int visibilityMask = RV_Actors * Settings::Manager::getBool("actor shadows", "Shadows")
|
|
+ (RV_Statics + RV_StaticsSmall) * Settings::Manager::getBool("statics shadows", "Shadows")
|
|
+ RV_Misc * Settings::Manager::getBool("misc shadows", "Shadows")
|
|
+ RV_Terrain * (Settings::Manager::getBool("terrain shadows", "Shadows"));
|
|
for (int i = 0; i < (split ? 3 : 1); ++i)
|
|
{
|
|
TexturePtr shadowTexture = mSceneMgr->getShadowTexture(i);
|
|
Viewport* vp = shadowTexture->getBuffer()->getRenderTarget()->getViewport(0);
|
|
vp->setVisibilityMask(visibilityMask);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
// --------------------------- Debug overlays to display the content of shadow maps -----------------------------------
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
/*
|
|
if (Settings::Manager::getBool("debug", "Shadows"))
|
|
{
|
|
OverlayManager& mgr = OverlayManager::getSingleton();
|
|
Overlay* overlay;
|
|
|
|
// destroy if already exists
|
|
if ((overlay = mgr.getByName("DebugOverlay")))
|
|
mgr.destroy(overlay);
|
|
|
|
overlay = mgr.create("DebugOverlay");
|
|
for (size_t i = 0; i < (split ? 3 : 1); ++i) {
|
|
TexturePtr tex = mRendering->getScene()->getShadowTexture(i);
|
|
|
|
// Set up a debug panel to display the shadow
|
|
|
|
if (MaterialManager::getSingleton().resourceExists("Ogre/DebugTexture" + StringConverter::toString(i)))
|
|
MaterialManager::getSingleton().remove("Ogre/DebugTexture" + StringConverter::toString(i));
|
|
MaterialPtr debugMat = MaterialManager::getSingleton().create(
|
|
"Ogre/DebugTexture" + StringConverter::toString(i),
|
|
ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
|
|
|
|
debugMat->getTechnique(0)->getPass(0)->setLightingEnabled(false);
|
|
TextureUnitState *t = debugMat->getTechnique(0)->getPass(0)->createTextureUnitState(tex->getName());
|
|
t->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
|
|
|
|
OverlayContainer* debugPanel;
|
|
|
|
// destroy container if exists
|
|
try
|
|
{
|
|
if ((debugPanel =
|
|
static_cast<OverlayContainer*>(
|
|
mgr.getOverlayElement("Ogre/DebugTexPanel" + StringConverter::toString(i)
|
|
))))
|
|
mgr.destroyOverlayElement(debugPanel);
|
|
}
|
|
catch (Ogre::Exception&) {}
|
|
|
|
debugPanel = (OverlayContainer*)
|
|
(OverlayManager::getSingleton().createOverlayElement("Panel", "Ogre/DebugTexPanel" + StringConverter::toString(i)));
|
|
debugPanel->_setPosition(0.8, i*0.25);
|
|
debugPanel->_setDimensions(0.2, 0.24);
|
|
debugPanel->setMaterialName(debugMat->getName());
|
|
debugPanel->show();
|
|
overlay->add2D(debugPanel);
|
|
overlay->show();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OverlayManager& mgr = OverlayManager::getSingleton();
|
|
Overlay* overlay;
|
|
|
|
if ((overlay = mgr.getByName("DebugOverlay")))
|
|
mgr.destroy(overlay);
|
|
}
|
|
*/
|
|
}
|
|
|
|
PSSMShadowCameraSetup* Shadows::getPSSMSetup()
|
|
{
|
|
return mPSSMSetup;
|
|
}
|