mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-10-31 15:56:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			198 lines
		
	
	
	
		
			7.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
	
		
			7.7 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) :
 | |
|     mShadowFar(1000), mFadeStart(0.9)
 | |
| {
 | |
|     mRendering = rend;
 | |
|     mSceneMgr = mRendering->getScene();
 | |
|     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 = split ? Settings::Manager::getInt("split shadow distance", "Shadows") : Settings::Manager::getInt("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;
 | |
| }
 | |
| 
 | |
| float Shadows::getShadowFar() const
 | |
| {
 | |
|     return mShadowFar;
 | |
| }
 | |
| 
 | |
| float Shadows::getFadeStart() const
 | |
| {
 | |
|     return mFadeStart;
 | |
| }
 |