mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-11-04 13:26:54 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			176 lines
		
	
	
	
		
			6.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			176 lines
		
	
	
	
		
			6.3 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 <OgreOverlayContainer.h>
 | 
						|
#include <OgreOverlayManager.h>
 | 
						|
 | 
						|
#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");
 | 
						|
 | 
						|
    // Split shadow maps are currently disabled because the terrain cannot cope with them
 | 
						|
    // (Too many texture units) Solution would be a multi-pass terrain material
 | 
						|
    bool split = Settings::Manager::getBool("split", "Shadows");
 | 
						|
    //const bool split = 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("depth_shadow_caster");
 | 
						|
    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);*/
 | 
						|
        }
 | 
						|
 | 
						|
        shadowCameraSetup = ShadowCameraSetupPtr(mPSSMSetup);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        LiSPSMShadowCameraSetup* lispsmSetup = new LiSPSMShadowCameraSetup();
 | 
						|
        lispsmSetup->setOptimalAdjustFactor(2);
 | 
						|
        //lispsmSetup->setCameraLightDirectionThreshold(Degree(0));
 | 
						|
        //lispsmSetup->setUseAggressiveFocusRegion(false);
 | 
						|
        shadowCameraSetup = ShadowCameraSetupPtr(lispsmSetup);
 | 
						|
    }
 | 
						|
    mSceneMgr->setShadowCameraSetup(shadowCameraSetup);
 | 
						|
 | 
						|
    // 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");
 | 
						|
 | 
						|
    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 -----------------------------------
 | 
						|
    // --------------------------------------------------------------------------------------------------------------------
 | 
						|
    /*
 | 
						|
	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();
 | 
						|
	}
 | 
						|
    */
 | 
						|
}
 | 
						|
 | 
						|
PSSMShadowCameraSetup* Shadows::getPSSMSetup()
 | 
						|
{
 | 
						|
    return mPSSMSetup;
 | 
						|
}
 | 
						|
 | 
						|
float Shadows::getShadowFar() const
 | 
						|
{
 | 
						|
    return mShadowFar;
 | 
						|
}
 | 
						|
 | 
						|
float Shadows::getFadeStart() const
 | 
						|
{
 | 
						|
    return mFadeStart;
 | 
						|
}
 |