mirror of
				https://github.com/TES3MP/openmw-tes3mp.git
				synced 2025-11-04 02:26:46 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			187 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
	
		
			7.6 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.9)
 | 
						|
{
 | 
						|
    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;
 | 
						|
}
 |