2021-06-01 12:15:25 -07:00
# include "postprocessor.hpp"
2022-05-21 06:42:05 +00:00
# include <algorithm>
2022-02-07 11:51:59 -08:00
# include <SDL_opengl_glext.h>
2022-05-13 18:58:00 -07:00
# include <osg/Texture1D>
2021-06-01 12:15:25 -07:00
# include <osg/Texture2D>
2022-05-13 18:58:00 -07:00
# include <osg/Texture3D>
2022-04-04 22:51:23 +02:00
# include <osg/Texture2DArray>
2021-06-01 12:15:25 -07:00
# include <components/settings/settings.hpp>
2021-11-21 02:25:05 +00:00
# include <components/sceneutil/depth.hpp>
2022-04-04 22:51:23 +02:00
# include <components/sceneutil/color.hpp>
2021-10-05 12:21:12 +00:00
# include <components/sceneutil/nodecallback.hpp>
2022-05-13 18:58:00 -07:00
# include <components/sceneutil/util.hpp>
# include <components/resource/scenemanager.hpp>
# include <components/shader/shadermanager.hpp>
# include <components/misc/stringops.hpp>
# include <components/vfs/manager.hpp>
2022-04-04 22:51:23 +02:00
# include <components/stereo/multiview.hpp>
# include <components/stereo/stereomanager.hpp>
2022-05-13 18:58:00 -07:00
# include "../mwbase/world.hpp"
# include "../mwbase/environment.hpp"
# include "../mwbase/windowmanager.hpp"
# include "../mwgui/postprocessorhud.hpp"
# include "transparentpass.hpp"
# include "pingpongcull.hpp"
# include "renderingmanager.hpp"
2021-07-09 10:05:27 -07:00
# include "vismask.hpp"
2022-05-13 18:58:00 -07:00
# include "sky.hpp"
2021-06-01 12:15:25 -07:00
namespace
{
2022-05-13 18:58:00 -07:00
struct ResizedCallback : osg : : GraphicsContext : : ResizedCallback
2021-06-01 12:15:25 -07:00
{
2022-05-13 18:58:00 -07:00
ResizedCallback ( MWRender : : PostProcessor * postProcessor )
: mPostProcessor ( postProcessor )
{ }
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
void resizedImplementation ( osg : : GraphicsContext * gc , int x , int y , int width , int height ) override
{
gc - > resizedImplementation ( x , y , width , height ) ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
mPostProcessor - > setRenderTargetSize ( width , height ) ;
mPostProcessor - > resize ( ) ;
}
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
MWRender : : PostProcessor * mPostProcessor ;
} ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
class HUDCullCallback : public SceneUtil : : NodeCallback < HUDCullCallback , osg : : Camera * , osgUtil : : CullVisitor * >
2021-06-01 12:15:25 -07:00
{
public :
2022-05-13 18:58:00 -07:00
void operator ( ) ( osg : : Camera * camera , osgUtil : : CullVisitor * cv )
2021-08-04 17:49:57 -07:00
{
2022-05-13 18:58:00 -07:00
osg : : ref_ptr < osg : : StateSet > stateset = new osg : : StateSet ;
auto & sm = Stereo : : Manager : : instance ( ) ;
auto * fullViewport = camera - > getViewport ( ) ;
if ( sm . getEye ( cv ) = = Stereo : : Eye : : Left )
stateset - > setAttributeAndModes ( new osg : : Viewport ( 0 , 0 , fullViewport - > width ( ) / 2 , fullViewport - > height ( ) ) ) ;
if ( sm . getEye ( cv ) = = Stereo : : Eye : : Right )
stateset - > setAttributeAndModes ( new osg : : Viewport ( fullViewport - > width ( ) / 2 , 0 , fullViewport - > width ( ) / 2 , fullViewport - > height ( ) ) ) ;
cv - > pushStateSet ( stateset ) ;
traverse ( camera , cv ) ;
cv - > popViewport ( ) ;
2021-08-04 17:49:57 -07:00
}
2022-05-13 18:58:00 -07:00
} ;
}
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
namespace MWRender
{
PostProcessor : : PostProcessor ( RenderingManager & rendering , osgViewer : : Viewer * viewer , osg : : Group * rootNode , const VFS : : Manager * vfs )
: osg : : Group ( )
, mRootNode ( rootNode )
, mSamples ( Settings : : Manager : : getInt ( " antialiasing " , " Video " ) )
, mDirty ( false )
, mDirtyFrameId ( 0 )
, mRendering ( rendering )
, mViewer ( viewer )
, mVFS ( vfs )
, mReload ( false )
, mEnabled ( false )
, mUsePostProcessing ( false )
, mSoftParticles ( false )
, mDisableDepthPasses ( false )
, mLastFrameNumber ( 0 )
, mLastSimulationTime ( 0.f )
, mExteriorFlag ( false )
, mUnderwater ( false )
, mHDR ( false )
, mNormals ( false )
, mPrevNormals ( false )
, mNormalsSupported ( false )
2022-05-14 22:53:53 -07:00
, mPassLights ( false )
, mPrevPassLights ( false )
2022-05-13 18:58:00 -07:00
, mMainTemplate ( new osg : : Texture2D )
{
mSoftParticles = Settings : : Manager : : getBool ( " soft particles " , " Shaders " ) & & ! Stereo : : getStereo ( ) & & ! Stereo : : getMultiview ( ) ;
mUsePostProcessing = Settings : : Manager : : getBool ( " enabled " , " Post Processing " ) ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
osg : : GraphicsContext * gc = viewer - > getCamera ( ) - > getGraphicsContext ( ) ;
osg : : GLExtensions * ext = gc - > getState ( ) - > get < osg : : GLExtensions > ( ) ;
mWidth = gc - > getTraits ( ) - > width ;
mHeight = gc - > getTraits ( ) - > height ;
if ( ! ext - > glDisablei & & ext - > glDisableIndexedEXT )
ext - > glDisablei = ext - > glDisableIndexedEXT ;
2022-05-15 09:36:21 -07:00
# ifdef ANDROID
ext - > glDisablei = nullptr ;
# endif
2022-05-13 18:58:00 -07:00
if ( ext - > glDisablei )
mNormalsSupported = true ;
else
Log ( Debug : : Error ) < < " 'glDisablei' unsupported, pass normals will not be available to shaders. " ;
if ( mSoftParticles )
for ( int i = 0 ; i < 2 ; + + i )
mTextures [ i ] [ Tex_OpaqueDepth ] = new osg : : Texture2D ;
mGLSLVersion = ext - > glslLanguageVersion * 100 ;
mUBO = ext & & ext - > isUniformBufferObjectSupported & & mGLSLVersion > = 330 ;
mStateUpdater = new fx : : StateUpdater ( mUBO ) ;
if ( ! SceneUtil : : AutoDepth : : isReversed ( ) & & ! mSoftParticles & & ! mUsePostProcessing & & ! Stereo : : getStereo ( ) & & ! Stereo : : getMultiview ( ) )
return ;
enable ( mUsePostProcessing ) ;
}
PostProcessor : : ~ PostProcessor ( )
{
if ( auto * bin = osgUtil : : RenderBin : : getRenderBinPrototype ( " DepthSortedBin " ) )
bin - > setDrawCallback ( nullptr ) ;
}
void PostProcessor : : resize ( )
{
for ( auto & technique : mTechniques )
{
for ( auto & [ name , rt ] : technique - > getRenderTargetsMap ( ) )
2022-04-04 22:51:23 +02:00
{
2022-05-13 18:58:00 -07:00
const auto [ w , h ] = rt . mSize . get ( mWidth , mHeight ) ;
rt . mTarget - > setTextureSize ( w , h ) ;
2021-06-01 12:15:25 -07:00
}
}
2021-07-09 10:05:27 -07:00
2022-05-13 18:58:00 -07:00
size_t frameId = frame ( ) % 2 ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
createTexturesAndCamera ( frameId ) ;
createObjectsForFrame ( frameId ) ;
mHUDCamera - > resize ( mWidth , mHeight ) ;
mViewer - > getCamera ( ) - > resize ( mWidth , mHeight ) ;
mRendering . updateProjectionMatrix ( ) ;
mRendering . setScreenRes ( mWidth , mHeight ) ;
dirtyTechniques ( ) ;
mPingPongCanvas - > dirty ( frameId ) ;
mDirty = true ;
mDirtyFrameId = ! frameId ;
if ( Stereo : : getStereo ( ) )
Stereo : : Manager : : instance ( ) . screenResolutionChanged ( ) ;
}
2022-05-21 06:42:05 +00:00
void PostProcessor : : populateTechniqueFiles ( )
{
for ( const auto & name : mVFS - > getRecursiveDirectoryIterator ( fx : : Technique : : sSubdir ) )
{
std : : filesystem : : path path = name ;
std : : string fileExt = Misc : : StringUtils : : lowerCase ( path . extension ( ) . string ( ) ) ;
if ( ! path . parent_path ( ) . has_parent_path ( ) & & fileExt = = fx : : Technique : : sExt )
{
auto absolutePath = std : : filesystem : : path ( mVFS - > getAbsoluteFileName ( name ) ) ;
mTechniqueFileMap [ absolutePath . stem ( ) . string ( ) ] = absolutePath ;
}
}
}
2022-05-13 18:58:00 -07:00
void PostProcessor : : enable ( bool usePostProcessing )
2021-06-01 12:15:25 -07:00
{
2022-05-13 18:58:00 -07:00
mReload = true ;
mEnabled = true ;
2022-05-15 09:36:21 -07:00
bool postPass = Settings : : Manager : : getBool ( " transparent postpass " , " Post Processing " ) ;
2022-05-13 18:58:00 -07:00
mUsePostProcessing = usePostProcessing & & ! Stereo : : getStereo ( ) & & ! Stereo : : getMultiview ( ) ;
2022-05-15 09:36:21 -07:00
mDisableDepthPasses = ! mSoftParticles & & ! postPass ;
# ifdef ANDROID
mDisableDepthPasses = true ;
# endif
2022-05-13 18:58:00 -07:00
if ( ! mDisableDepthPasses & & ! Stereo : : getStereo ( ) & & ! Stereo : : getMultiview ( ) )
2021-06-01 12:15:25 -07:00
{
2022-05-15 09:36:21 -07:00
mTransparentDepthPostPass = new TransparentDepthBinCallback ( mRendering . getResourceSystem ( ) - > getSceneManager ( ) - > getShaderManager ( ) , postPass ) ;
2022-05-13 18:58:00 -07:00
osgUtil : : RenderBin : : getRenderBinPrototype ( " DepthSortedBin " ) - > setDrawCallback ( mTransparentDepthPostPass ) ;
2021-06-01 12:15:25 -07:00
}
2022-05-13 18:58:00 -07:00
if ( mUsePostProcessing & & mTechniqueFileMap . empty ( ) )
2021-06-01 12:15:25 -07:00
{
2022-05-21 06:42:05 +00:00
populateTechniqueFiles ( ) ;
2021-06-01 12:15:25 -07:00
}
2022-05-13 18:58:00 -07:00
mMainTemplate - > setFilter ( osg : : Texture : : MIN_FILTER , osg : : Texture : : LINEAR ) ;
mMainTemplate - > setFilter ( osg : : Texture : : MAG_FILTER , osg : : Texture : : LINEAR ) ;
mMainTemplate - > setWrap ( osg : : Texture : : WRAP_S , osg : : Texture : : CLAMP_TO_EDGE ) ;
mMainTemplate - > setWrap ( osg : : Texture : : WRAP_T , osg : : Texture : : CLAMP_TO_EDGE ) ;
mMainTemplate - > setInternalFormat ( GL_RGBA ) ;
mMainTemplate - > setSourceType ( GL_UNSIGNED_BYTE ) ;
mMainTemplate - > setSourceFormat ( GL_RGBA ) ;
2021-10-20 09:42:18 -07:00
2022-05-13 18:58:00 -07:00
createTexturesAndCamera ( frame ( ) % 2 ) ;
2021-11-20 18:39:20 -08:00
2022-05-13 18:58:00 -07:00
removeChild ( mHUDCamera ) ;
removeChild ( mRootNode ) ;
addChild ( mHUDCamera ) ;
addChild ( mRootNode ) ;
mViewer - > setSceneData ( this ) ;
mViewer - > getCamera ( ) - > setRenderTargetImplementation ( osg : : Camera : : FRAME_BUFFER_OBJECT ) ;
mViewer - > getCamera ( ) - > getGraphicsContext ( ) - > setResizedCallback ( new ResizedCallback ( this ) ) ;
mViewer - > getCamera ( ) - > setUserData ( this ) ;
setCullCallback ( mStateUpdater ) ;
mHUDCamera - > setCullCallback ( new HUDCullCallback ) ;
}
2021-11-20 18:39:20 -08:00
2022-05-13 18:58:00 -07:00
void PostProcessor : : disable ( )
{
if ( ! mSoftParticles )
osgUtil : : RenderBin : : getRenderBinPrototype ( " DepthSortedBin " ) - > setDrawCallback ( nullptr ) ;
2021-10-20 09:42:18 -07:00
2022-05-13 18:58:00 -07:00
if ( ! SceneUtil : : AutoDepth : : isReversed ( ) & & ! mSoftParticles & & ! Stereo : : getStereo ( ) & & ! Stereo : : getMultiview ( ) )
{
removeChild ( mHUDCamera ) ;
setCullCallback ( nullptr ) ;
2021-10-20 09:42:18 -07:00
2022-05-13 18:58:00 -07:00
mViewer - > getCamera ( ) - > setRenderTargetImplementation ( osg : : Camera : : FRAME_BUFFER ) ;
mViewer - > getCamera ( ) - > getGraphicsContext ( ) - > setResizedCallback ( nullptr ) ;
mViewer - > getCamera ( ) - > setUserData ( nullptr ) ;
2021-10-20 09:42:18 -07:00
2022-05-13 18:58:00 -07:00
mEnabled = false ;
2021-10-20 09:42:18 -07:00
}
2022-05-13 18:58:00 -07:00
mUsePostProcessing = false ;
mRendering . getSkyManager ( ) - > setSunglare ( true ) ;
}
void PostProcessor : : traverse ( osg : : NodeVisitor & nv )
{
if ( ! mEnabled )
2021-11-20 18:39:20 -08:00
{
2022-05-13 18:58:00 -07:00
osg : : Group : : traverse ( nv ) ;
return ;
2021-11-20 18:39:20 -08:00
}
2022-05-13 18:58:00 -07:00
size_t frameId = nv . getTraversalNumber ( ) % 2 ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
if ( nv . getVisitorType ( ) = = osg : : NodeVisitor : : CULL_VISITOR )
cull ( frameId , static_cast < osgUtil : : CullVisitor * > ( & nv ) ) ;
else if ( nv . getVisitorType ( ) = = osg : : NodeVisitor : : UPDATE_VISITOR )
update ( frameId ) ;
osg : : Group : : traverse ( nv ) ;
}
void PostProcessor : : cull ( size_t frameId , osgUtil : : CullVisitor * cv )
2021-06-01 12:15:25 -07:00
{
2022-05-13 18:58:00 -07:00
const auto & fbo = getFbo ( FBO_Intercept , frameId ) ;
if ( fbo )
{
osgUtil : : RenderStage * rs = cv - > getRenderStage ( ) ;
if ( rs & & rs - > getMultisampleResolveFramebufferObject ( ) )
rs - > setMultisampleResolveFramebufferObject ( fbo ) ;
}
2021-10-20 09:42:18 -07:00
2022-05-13 18:58:00 -07:00
mPingPongCanvas - > setPostProcessing ( frameId , mUsePostProcessing ) ;
mPingPongCanvas - > setNormalsTexture ( frameId , mNormals ? getTexture ( Tex_Normal , frameId ) : nullptr ) ;
mPingPongCanvas - > setMask ( frameId , mUnderwater , mExteriorFlag ) ;
mPingPongCanvas - > setHDR ( frameId , getHDR ( ) ) ;
2021-08-17 17:45:50 -07:00
2022-05-13 18:58:00 -07:00
if ( Stereo : : getStereo ( ) )
{
auto & sm = Stereo : : Manager : : instance ( ) ;
2021-07-09 10:05:27 -07:00
2022-05-13 18:58:00 -07:00
int index = sm . getEye ( cv ) = = Stereo : : Eye : : Left ? 0 : 1 ;
2021-07-09 10:05:27 -07:00
2022-05-13 18:58:00 -07:00
mPingPongCanvas - > setSceneTexture ( frameId , sm . multiviewFramebuffer ( ) - > layerColorBuffer ( index ) ) ;
mPingPongCanvas - > setDepthTexture ( frameId , sm . multiviewFramebuffer ( ) - > layerDepthBuffer ( index ) ) ;
}
else if ( Stereo : : getMultiview ( ) )
2021-07-09 10:05:27 -07:00
{
2022-05-13 18:58:00 -07:00
auto & sm = Stereo : : Manager : : instance ( ) ;
mPingPongCanvas - > setSceneTexture ( frameId , sm . multiviewFramebuffer ( ) - > multiviewColorBuffer ( ) ) ;
mPingPongCanvas - > setDepthTexture ( frameId , sm . multiviewFramebuffer ( ) - > multiviewDepthBuffer ( ) ) ;
2021-07-09 10:05:27 -07:00
}
2022-05-13 18:58:00 -07:00
else
{
mPingPongCanvas - > setSceneTexture ( frameId , getTexture ( Tex_Scene , frameId ) ) ;
if ( mDisableDepthPasses )
mPingPongCanvas - > setDepthTexture ( frameId , getTexture ( Tex_Depth , frameId ) ) ;
else
mPingPongCanvas - > setDepthTexture ( frameId , getTexture ( Tex_OpaqueDepth , frameId ) ) ;
mPingPongCanvas - > setLDRSceneTexture ( frameId , getTexture ( Tex_Scene_LDR , frameId ) ) ;
2021-07-09 10:05:27 -07:00
2022-05-13 18:58:00 -07:00
if ( mTransparentDepthPostPass )
{
mTransparentDepthPostPass - > mFbo [ frameId ] = mFbos [ frameId ] [ FBO_Primary ] ;
mTransparentDepthPostPass - > mMsaaFbo [ frameId ] = mFbos [ frameId ] [ FBO_Multisample ] ;
mTransparentDepthPostPass - > mOpaqueFbo [ frameId ] = mFbos [ frameId ] [ FBO_OpaqueDepth ] ;
}
}
size_t frame = cv - > getTraversalNumber ( ) ;
mStateUpdater - > setResolution ( osg : : Vec2f ( cv - > getViewport ( ) - > width ( ) , cv - > getViewport ( ) - > height ( ) ) ) ;
// per-frame data
if ( frame ! = mLastFrameNumber )
2021-07-09 10:05:27 -07:00
{
2022-05-13 18:58:00 -07:00
mLastFrameNumber = frame ;
auto stamp = cv - > getFrameStamp ( ) ;
mStateUpdater - > setSimulationTime ( static_cast < float > ( stamp - > getSimulationTime ( ) ) ) ;
mStateUpdater - > setDeltaSimulationTime ( static_cast < float > ( stamp - > getSimulationTime ( ) - mLastSimulationTime ) ) ;
mLastSimulationTime = stamp - > getSimulationTime ( ) ;
for ( const auto & dispatchNode : mPingPongCanvas - > getCurrentFrameData ( frame ) )
{
for ( auto & uniform : dispatchNode . mHandle - > getUniformMap ( ) )
{
if ( uniform - > getType ( ) . has_value ( ) & & ! uniform - > mSamplerType )
if ( auto * u = dispatchNode . mRootStateSet - > getUniform ( uniform - > mName ) )
uniform - > setUniform ( u ) ;
}
}
2021-07-09 10:05:27 -07:00
}
2022-05-13 18:58:00 -07:00
}
2022-05-21 06:42:05 +00:00
void PostProcessor : : updateLiveReload ( )
2022-05-13 18:58:00 -07:00
{
static const bool liveReload = Settings : : Manager : : getBool ( " live reload " , " Post Processing " ) ;
2022-05-21 06:42:05 +00:00
if ( ! liveReload )
return ;
2021-07-09 10:05:27 -07:00
2022-05-21 06:42:05 +00:00
for ( auto & technique : mTechniques )
2021-07-09 10:05:27 -07:00
{
2022-05-21 06:42:05 +00:00
if ( technique - > getStatus ( ) = = fx : : Technique : : Status : : File_Not_exists )
continue ;
2022-05-13 18:58:00 -07:00
2022-05-21 06:42:05 +00:00
const auto lastWriteTime = std : : filesystem : : last_write_time ( mTechniqueFileMap [ technique - > getName ( ) ] ) ;
const bool isDirty = technique - > setLastModificationTime ( lastWriteTime ) ;
2022-05-13 18:58:00 -07:00
2022-05-23 21:27:32 -07:00
if ( ! isDirty )
2022-05-21 06:42:05 +00:00
continue ;
2022-05-13 18:58:00 -07:00
2022-05-21 06:42:05 +00:00
if ( technique - > compile ( ) )
Log ( Debug : : Info ) < < " Reloaded technique : " < < mTechniqueFileMap [ technique - > getName ( ) ] . string ( ) ;
2022-05-13 18:58:00 -07:00
2022-05-21 06:42:05 +00:00
mReload = technique - > isValid ( ) ;
2021-07-09 10:05:27 -07:00
}
2022-05-21 06:42:05 +00:00
}
2021-07-09 10:05:27 -07:00
2022-05-21 06:42:05 +00:00
void PostProcessor : : reloadIfRequired ( )
{
if ( ! mReload )
return ;
2022-05-13 18:58:00 -07:00
2022-05-21 06:42:05 +00:00
mReload = false ;
2021-06-01 12:15:25 -07:00
2022-05-21 06:42:05 +00:00
if ( ! mTechniques . empty ( ) )
reloadMainPass ( * mTechniques [ 0 ] ) ;
2021-06-01 12:15:25 -07:00
2022-05-21 06:42:05 +00:00
reloadTechniques ( ) ;
if ( ! mUsePostProcessing )
resize ( ) ;
}
void PostProcessor : : update ( size_t frameId )
{
2022-05-22 18:53:38 -07:00
while ( ! mQueuedTemplates . empty ( ) )
{
mTemplates . push_back ( std : : move ( mQueuedTemplates . back ( ) ) ) ;
mQueuedTemplates . pop_back ( ) ;
}
2022-05-21 06:42:05 +00:00
updateLiveReload ( ) ;
reloadIfRequired ( ) ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
if ( mDirty & & mDirtyFrameId = = frameId )
2022-04-04 22:51:23 +02:00
{
2022-05-13 18:58:00 -07:00
createTexturesAndCamera ( frameId ) ;
createObjectsForFrame ( frameId ) ;
mDirty = false ;
2022-06-05 15:46:25 -07:00
mPingPongCanvas - > setCurrentFrameData ( frameId , fx : : DispatchArray ( mTemplateData ) ) ;
2022-04-04 22:51:23 +02:00
}
2021-06-01 12:15:25 -07:00
2022-05-14 22:53:53 -07:00
if ( ( mNormalsSupported & & mNormals ! = mPrevNormals ) | | ( mPassLights ! = mPrevPassLights ) )
2022-05-13 18:58:00 -07:00
{
mPrevNormals = mNormals ;
2022-05-14 22:53:53 -07:00
mPrevPassLights = mPassLights ;
2022-05-13 18:58:00 -07:00
mViewer - > stopThreading ( ) ;
auto & shaderManager = MWBase : : Environment : : get ( ) . getResourceSystem ( ) - > getSceneManager ( ) - > getShaderManager ( ) ;
auto defines = shaderManager . getGlobalDefines ( ) ;
defines [ " disableNormals " ] = mNormals ? " 0 " : " 1 " ;
shaderManager . setGlobalDefines ( defines ) ;
2022-05-14 22:53:53 -07:00
mRendering . getLightRoot ( ) - > setCollectPPLights ( mPassLights ) ;
mStateUpdater - > bindPointLights ( mPassLights ? mRendering . getLightRoot ( ) - > getPPLightsBuffer ( ) : nullptr ) ;
mStateUpdater - > reset ( ) ;
2022-05-13 18:58:00 -07:00
mViewer - > startThreading ( ) ;
createTexturesAndCamera ( frameId ) ;
createObjectsForFrame ( frameId ) ;
2022-05-14 22:53:53 -07:00
2022-05-13 18:58:00 -07:00
mDirty = true ;
mDirtyFrameId = ! frameId ;
}
2021-06-01 12:15:25 -07:00
}
2022-05-13 18:58:00 -07:00
void PostProcessor : : createObjectsForFrame ( size_t frameId )
2021-06-01 12:15:25 -07:00
{
2022-05-13 18:58:00 -07:00
if ( Stereo : : getStereo ( ) | | Stereo : : getMultiview ( ) )
return ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
auto & fbos = mFbos [ frameId ] ;
auto & textures = mTextures [ frameId ] ;
for ( auto & tex : textures )
2021-10-20 09:42:18 -07:00
{
2022-05-13 18:58:00 -07:00
if ( ! tex )
continue ;
tex - > setTextureSize ( mWidth , mHeight ) ;
tex - > dirtyTextureObject ( ) ;
2021-10-20 09:42:18 -07:00
}
2022-05-13 18:58:00 -07:00
fbos [ FBO_Primary ] = new osg : : FrameBufferObject ;
fbos [ FBO_Primary ] - > setAttachment ( osg : : Camera : : COLOR_BUFFER0 , osg : : FrameBufferAttachment ( textures [ Tex_Scene ] ) ) ;
if ( mNormals & & mNormalsSupported )
fbos [ FBO_Primary ] - > setAttachment ( osg : : Camera : : COLOR_BUFFER1 , osg : : FrameBufferAttachment ( textures [ Tex_Normal ] ) ) ;
fbos [ FBO_Primary ] - > setAttachment ( osg : : Camera : : PACKED_DEPTH_STENCIL_BUFFER , osg : : FrameBufferAttachment ( textures [ Tex_Depth ] ) ) ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
fbos [ FBO_FirstPerson ] = new osg : : FrameBufferObject ;
osg : : ref_ptr < osg : : RenderBuffer > fpDepthRb = new osg : : RenderBuffer ( mWidth , mHeight , textures [ Tex_Depth ] - > getInternalFormat ( ) , mSamples > 1 ? mSamples : 0 ) ;
fbos [ FBO_FirstPerson ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : PACKED_DEPTH_STENCIL_BUFFER , osg : : FrameBufferAttachment ( fpDepthRb ) ) ;
2021-06-01 12:15:25 -07:00
// When MSAA is enabled we must first render to a render buffer, then
// blit the result to the FBO which is either passed to the main frame
// buffer for display or used as the entry point for a post process chain.
2022-05-13 18:58:00 -07:00
if ( mSamples > 1 )
2021-06-01 12:15:25 -07:00
{
2022-05-13 18:58:00 -07:00
fbos [ FBO_Multisample ] = new osg : : FrameBufferObject ;
osg : : ref_ptr < osg : : RenderBuffer > colorRB = new osg : : RenderBuffer ( mWidth , mHeight , textures [ Tex_Scene ] - > getInternalFormat ( ) , mSamples ) ;
if ( mNormals & & mNormalsSupported )
{
osg : : ref_ptr < osg : : RenderBuffer > normalRB = new osg : : RenderBuffer ( mWidth , mHeight , textures [ Tex_Normal ] - > getInternalFormat ( ) , mSamples ) ;
fbos [ FBO_Multisample ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER1 , osg : : FrameBufferAttachment ( normalRB ) ) ;
fbos [ FBO_FirstPerson ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER1 , osg : : FrameBufferAttachment ( normalRB ) ) ;
}
osg : : ref_ptr < osg : : RenderBuffer > depthRB = new osg : : RenderBuffer ( mWidth , mHeight , textures [ Tex_Depth ] - > getInternalFormat ( ) , mSamples ) ;
fbos [ FBO_Multisample ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER0 , osg : : FrameBufferAttachment ( colorRB ) ) ;
fbos [ FBO_Multisample ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : PACKED_DEPTH_STENCIL_BUFFER , osg : : FrameBufferAttachment ( depthRB ) ) ;
fbos [ FBO_FirstPerson ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER0 , osg : : FrameBufferAttachment ( colorRB ) ) ;
fbos [ FBO_Intercept ] = new osg : : FrameBufferObject ;
fbos [ FBO_Intercept ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER0 , osg : : FrameBufferAttachment ( textures [ Tex_Scene ] ) ) ;
fbos [ FBO_Intercept ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER1 , osg : : FrameBufferAttachment ( textures [ Tex_Normal ] ) ) ;
}
else
{
fbos [ FBO_FirstPerson ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER0 , osg : : FrameBufferAttachment ( textures [ Tex_Scene ] ) ) ;
if ( mNormals & & mNormalsSupported )
fbos [ FBO_FirstPerson ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER1 , osg : : FrameBufferAttachment ( textures [ Tex_Normal ] ) ) ;
2021-06-01 12:15:25 -07:00
}
2022-05-13 18:58:00 -07:00
if ( textures [ Tex_OpaqueDepth ] )
{
fbos [ FBO_OpaqueDepth ] = new osg : : FrameBufferObject ;
fbos [ FBO_OpaqueDepth ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : PACKED_DEPTH_STENCIL_BUFFER , osg : : FrameBufferAttachment ( textures [ Tex_OpaqueDepth ] ) ) ;
}
2022-04-04 22:51:23 +02:00
2022-05-13 18:58:00 -07:00
# ifdef __APPLE__
if ( textures [ Tex_OpaqueDepth ] )
fbos [ FBO_OpaqueDepth ] - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER , osg : : FrameBufferAttachment ( new osg : : RenderBuffer ( textures [ Tex_OpaqueDepth ] - > getTextureWidth ( ) , textures [ Tex_OpaqueDepth ] - > getTextureHeight ( ) , textures [ Tex_Scene ] - > getInternalFormat ( ) ) ) ) ;
# endif
2021-06-01 12:15:25 -07:00
}
2022-05-13 18:58:00 -07:00
void PostProcessor : : dirtyTechniques ( )
2022-04-04 22:51:23 +02:00
{
2022-05-13 18:58:00 -07:00
if ( ! isEnabled ( ) )
return ;
2022-04-04 22:51:23 +02:00
2022-06-05 15:46:25 -07:00
size_t frameId = frame ( ) % 2 ;
mDirty = true ;
mDirtyFrameId = ! frameId ;
mTemplateData = { } ;
2022-05-13 18:58:00 -07:00
bool sunglare = true ;
mHDR = false ;
mNormals = false ;
2022-05-14 22:53:53 -07:00
mPassLights = false ;
2022-05-13 18:58:00 -07:00
for ( const auto & technique : mTechniques )
2022-04-04 22:51:23 +02:00
{
2022-05-13 18:58:00 -07:00
if ( ! technique - > isValid ( ) )
continue ;
2022-04-04 22:51:23 +02:00
2022-05-13 18:58:00 -07:00
if ( technique - > getGLSLVersion ( ) > mGLSLVersion )
2022-04-04 22:51:23 +02:00
{
2022-05-13 18:58:00 -07:00
Log ( Debug : : Warning ) < < " Technique " < < technique - > getName ( ) < < " requires GLSL version " < < technique - > getGLSLVersion ( ) < < " which is unsupported by your hardware. " ;
continue ;
2022-04-04 22:51:23 +02:00
}
2022-05-13 18:58:00 -07:00
fx : : DispatchNode node ;
node . mFlags = technique - > getFlags ( ) ;
if ( technique - > getHDR ( ) )
mHDR = true ;
if ( technique - > getNormals ( ) )
mNormals = true ;
2022-05-14 22:53:53 -07:00
if ( technique - > getLights ( ) )
mPassLights = true ;
2022-05-13 18:58:00 -07:00
if ( node . mFlags & fx : : Technique : : Flag_Disable_SunGlare )
sunglare = false ;
// required default samplers available to every shader pass
node . mRootStateSet - > addUniform ( new osg : : Uniform ( " omw_SamplerLastShader " , Unit_LastShader ) ) ;
node . mRootStateSet - > addUniform ( new osg : : Uniform ( " omw_SamplerLastPass " , Unit_LastPass ) ) ;
node . mRootStateSet - > addUniform ( new osg : : Uniform ( " omw_SamplerDepth " , Unit_Depth ) ) ;
if ( mNormals )
node . mRootStateSet - > addUniform ( new osg : : Uniform ( " omw_SamplerNormals " , Unit_Normals ) ) ;
if ( technique - > getHDR ( ) )
node . mRootStateSet - > addUniform ( new osg : : Uniform ( " omw_EyeAdaptation " , Unit_EyeAdaptation ) ) ;
int texUnit = Unit_NextFree ;
// user-defined samplers
for ( const osg : : Texture * texture : technique - > getTextures ( ) )
{
if ( const auto * tex1D = dynamic_cast < const osg : : Texture1D * > ( texture ) )
node . mRootStateSet - > setTextureAttribute ( texUnit , new osg : : Texture1D ( * tex1D ) ) ;
else if ( const auto * tex2D = dynamic_cast < const osg : : Texture2D * > ( texture ) )
node . mRootStateSet - > setTextureAttribute ( texUnit , new osg : : Texture2D ( * tex2D ) ) ;
else if ( const auto * tex3D = dynamic_cast < const osg : : Texture3D * > ( texture ) )
node . mRootStateSet - > setTextureAttribute ( texUnit , new osg : : Texture3D ( * tex3D ) ) ;
node . mRootStateSet - > addUniform ( new osg : : Uniform ( texture - > getName ( ) . c_str ( ) , texUnit + + ) ) ;
}
// user-defined uniforms
for ( auto & uniform : technique - > getUniformMap ( ) )
{
if ( uniform - > mSamplerType ) continue ;
if ( auto type = uniform - > getType ( ) )
2022-05-22 18:53:38 -07:00
uniform - > setUniform ( node . mRootStateSet - > getOrCreateUniform ( uniform - > mName . c_str ( ) , * type , uniform - > getNumElements ( ) ) ) ;
2022-05-13 18:58:00 -07:00
}
2022-05-18 19:45:09 -07:00
std : : unordered_map < osg : : Texture2D * , osg : : Texture2D * > renderTargetCache ;
2022-05-13 18:58:00 -07:00
for ( const auto & pass : technique - > getPasses ( ) )
{
2022-05-18 19:45:09 -07:00
int subTexUnit = texUnit ;
2022-05-13 18:58:00 -07:00
fx : : DispatchNode : : SubPass subPass ;
pass - > prepareStateSet ( subPass . mStateSet , technique - > getName ( ) ) ;
node . mHandle = technique ;
if ( ! pass - > getTarget ( ) . empty ( ) )
{
const auto & rt = technique - > getRenderTargetsMap ( ) [ pass - > getTarget ( ) ] ;
const auto [ w , h ] = rt . mSize . get ( mWidth , mHeight ) ;
subPass . mRenderTexture = new osg : : Texture2D ( * rt . mTarget ) ;
2022-05-18 19:45:09 -07:00
renderTargetCache [ rt . mTarget ] = subPass . mRenderTexture ;
2022-05-13 18:58:00 -07:00
subPass . mRenderTexture - > setTextureSize ( w , h ) ;
subPass . mRenderTexture - > setName ( std : : string ( pass - > getTarget ( ) ) ) ;
if ( rt . mMipMap )
subPass . mRenderTexture - > setNumMipmapLevels ( osg : : Image : : computeNumberOfMipmapLevels ( w , h ) ) ;
subPass . mRenderTarget = new osg : : FrameBufferObject ;
subPass . mRenderTarget - > setAttachment ( osg : : FrameBufferObject : : BufferComponent : : COLOR_BUFFER0 , osg : : FrameBufferAttachment ( subPass . mRenderTexture ) ) ;
subPass . mStateSet - > setAttributeAndModes ( new osg : : Viewport ( 0 , 0 , w , h ) ) ;
2022-05-18 19:45:09 -07:00
}
2022-05-13 18:58:00 -07:00
2022-05-18 19:45:09 -07:00
for ( const auto & whitelist : pass - > getRenderTargets ( ) )
{
auto it = technique - > getRenderTargetsMap ( ) . find ( whitelist ) ;
if ( it ! = technique - > getRenderTargetsMap ( ) . end ( ) & & renderTargetCache [ it - > second . mTarget ] )
{
2022-06-20 06:58:40 +00:00
subPass . mStateSet - > setTextureAttribute ( subTexUnit , renderTargetCache [ it - > second . mTarget ] ) ;
2022-05-18 19:45:09 -07:00
subPass . mStateSet - > addUniform ( new osg : : Uniform ( std : : string ( it - > first ) . c_str ( ) , subTexUnit + + ) ) ;
}
2022-05-13 18:58:00 -07:00
}
2022-05-18 19:45:09 -07:00
2022-05-13 18:58:00 -07:00
node . mPasses . emplace_back ( std : : move ( subPass ) ) ;
}
2022-06-05 15:46:25 -07:00
node . compile ( ) ;
2022-04-04 22:51:23 +02:00
2022-06-05 15:46:25 -07:00
mTemplateData . emplace_back ( std : : move ( node ) ) ;
}
2022-05-13 18:58:00 -07:00
2022-06-05 15:46:25 -07:00
mPingPongCanvas - > setCurrentFrameData ( frameId , fx : : DispatchArray ( mTemplateData ) ) ;
2022-05-13 18:58:00 -07:00
if ( auto hud = MWBase : : Environment : : get ( ) . getWindowManager ( ) - > getPostProcessorHud ( ) )
hud - > updateTechniques ( ) ;
mRendering . getSkyManager ( ) - > setSunglare ( sunglare ) ;
}
2022-05-31 08:45:27 +00:00
PostProcessor : : Status PostProcessor : : enableTechnique ( std : : shared_ptr < fx : : Technique > technique , std : : optional < int > location )
2022-05-13 18:58:00 -07:00
{
2022-05-22 18:53:38 -07:00
if ( ! isEnabled ( ) )
{
Log ( Debug : : Warning ) < < " PostProcessing disabled, cannot load technique ' " < < technique - > getName ( ) < < " ' " ;
2022-05-31 08:45:27 +00:00
return Status_Error ;
2022-05-22 18:53:38 -07:00
}
2022-06-20 06:58:40 +00:00
if ( ! technique | | technique - > getLocked ( ) | | ( location . has_value ( ) & & location . value ( ) < = 0 ) )
2022-05-31 08:45:27 +00:00
return Status_Error ;
2022-05-13 18:58:00 -07:00
disableTechnique ( technique , false ) ;
int pos = std : : min < int > ( location . value_or ( mTechniques . size ( ) ) , mTechniques . size ( ) ) ;
mTechniques . insert ( mTechniques . begin ( ) + pos , technique ) ;
dirtyTechniques ( ) ;
2022-05-31 08:45:27 +00:00
return Status_Toggled ;
2022-05-13 18:58:00 -07:00
}
2022-05-31 08:45:27 +00:00
PostProcessor : : Status PostProcessor : : disableTechnique ( std : : shared_ptr < fx : : Technique > technique , bool dirty )
2022-05-13 18:58:00 -07:00
{
2022-06-20 06:58:40 +00:00
if ( technique - > getLocked ( ) )
2022-05-31 08:45:27 +00:00
return Status_Error ;
2022-05-23 21:27:32 -07:00
2022-05-21 06:42:05 +00:00
auto it = std : : find ( mTechniques . begin ( ) , mTechniques . end ( ) , technique ) ;
if ( it = = std : : end ( mTechniques ) )
2022-05-31 08:45:27 +00:00
return Status_Unchanged ;
2022-04-04 22:51:23 +02:00
2022-05-21 06:42:05 +00:00
mTechniques . erase ( it ) ;
if ( dirty )
dirtyTechniques ( ) ;
2022-05-31 08:45:27 +00:00
return Status_Toggled ;
2022-05-13 18:58:00 -07:00
}
bool PostProcessor : : isTechniqueEnabled ( const std : : shared_ptr < fx : : Technique > & technique ) const
{
2022-05-21 06:42:05 +00:00
if ( auto it = std : : find ( mTechniques . begin ( ) , mTechniques . end ( ) , technique ) ; it = = mTechniques . end ( ) )
return false ;
2022-04-04 22:51:23 +02:00
2022-05-21 06:42:05 +00:00
return technique - > isValid ( ) ;
2022-05-13 18:58:00 -07:00
}
void PostProcessor : : createTexturesAndCamera ( size_t frameId )
{
auto & textures = mTextures [ frameId ] ;
for ( auto & texture : textures )
2022-04-04 22:51:23 +02:00
{
2022-05-13 18:58:00 -07:00
if ( ! texture )
texture = new osg : : Texture2D ;
texture - > setTextureSize ( mWidth , mHeight ) ;
texture - > setSourceFormat ( GL_RGBA ) ;
texture - > setSourceType ( GL_UNSIGNED_BYTE ) ;
texture - > setInternalFormat ( GL_RGBA ) ;
texture - > setFilter ( osg : : Texture2D : : MIN_FILTER , osg : : Texture : : LINEAR ) ;
texture - > setFilter ( osg : : Texture2D : : MAG_FILTER , osg : : Texture : : LINEAR ) ;
texture - > setWrap ( osg : : Texture : : WRAP_S , osg : : Texture : : CLAMP_TO_EDGE ) ;
texture - > setWrap ( osg : : Texture : : WRAP_T , osg : : Texture : : CLAMP_TO_EDGE ) ;
texture - > setResizeNonPowerOfTwoHint ( false ) ;
2022-04-04 22:51:23 +02:00
}
2022-05-13 18:58:00 -07:00
textures [ Tex_Normal ] - > setSourceFormat ( GL_RGB ) ;
textures [ Tex_Normal ] - > setInternalFormat ( GL_RGB ) ;
2022-04-04 22:51:23 +02:00
2022-05-13 18:58:00 -07:00
if ( mMainTemplate )
{
textures [ Tex_Scene ] - > setSourceFormat ( mMainTemplate - > getSourceFormat ( ) ) ;
textures [ Tex_Scene ] - > setSourceType ( mMainTemplate - > getSourceType ( ) ) ;
textures [ Tex_Scene ] - > setInternalFormat ( mMainTemplate - > getInternalFormat ( ) ) ;
textures [ Tex_Scene ] - > setFilter ( osg : : Texture2D : : MIN_FILTER , mMainTemplate - > getFilter ( osg : : Texture2D : : MIN_FILTER ) ) ;
textures [ Tex_Scene ] - > setFilter ( osg : : Texture2D : : MAG_FILTER , mMainTemplate - > getFilter ( osg : : Texture2D : : MAG_FILTER ) ) ;
textures [ Tex_Scene ] - > setWrap ( osg : : Texture : : WRAP_S , mMainTemplate - > getWrap ( osg : : Texture2D : : WRAP_S ) ) ;
textures [ Tex_Scene ] - > setWrap ( osg : : Texture : : WRAP_T , mMainTemplate - > getWrap ( osg : : Texture2D : : WRAP_T ) ) ;
}
auto setupDepth = [ ] ( osg : : Texture2D * tex ) {
tex - > setSourceFormat ( GL_DEPTH_STENCIL_EXT ) ;
tex - > setSourceType ( SceneUtil : : AutoDepth : : depthSourceType ( ) ) ;
tex - > setInternalFormat ( SceneUtil : : AutoDepth : : depthInternalFormat ( ) ) ;
} ;
setupDepth ( textures [ Tex_Depth ] ) ;
if ( mDisableDepthPasses )
{
textures [ Tex_OpaqueDepth ] = nullptr ;
}
else
2021-10-20 09:42:18 -07:00
{
2022-05-13 18:58:00 -07:00
setupDepth ( textures [ Tex_OpaqueDepth ] ) ;
textures [ Tex_OpaqueDepth ] - > setName ( " opaqueTexMap " ) ;
2021-10-20 09:42:18 -07:00
}
2022-05-13 18:58:00 -07:00
if ( mHUDCamera )
return ;
2021-06-01 12:15:25 -07:00
mHUDCamera = new osg : : Camera ;
mHUDCamera - > setReferenceFrame ( osg : : Camera : : ABSOLUTE_RF ) ;
mHUDCamera - > setRenderOrder ( osg : : Camera : : POST_RENDER ) ;
mHUDCamera - > setClearColor ( osg : : Vec4 ( 0.45 , 0.45 , 0.14 , 1.0 ) ) ;
2022-04-04 22:51:23 +02:00
mHUDCamera - > setClearMask ( 0 ) ;
2021-06-01 12:15:25 -07:00
mHUDCamera - > setProjectionMatrix ( osg : : Matrix : : ortho2D ( 0 , 1 , 0 , 1 ) ) ;
mHUDCamera - > setAllowEventFocus ( false ) ;
2022-05-13 18:58:00 -07:00
mHUDCamera - > setViewport ( 0 , 0 , mWidth , mHeight ) ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
mViewer - > getCamera ( ) - > removeCullCallback ( mPingPongCull ) ;
mPingPongCull = new PingPongCull ;
mViewer - > getCamera ( ) - > addCullCallback ( mPingPongCull ) ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
mPingPongCanvas = new PingPongCanvas ( mRendering . getResourceSystem ( ) - > getSceneManager ( ) - > getShaderManager ( ) ) ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
mHUDCamera - > addChild ( mPingPongCanvas ) ;
mHUDCamera - > setNodeMask ( Mask_RenderToTexture ) ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
mHUDCamera - > getOrCreateStateSet ( ) - > setMode ( GL_LIGHTING , osg : : StateAttribute : : OFF ) ;
mHUDCamera - > getOrCreateStateSet ( ) - > setMode ( GL_DEPTH_TEST , osg : : StateAttribute : : OFF ) ;
}
2021-06-01 12:15:25 -07:00
2022-05-22 18:53:38 -07:00
std : : shared_ptr < fx : : Technique > PostProcessor : : loadTechnique ( const std : : string & name , bool loadNextFrame )
2022-05-13 18:58:00 -07:00
{
if ( ! isEnabled ( ) )
2022-05-22 18:53:38 -07:00
{
Log ( Debug : : Warning ) < < " PostProcessing disabled, cannot load technique ' " < < name < < " ' " ;
2022-05-13 18:58:00 -07:00
return nullptr ;
2022-05-22 18:53:38 -07:00
}
2021-06-01 12:15:25 -07:00
2022-05-22 18:53:38 -07:00
for ( const auto & technique : mTemplates )
if ( Misc : : StringUtils : : ciEqual ( technique - > getName ( ) , name ) )
return technique ;
for ( const auto & technique : mQueuedTemplates )
if ( Misc : : StringUtils : : ciEqual ( technique - > getName ( ) , name ) )
return technique ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
auto technique = std : : make_shared < fx : : Technique > ( * mVFS , * mRendering . getResourceSystem ( ) - > getImageManager ( ) , name , mWidth , mHeight , mUBO , mNormalsSupported ) ;
2022-04-04 22:51:23 +02:00
2022-05-13 18:58:00 -07:00
technique - > compile ( ) ;
2022-04-04 22:51:23 +02:00
2022-05-13 18:58:00 -07:00
if ( technique - > getStatus ( ) ! = fx : : Technique : : Status : : File_Not_exists )
2022-05-21 06:42:05 +00:00
technique - > setLastModificationTime ( std : : filesystem : : last_write_time ( mTechniqueFileMap [ technique - > getName ( ) ] ) ) ;
2022-04-04 22:51:23 +02:00
2022-05-31 08:45:27 +00:00
if ( loadNextFrame )
2022-05-22 18:53:38 -07:00
{
mQueuedTemplates . push_back ( technique ) ;
2022-05-13 18:58:00 -07:00
return technique ;
2022-05-22 18:53:38 -07:00
}
2022-05-13 18:58:00 -07:00
reloadMainPass ( * technique ) ;
mTemplates . push_back ( std : : move ( technique ) ) ;
return mTemplates . back ( ) ;
}
void PostProcessor : : reloadTechniques ( )
{
if ( ! isEnabled ( ) )
return ;
mTechniques . clear ( ) ;
std : : vector < std : : string > techniqueStrings ;
Misc : : StringUtils : : split ( Settings : : Manager : : getString ( " chain " , " Post Processing " ) , techniqueStrings , " , " ) ;
2022-06-20 06:58:40 +00:00
const std : : string & mainIdentifier = " main " ;
auto main = loadTechnique ( mainIdentifier ) ;
if ( main )
main - > setLocked ( true ) ;
mTechniques . push_back ( std : : move ( main ) ) ;
2022-05-13 18:58:00 -07:00
for ( auto & techniqueName : techniqueStrings )
{
Misc : : StringUtils : : trim ( techniqueName ) ;
2022-06-20 06:58:40 +00:00
if ( techniqueName . empty ( ) | | Misc : : StringUtils : : ciEqual ( techniqueName , mainIdentifier ) )
2022-05-13 18:58:00 -07:00
continue ;
2022-04-04 22:51:23 +02:00
2022-05-13 18:58:00 -07:00
mTechniques . push_back ( loadTechnique ( techniqueName ) ) ;
}
dirtyTechniques ( ) ;
}
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
void PostProcessor : : reloadMainPass ( fx : : Technique & technique )
{
if ( ! technique . getMainTemplate ( ) )
return ;
2021-06-01 12:15:25 -07:00
2022-05-13 18:58:00 -07:00
mMainTemplate = technique . getMainTemplate ( ) ;
resize ( ) ;
2021-06-01 12:15:25 -07:00
}
2022-05-13 18:58:00 -07:00
void PostProcessor : : toggleMode ( )
{
for ( auto & technique : mTemplates )
technique - > compile ( ) ;
dirtyTechniques ( ) ;
}
2022-05-31 08:45:27 +00:00
void PostProcessor : : disableDynamicShaders ( )
{
for ( auto & technique : mTechniques )
if ( technique - > getDynamic ( ) )
disableTechnique ( technique ) ;
}
2021-06-01 12:15:25 -07:00
}
2022-04-04 22:51:23 +02:00