Commit 15673810 authored by DavidWyand-GG's avatar DavidWyand-GG

Expand PostFX Viewport Options

- Added an option for a postFX to get its viewport from a named texture
in slot 0, if there is one.  This allows the postFX to operate when the
named input texture's viewport is different than the current viewport.
- Modified the SSAO postFX to use the new
PFXTargetViewport_NamedInTexture0 option to more closely link SSAO with
the prepass buffer.
- Modifed the GFX method setActiveRenderTarget() with a new parameter
that indicates if the current viewport should be modified with the new
rendering target.  This defaults to true to maintain its previous
behaviour.  The postFX rendering pipeline sets this to false as it now
handles its own viewport setup, and removes an unnecessary
GFX->setViewport() call.
parent 88f2a4d9
......@@ -849,7 +849,7 @@ void GFXDevice::popActiveRenderTarget()
mRTStack.pop_back();
}
void GFXDevice::setActiveRenderTarget( GFXTarget *target )
void GFXDevice::setActiveRenderTarget( GFXTarget *target, bool updateViewport )
{
AssertFatal( target,
"GFXDevice::setActiveRenderTarget - must specify a render target!" );
......@@ -878,7 +878,10 @@ void GFXDevice::setActiveRenderTarget( GFXTarget *target )
// We should consider removing this and making it the
// responsibility of the caller to set a proper viewport
// when the target is changed.
setViewport( RectI( Point2I::Zero, mCurrentRT->getSize() ) );
if ( updateViewport )
{
setViewport( RectI( Point2I::Zero, mCurrentRT->getSize() ) );
}
}
/// Helper class for GFXDevice::describeResources.
......
......@@ -695,7 +695,7 @@ public:
void popActiveRenderTarget();
/// Assign a new active render target.
void setActiveRenderTarget( GFXTarget *target );
void setActiveRenderTarget( GFXTarget *target, bool updateViewport=true );
/// Returns the current active render target.
inline GFXTarget* getActiveRenderTarget() { return mCurrentRT; }
......
......@@ -118,6 +118,7 @@ ImplementEnumType( PFXTargetViewport,
"@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" },
{ PFXTargetViewport_NamedInTexture0, "PFXTargetViewport_NamedInTexture0", "Use the input texture 0 if it is named (scaled to match target size), otherwise revert to PFXTargetViewport_TargetSize if there is none.\n" },
EndImplementEnumType;
......@@ -947,7 +948,17 @@ void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarg
const Point2I &oldTargetSize = oldTarget->getSize();
Point2F scale(targetSize.x / F32(oldTargetSize.x), targetSize.y / F32(oldTargetSize.y));
const RectI viewport = GFX->getViewport();
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 if(mTargetViewport == PFXTargetViewport_NamedInTexture0 && mActiveNamedTarget[0] && mActiveNamedTarget[0]->getTexture())
{
// Scale the named input texture's viewport to match our target
const Point3I &namedTargetSize = mActiveNamedTarget[0]->getTexture()->getSize();
Point2F scale(targetSize.x / F32(namedTargetSize.x), targetSize.y / F32(namedTargetSize.y));
const RectI &viewport = mActiveNamedTarget[0]->getViewport();
mNamedTarget.setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) );
}
......@@ -1009,7 +1020,17 @@ void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarg
const Point2I &oldTargetSize = oldTarget->getSize();
Point2F scale(targetSize.x / F32(oldTargetSize.x), targetSize.y / F32(oldTargetSize.y));
const RectI viewport = GFX->getViewport();
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 if(mTargetViewport == PFXTargetViewport_NamedInTexture0 && mActiveNamedTarget[0] && mActiveNamedTarget[0]->getTexture())
{
// Scale the named input texture's viewport to match our target
const Point3I &namedTargetSize = mActiveNamedTarget[0]->getTexture()->getSize();
Point2F scale(targetSize.x / F32(namedTargetSize.x), targetSize.y / F32(namedTargetSize.y));
const RectI &viewport = mActiveNamedTarget[0]->getViewport();
mNamedTargetDepthStencil.setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) );
}
......@@ -1093,8 +1114,6 @@ void PostEffect::process( const SceneRenderState *state,
bool clearTarget = false;
_setupTarget( state, &clearTarget );
RectI oldViewport = GFX->getViewport();
if ( mTargetTex || mTargetDepthStencil )
{
......@@ -1110,6 +1129,7 @@ void PostEffect::process( const SceneRenderState *state,
GFX->getActiveRenderTarget()->preserve();
#endif
const RectI &oldViewport = GFX->getViewport();
GFXTarget *oldTarget = GFX->getActiveRenderTarget();
GFX->pushActiveRenderTarget();
......@@ -1121,21 +1141,38 @@ void PostEffect::process( const SceneRenderState *state,
else
mTarget->attachTexture( GFXTextureTarget::DepthStencil, mTargetDepthStencil );
GFX->setActiveRenderTarget( mTarget );
// Set the render target but not its viewport. We'll do that below.
GFX->setActiveRenderTarget( mTarget, false );
// The setActiveRenderTarget() called above will change the viewport to cover the
// entire target area. Restore the viewport as necessary.
if(mNamedTarget.isRegistered())
{
// Always use the name target's viewport, if available. It was set up in _setupTarget().
GFX->setViewport(mNamedTarget.getViewport());
}
else if(mTargetViewport == PFXTargetViewport_GFXViewport)
{
// Go with the current viewport as scaled against our render target.
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 ) );
}
else if(mTargetViewport == PFXTargetViewport_NamedInTexture0 && mActiveNamedTarget[0] && mActiveNamedTarget[0]->getTexture())
{
// Go with the first input texture, if it is named. Scale the named input texture's viewport to match our target
const Point3I &namedTargetSize = mActiveNamedTarget[0]->getTexture()->getSize();
const Point2I &targetSize = mTarget->getSize();
Point2F scale(targetSize.x / F32(namedTargetSize.x), targetSize.y / F32(namedTargetSize.y));
const RectI &viewport = mActiveNamedTarget[0]->getViewport();
GFX->setViewport( RectI( viewport.point.x*scale.x, viewport.point.y*scale.y, viewport.extent.x*scale.x, viewport.extent.y*scale.y ) );
}
else
{
// Default to using the whole target as the viewport
GFX->setViewport( RectI( Point2I::Zero, mTarget->getSize() ) );
}
}
if ( clearTarget )
......
......@@ -77,6 +77,10 @@ enum PFXTargetViewport
/// Use the current GFX viewport
PFXTargetViewport_GFXViewport,
/// Use the input texture 0 if it is named, otherwise
/// revert to PFXTargetViewport_TargetSize if there is none
PFXTargetViewport_NamedInTexture0,
};
DefineEnumType( PFXTargetViewport );
......
......@@ -190,7 +190,7 @@ singleton PostEffect( SSAOPostFx )
target = "$outTex";
targetScale = "0.5 0.5";
targetViewport = "PFXTargetViewport_GFXViewport";
targetViewport = "PFXTargetViewport_NamedInTexture0";
singleton PostEffect()
{
......
......@@ -190,7 +190,7 @@ singleton PostEffect( SSAOPostFx )
target = "$outTex";
targetScale = "0.5 0.5";
targetViewport = "PFXTargetViewport_GFXViewport";
targetViewport = "PFXTargetViewport_NamedInTexture0";
singleton PostEffect()
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment