diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index fdc7958f5..ff83997eb 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -112,6 +112,14 @@ ImplementEnumType( PFXTargetClear, { PFXTargetClear_OnDraw, "PFXTargetClear_OnDraw", "Clear before every draw.\n" }, EndImplementEnumType; +ImplementEnumType( PFXTargetViewport, + "Specifies how the viewport should be set up for a PostEffect's target.\n" + "@note Applies to both the diffuse target and the depth target (if defined).\n" + "@ingroup Rendering\n\n") + { PFXTargetViewport_TargetSize, "PFXTargetViewport_TargetSize", "Set viewport to match target size (default).\n" }, + { PFXTargetViewport_GFXViewport, "PFXTargetViewport_GFXViewport", "Use the current GFX viewport (scaled to match target size).\n" }, +EndImplementEnumType; + GFXImplementVertexFormat( PFXVertex ) { @@ -235,6 +243,7 @@ PostEffect::PostEffect() mStateBlockData( NULL ), mAllowReflectPass( false ), mTargetClear( PFXTargetClear_None ), + mTargetViewport( PFXTargetViewport_TargetSize ), mTargetScale( Point2F::One ), mTargetSize( Point2I::Zero ), mTargetFormat( GFXFormatR8G8B8A8 ), @@ -312,6 +321,9 @@ void PostEffect::initPersistFields() addField( "targetClear", TYPEID< PFXTargetClear >(), Offset( mTargetClear, PostEffect ), "Describes when the target texture should be cleared." ); + addField( "targetViewport", TYPEID< PFXTargetViewport >(), Offset( mTargetViewport, PostEffect ), + "Specifies how the viewport should be set up for a target texture." ); + addField( "texture", TypeImageFilename, Offset( mTexFilename, PostEffect ), NumTextures, "Input textures to this effect ( samplers ).\n" "@see PFXTextureIdentifiers" ); @@ -927,7 +939,23 @@ void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarg if ( mTargetClear == PFXTargetClear_OnCreate ) *outClearTarget = true; - mNamedTarget.setViewport( RectI( 0, 0, targetSize.x, targetSize.y ) ); + if(mTargetViewport == PFXTargetViewport_GFXViewport) + { + // We may need to scale the GFX viewport to fit within + // our target texture size + GFXTarget *oldTarget = GFX->getActiveRenderTarget(); + const Point2I &oldTargetSize = oldTarget->getSize(); + Point2F scale(targetSize.x / F32(oldTargetSize.x), targetSize.y / F32(oldTargetSize.y)); + + const RectI viewport = GFX->getViewport(); + + mNamedTarget.setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) ); + } + else + { + // PFXTargetViewport_TargetSize + mNamedTarget.setViewport( RectI( 0, 0, targetSize.x, targetSize.y ) ); + } } } else @@ -973,7 +1001,23 @@ void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarg if ( mTargetClear == PFXTargetClear_OnCreate ) *outClearTarget = true; - mNamedTargetDepthStencil.setViewport( RectI( 0, 0, targetSize.x, targetSize.y ) ); + if(mTargetViewport == PFXTargetViewport_GFXViewport) + { + // We may need to scale the GFX viewport to fit within + // our target texture size + GFXTarget *oldTarget = GFX->getActiveRenderTarget(); + const Point2I &oldTargetSize = oldTarget->getSize(); + Point2F scale(targetSize.x / F32(oldTargetSize.x), targetSize.y / F32(oldTargetSize.y)); + + const RectI viewport = GFX->getViewport(); + + mNamedTargetDepthStencil.setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) ); + } + else + { + // PFXTargetViewport_TargetSize + mNamedTargetDepthStencil.setViewport( RectI( 0, 0, targetSize.x, targetSize.y ) ); + } } } else @@ -1049,6 +1093,8 @@ void PostEffect::process( const SceneRenderState *state, bool clearTarget = false; _setupTarget( state, &clearTarget ); + RectI oldViewport = GFX->getViewport(); + if ( mTargetTex || mTargetDepthStencil ) { @@ -1064,6 +1110,8 @@ void PostEffect::process( const SceneRenderState *state, GFX->getActiveRenderTarget()->preserve(); #endif + GFXTarget *oldTarget = GFX->getActiveRenderTarget(); + GFX->pushActiveRenderTarget(); mTarget->attachTexture( GFXTextureTarget::Color0, mTargetTex ); @@ -1074,6 +1122,20 @@ void PostEffect::process( const SceneRenderState *state, mTarget->attachTexture( GFXTextureTarget::DepthStencil, mTargetDepthStencil ); GFX->setActiveRenderTarget( mTarget ); + + // The setActiveRenderTarget() called above will change the viewport to cover the + // entire target area. Restore the viewport as necessary. + if(mNamedTarget.isRegistered()) + { + GFX->setViewport(mNamedTarget.getViewport()); + } + else if(mTargetViewport == PFXTargetViewport_GFXViewport) + { + const Point2I &oldTargetSize = oldTarget->getSize(); + const Point2I &targetSize = mTarget->getSize(); + Point2F scale(targetSize.x / F32(oldTargetSize.x), targetSize.y / F32(oldTargetSize.y)); + GFX->setViewport( RectI( oldViewport.point.x*scale.x, oldViewport.point.y*scale.y, oldViewport.extent.x*scale.x, oldViewport.extent.y*scale.y ) ); + } } if ( clearTarget ) diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index 71ee725e8..8208a8e88 100644 --- a/Engine/source/postFx/postEffect.h +++ b/Engine/source/postFx/postEffect.h @@ -170,6 +170,7 @@ protected: PFXRenderTime mRenderTime; PFXTargetClear mTargetClear; + PFXTargetViewport mTargetViewport; String mRenderBin; diff --git a/Engine/source/postFx/postEffectCommon.h b/Engine/source/postFx/postEffectCommon.h index dcbbdda27..fecef5a52 100644 --- a/Engine/source/postFx/postEffectCommon.h +++ b/Engine/source/postFx/postEffectCommon.h @@ -67,6 +67,20 @@ enum PFXTargetClear DefineEnumType( PFXTargetClear ); + +/// PFXTargetViewport specifies how the viewport should be +/// set up for a PostEffect's target. +enum PFXTargetViewport +{ + /// The default viewport set up to match the target size + PFXTargetViewport_TargetSize, + + /// Use the current GFX viewport + PFXTargetViewport_GFXViewport, +}; + +DefineEnumType( PFXTargetViewport ); + /// struct PFXFrameState { diff --git a/Templates/Empty/game/core/scripts/client/postFx/ssao.cs b/Templates/Empty/game/core/scripts/client/postFx/ssao.cs index 69977f352..8b54ce870 100644 --- a/Templates/Empty/game/core/scripts/client/postFx/ssao.cs +++ b/Templates/Empty/game/core/scripts/client/postFx/ssao.cs @@ -190,6 +190,7 @@ singleton PostEffect( SSAOPostFx ) target = "$outTex"; targetScale = "0.5 0.5"; + targetViewport = "PFXTargetViewport_GFXViewport"; singleton PostEffect() { diff --git a/Templates/Full/game/core/scripts/client/postFx/ssao.cs b/Templates/Full/game/core/scripts/client/postFx/ssao.cs index 69977f352..8b54ce870 100644 --- a/Templates/Full/game/core/scripts/client/postFx/ssao.cs +++ b/Templates/Full/game/core/scripts/client/postFx/ssao.cs @@ -190,6 +190,7 @@ singleton PostEffect( SSAOPostFx ) target = "$outTex"; targetScale = "0.5 0.5"; + targetViewport = "PFXTargetViewport_GFXViewport"; singleton PostEffect() {