From 60e659aedcea9ffbacda568d31fb9893549ffb94 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Sun, 19 Apr 2026 15:47:48 +0100 Subject: [PATCH] adds multiple targets to the posteffect class These changes allows for multiple color targets from a post effect pass. This is not 100% complete yet as the api still expects 1 target out from a posteffect and will not pass those on to other stages in a posteffect chain but will be adding that soon. This is a working state and everything renders correctly here. --- Engine/source/postFx/postEffect.cpp | 479 ++++++++++++---------- Engine/source/postFx/postEffect.h | 512 ++++++++++-------------- Engine/source/postFx/postEffectCommon.h | 5 +- Engine/source/postFx/postEffectVis.cpp | 6 +- 4 files changed, 494 insertions(+), 508 deletions(-) diff --git a/Engine/source/postFx/postEffect.cpp b/Engine/source/postFx/postEffect.cpp index ab4363c37..e17509b02 100644 --- a/Engine/source/postFx/postEffect.cpp +++ b/Engine/source/postFx/postEffect.cpp @@ -137,9 +137,6 @@ GFX_ImplementTextureProfile( PostFxTargetProfile, GFXTextureProfile::Pooled, GFXTextureProfile::NONE ); -IMPLEMENT_CONOBJECT(PostEffect); - - GFX_ImplementTextureProfile( PostFxTextureProfile, GFXTextureProfile::DiffuseMap, GFXTextureProfile::Static | GFXTextureProfile::PreserveSize, @@ -162,6 +159,12 @@ GFX_ImplementTextureProfile( VRDepthProfile, GFXTextureProfile::ZTarget, GFXTextureProfile::NONE ); +IMPLEMENT_CONOBJECT(PostEffect); + +//--------------------------------------------------------------------- +// EffectConst +//--------------------------------------------------------------------- + void PostEffect::EffectConst::set( const String &newVal ) { if ( mStringVal == newVal ) @@ -445,69 +448,77 @@ void PostEffect::EffectConst::setToBuffer( GFXShaderConstBufferRef buff ) } } +//--------------------------------------------------------------------- +// EffectConst END +//--------------------------------------------------------------------- //------------------------------------------------------------------------- // PostEffect //------------------------------------------------------------------------- PostEffect::PostEffect() - : mRenderTime( PFXAfterDiffuse ), - mRenderPriority( 1.0 ), - mEnabled( false ), - mStateBlockData( NULL ), - mUpdateShader( true ), - mSkip( false ), - mPreProcessed(false), - mAllowReflectPass( false ), - mTargetClear( PFXTargetClear_None ), - mTargetScale( Point2F::One ), - mTargetViewport( PFXTargetViewport_TargetSize ), - mTargetSize( Point2I::Zero ), - mTargetFormat( GFXFormatR8G8B8A8 ), - mTargetClearColor( LinearColorF::BLACK ), - mOneFrameOnly( false ), - mOnThisFrame( true ), - mRTSizeSC( NULL ), - mIsValid( false ), - mShaderReloadKey( 0 ), - mOneOverRTSizeSC( NULL ), - mViewportOffsetSC( NULL ), - mTargetViewportSC( NULL ), - mFogDataSC( NULL ), - mFogColorSC( NULL ), - mEyePosSC( NULL ), - mMatWorldToScreenSC( NULL ), - mMatScreenToWorldSC( NULL ), - mMatPrevScreenToWorldSC( NULL ), - mNearFarSC( NULL ), - mInvNearFarSC( NULL ), - mWorldToScreenScaleSC( NULL ), - mProjectionOffsetSC( NULL ), - mWaterColorSC( NULL ), - mWaterFogDataSC( NULL ), - mAmbientColorSC( NULL ), - mWaterFogPlaneSC( NULL ), - mWaterDepthGradMaxSC( NULL ), - mScreenSunPosSC( NULL ), - mLightDirectionSC( NULL ), - mCameraForwardSC( NULL ), - mAccumTimeSC( NULL ), - mDampnessSC(NULL), - mDeltaTimeSC( NULL ), - mInvCameraMatSC( NULL ), - mMatCameraToWorldSC( NULL), - mInvCameraTransSC(NULL), - mMatCameraToScreenSC(NULL), - mMatScreenToCameraSC(NULL), - mIsCapturingSC(NULL), - mMipCap(1) + : mRenderTime(PFXAfterDiffuse), + mRenderPriority(1.0), + mEnabled(false), + mStateBlockData(NULL), + mUpdateShader(true), + mSkip(false), + mPreProcessed(false), + mAllowReflectPass(false), + mTargetScale(Point2F::One), + mTargetSize(Point2I::Zero), + mTargetViewport(PFXTargetViewport_TargetSize), + mMipCap(1), + mOneFrameOnly(false), + mOnThisFrame(true), + mRTSizeSC(NULL), + mIsValid(false), + mShaderReloadKey(0), + mOneOverRTSizeSC(NULL), + mViewportOffsetSC(NULL), + mTargetViewportSC(NULL), + mFogDataSC(NULL), + mFogColorSC(NULL), + mEyePosSC(NULL), + mMatWorldToScreenSC(NULL), + mMatScreenToWorldSC(NULL), + mMatPrevScreenToWorldSC(NULL), + mNearFarSC(NULL), + mInvNearFarSC(NULL), + mWorldToScreenScaleSC(NULL), + mProjectionOffsetSC(NULL), + mWaterColorSC(NULL), + mWaterFogDataSC(NULL), + mAmbientColorSC(NULL), + mWaterFogPlaneSC(NULL), + mWaterDepthGradMaxSC(NULL), + mScreenSunPosSC(NULL), + mLightDirectionSC(NULL), + mCameraForwardSC(NULL), + mAccumTimeSC(NULL), + mDampnessSC(NULL), + mDeltaTimeSC(NULL), + mInvCameraMatSC(NULL), + mMatCameraToWorldSC(NULL), + mInvCameraTransSC(NULL), + mMatCameraToScreenSC(NULL), + mMatScreenToCameraSC(NULL), + mIsCapturingSC(NULL) { - dMemset( mTexSRGB, 0, sizeof(bool) * NumTextures); - dMemset( mActiveTextures, 0, sizeof( GFXTextureObject* ) * NumTextures ); - dMemset( mActiveNamedTarget, 0, sizeof( NamedTexTarget* ) * NumTextures ); - dMemset( mActiveTextureViewport, 0, sizeof( RectI ) * NumTextures ); - dMemset( mTexSizeSC, 0, sizeof( GFXShaderConstHandle* ) * NumTextures ); - dMemset( mRenderTargetParamsSC, 0, sizeof( GFXShaderConstHandle* ) * NumTextures ); + // MRT arrays — slot 0 gets primary defaults, 1-3 are inactive. + for (U32 c = 0; c < NumMRTTargets; c++) + { + mTargetFormat[c] = GFXFormatR8G8B8A8; + mTargetClearColor[c] = LinearColorF::BLACK; + mTargetClear[c] = PFXTargetClear_None; + } + + dMemset(mTexSRGB, 0, sizeof(bool) * NumTextures); + dMemset(mActiveTextures, 0, sizeof(GFXTextureObject*) * NumTextures); + dMemset(mActiveNamedTarget, 0, sizeof(NamedTexTarget*) * NumTextures); + dMemset(mActiveTextureViewport, 0, sizeof(RectI) * NumTextures); + dMemset(mTexSizeSC, 0, sizeof(GFXShaderConstHandle*) * NumTextures); + dMemset(mRenderTargetParamsSC, 0, sizeof(GFXShaderConstHandle*) * NumTextures); dMemset(mMipCountSC, 0, sizeof(GFXShaderConstHandle*) * NumTextures); } @@ -527,9 +538,18 @@ void PostEffect::initPersistFields() addField( "stateBlock", TYPEID(), Offset( mStateBlockData, PostEffect ), "Name of a GFXStateBlockData for this effect." ); - addField( "target", TypeRealString, Offset( mTargetName, PostEffect ), + addField( "target", TypeRealString, Offset( mTargetName, PostEffect ), NumMRTTargets, "String identifier of this effect's target texture.\n" "@see PFXTextureIdentifiers" ); + + addField("targetFormat", TypeGFXFormat, Offset(mTargetFormat, PostEffect), NumMRTTargets, + "Format of the target texture, not applicable if writing to the backbuffer."); + + addField("targetClearColor", TypeColorF, Offset(mTargetClearColor, PostEffect), NumMRTTargets, + "Color to which the target texture is cleared before rendering."); + + addField("targetClear", TYPEID< PFXTargetClear >(), Offset(mTargetClear, PostEffect), NumMRTTargets, + "Describes when the target texture should be cleared."); addField( "targetDepthStencil", TypeRealString, Offset( mTargetDepthStencilName, PostEffect ), "Optional string identifier for this effect's target depth/stencil texture.\n" @@ -543,15 +563,6 @@ void PostEffect::initPersistFields() addField( "targetSize", TypePoint2I, Offset( mTargetSize, PostEffect ), "If non-zero this is used as the absolute target size." ); - - addField( "targetFormat", TypeGFXFormat, Offset( mTargetFormat, PostEffect ), - "Format of the target texture, not applicable if writing to the backbuffer." ); - - addField( "targetClearColor", TypeColorF, Offset( mTargetClearColor, PostEffect ), - "Color to which the target texture is cleared before rendering." ); - - 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." ); @@ -624,15 +635,21 @@ bool PostEffect::onAdd() } // Is the target a named target? - if ( mTargetName.isNotEmpty() && mTargetName[0] == '#' ) + bool anyNamed = false; + for (U32 c = 0; c < NumMRTTargets; c++) { - mNamedTarget.registerWithName(mTargetName.substr(1)); - mNamedTarget.getTextureDelegate().bind( this, &PostEffect::_getTargetTexture ); + if (mTargetName[c].isNotEmpty() && mTargetName[c][0] == '#') + { + mNamedTarget[c].registerWithName(mTargetName[c].substr(1)); + mNamedTarget[c].getTextureDelegate().bind(this, &PostEffect::_getTargetTexture); + anyNamed = true; + } } + if ( mTargetDepthStencilName.isNotEmpty() && mTargetDepthStencilName[0] == '#' ) mNamedTargetDepthStencil.registerWithName( mTargetDepthStencilName.substr( 1 ) ); - if (mNamedTarget.isRegistered() || mNamedTargetDepthStencil.isRegistered()) + if (anyNamed || mNamedTargetDepthStencil.isRegistered()) GFXTextureManager::addEventDelegate( this, &PostEffect::_onTextureEvent ); // Call onAdd in script @@ -661,15 +678,20 @@ void PostEffect::onRemove() mShader = NULL; _cleanTargets(); - if ( mNamedTarget.isRegistered() || mNamedTargetDepthStencil.isRegistered() ) - GFXTextureManager::removeEventDelegate( this, &PostEffect::_onTextureEvent ); - - if ( mNamedTarget.isRegistered() ) + bool anyNamed = false; + for (U32 c = 0; c < NumMRTTargets; c++) { - mNamedTarget.unregister(); - mNamedTarget.getTextureDelegate().clear(); + if (mNamedTarget[c].isRegistered()) + { + mNamedTarget[c].unregister(); + mNamedTarget[c].getTextureDelegate().clear(); + anyNamed = true; + } } + if (anyNamed || mNamedTargetDepthStencil.isRegistered() ) + GFXTextureManager::removeEventDelegate( this, &PostEffect::_onTextureEvent ); + if ( mNamedTargetDepthStencil.isRegistered() ) mNamedTargetDepthStencil.unregister(); } @@ -1156,7 +1178,7 @@ void PostEffect::_setupTexture( U32 stage, GFXTexHandle &inputTex, const RectI * RectI viewport = GFX->getViewport(); - if ( texFilename.compare( "$inTex", 0, String::NoCase ) == 0 ) + if ( _inTexSlotFromName(texFilename) >= 0 ) { theTex = inputTex; @@ -1236,162 +1258,166 @@ void PostEffect::_setupTransforms() void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarget ) { - if ( mNamedTarget.isRegistered() || - mTargetName.compare( "$outTex", 0, String::NoCase ) == 0 ) + for (U32 c = 0; c < NumMRTTargets; c++) { - // Size it relative to the texture of the first stage or - // if NULL then use the current target. - - Point2I targetSize; - - // If we have an absolute target size then use that. - if ( !mTargetSize.isZero() ) - targetSize = mTargetSize; - - // Else generate a relative size using the target scale. - else if ( mActiveTextures[ 0 ] ) + if (mNamedTarget[c].isRegistered() || _outTexSlotFromName(mTargetName[c]) >= 0) { - const Point3I &texSize = mActiveTextures[ 0 ]->getSize(); + // Size it relative to the texture of the first stage or + // if NULL then use the current target. - targetSize.set( texSize.x * mTargetScale.x, - texSize.y * mTargetScale.y ); - } - else - { - GFXTarget *oldTarget = GFX->getActiveRenderTarget(); - const Point2I &oldTargetSize = oldTarget->getSize(); + Point2I targetSize; - targetSize.set( oldTargetSize.x * mTargetScale.x, - oldTargetSize.y * mTargetScale.y ); - } + // If we have an absolute target size then use that. + if (!mTargetSize.isZero()) + targetSize = mTargetSize; - // Make sure its at least 1x1. - targetSize.setMax( Point2I::One ); - - if ( mNamedTarget.isRegistered() || - !mTargetTex || - mTargetTex.getWidthHeight() != targetSize ) - { - mTargetTex.set( targetSize.x, targetSize.y, mTargetFormat, - &PostFxTargetProfile, "PostEffect::_setupTarget", mMipCap); - - if ( mTargetClear == PFXTargetClear_OnCreate ) - *outClearTarget = true; - - if(mTargetViewport == PFXTargetViewport_GFXViewport) + // Else generate a relative size using the target scale. + else if (mActiveTextures[0]) { - // 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 Point3I& texSize = mActiveTextures[0]->getSize(); - 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 ) ); + targetSize.set(texSize.x * mTargetScale.x, + texSize.y * mTargetScale.y); } else { - // PFXTargetViewport_TargetSize - mNamedTarget.setViewport( RectI( 0, 0, targetSize.x, targetSize.y ) ); + GFXTarget* oldTarget = GFX->getActiveRenderTarget(); + const Point2I& oldTargetSize = oldTarget->getSize(); + + targetSize.set(oldTargetSize.x * mTargetScale.x, + oldTargetSize.y * mTargetScale.y); + } + + // Make sure its at least 1x1. + targetSize.setMax(Point2I::One); + + if (mNamedTarget[c].isRegistered() || + !mTargetTex[c] || + mTargetTex[c].getWidthHeight() != targetSize) + { + mTargetTex[c].set(targetSize.x, targetSize.y, mTargetFormat[c], + &PostFxTargetProfile, "PostEffect::_setupTarget", mMipCap); + + if (mTargetClear[c] == PFXTargetClear_OnCreate) + *outClearTarget = true; + + 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[c].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[c].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[c].setViewport(RectI(0, 0, targetSize.x, targetSize.y)); + } } } + else + mTargetTex[c] = NULL; } - else - mTargetTex = NULL; // Do we have a named depthStencil target? - if ( mNamedTargetDepthStencil.isRegistered() ) + if (mNamedTargetDepthStencil.isRegistered()) { // Size it relative to the texture of the first stage or // if NULL then use the current target. Point2I targetSize; // If we have an absolute target size then use that. - if ( !mTargetSize.isZero() ) + if (!mTargetSize.isZero()) targetSize = mTargetSize; // Else generate a relative size using the target scale. - else if ( mActiveTextures[ 0 ] ) + else if (mActiveTextures[0]) { - const Point3I &texSize = mActiveTextures[ 0 ]->getSize(); + const Point3I& texSize = mActiveTextures[0]->getSize(); - targetSize.set( texSize.x * mTargetScale.x, - texSize.y * mTargetScale.y ); + targetSize.set(texSize.x * mTargetScale.x, + texSize.y * mTargetScale.y); } else { - GFXTarget *oldTarget = GFX->getActiveRenderTarget(); - const Point2I &oldTargetSize = oldTarget->getSize(); + GFXTarget* oldTarget = GFX->getActiveRenderTarget(); + const Point2I& oldTargetSize = oldTarget->getSize(); - targetSize.set( oldTargetSize.x * mTargetScale.x, - oldTargetSize.y * mTargetScale.y ); + targetSize.set(oldTargetSize.x * mTargetScale.x, + oldTargetSize.y * mTargetScale.y); } // Make sure its at least 1x1. - targetSize.setMax( Point2I::One ); - - if ( mNamedTargetDepthStencil.isRegistered() && - mTargetDepthStencil.getWidthHeight() != targetSize ) - { - mTargetDepthStencil.set( targetSize.x, targetSize.y, GFXFormatD24S8, - &GFXZTargetProfile, "PostEffect::_setupTarget" ); + targetSize.setMax(Point2I::One); - if ( mTargetClear == PFXTargetClear_OnCreate ) + if (mNamedTargetDepthStencil.isRegistered() && + mTargetDepthStencil.getWidthHeight() != targetSize) + { + mTargetDepthStencil.set(targetSize.x, targetSize.y, GFXFormatD24S8, + &GFXZTargetProfile, "PostEffect::_setupTarget"); + + if (mTargetClear[0] == PFXTargetClear_OnCreate) *outClearTarget = true; - if(mTargetViewport == PFXTargetViewport_GFXViewport) + 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(); + 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(); + 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 ) ); + 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()) + 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(); + 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(); + 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 ) ); + 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 ) ); + mNamedTargetDepthStencil.setViewport(RectI(0, 0, targetSize.x, targetSize.y)); } } } else mTargetDepthStencil = NULL; - if ( mTargetClear == PFXTargetClear_OnDraw ) + if (mTargetClear[0] == PFXTargetClear_OnDraw) *outClearTarget = true; - if ( !mTarget && (mTargetTex || mTargetDepthStencil) ) + if (!mTarget && (mTargetTex || mTargetDepthStencil)) mTarget = GFX->allocRenderToTextureTarget(); } void PostEffect::_cleanTargets( bool recurse ) { - mTargetTex = NULL; + for (U32 c = 0; c < NumMRTTargets; c++) + mTargetTex[c] = NULL; + mTargetDepthStencil = NULL; mTarget = NULL; @@ -1407,7 +1433,7 @@ void PostEffect::_cleanTargets( bool recurse ) } void PostEffect::process( const SceneRenderState *state, - GFXTexHandle &inOutTex, + GFXTexHandle& inOutTex, const RectI *inTexViewport ) { // If the shader is forced to be skipped... then skip. @@ -1461,27 +1487,56 @@ void PostEffect::process( const SceneRenderState *state, bool clearTarget = false; _setupTarget( state, &clearTarget ); - if ( mTargetTex || mTargetDepthStencil ) + const bool hasDepth = mTargetDepthStencil.isValid(); + bool hasColorTarget = false; + + for (U32 c = 0; c < NumMRTTargets; c++) + { + if (mTargetTex[c].isValid()) + { + hasColorTarget = true; + break; + } + } + + // Attach each color slot. NULL explicitly detaches unused slots, + // preventing stale attachments from a previous frame. + static const GFXTextureTarget::RenderSlot kSlots[NumMRTTargets] = + { + GFXTextureTarget::Color0, + GFXTextureTarget::Color1, + GFXTextureTarget::Color2, + GFXTextureTarget::Color3, + }; + + if (hasColorTarget || hasDepth) { const RectI &oldViewport = GFX->getViewport(); GFXTarget *oldTarget = GFX->getActiveRenderTarget(); GFX->pushActiveRenderTarget(); - mTarget->attachTexture( GFXTextureTarget::Color0, mTargetTex ); + + for (U32 c = 0; c < NumMRTTargets; c++) + { + mTarget->attachTexture(kSlots[c], mTargetTex[c].isValid() ? mTargetTex[c] : NULL); + } // Set the right depth stencil target. - if ( !mTargetDepthStencil && mTargetTex.getWidthHeight() == GFX->getActiveRenderTarget()->getSize() ) - mTarget->attachTexture( GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil ); + if (!hasDepth && mTargetTex[0].isValid() && mTargetTex[0].getWidthHeight() == oldTarget->getSize()) + mTarget->attachTexture(GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil); else - mTarget->attachTexture( GFXTextureTarget::DepthStencil, mTargetDepthStencil ); + mTarget->attachTexture(GFXTextureTarget::DepthStencil, mTargetDepthStencil); // Set the render target but not its viewport. We'll do that below. GFX->setActiveRenderTarget( mTarget, false ); - if(mNamedTarget.isRegistered()) + if (mNamedTarget[0].isRegistered()) { - // Always use the name target's viewport, if available. It was set up in _setupTarget(). - GFX->setViewport(mNamedTarget.getViewport()); + GFX->setViewport(mNamedTarget[0].getViewport()); + } + else if (mTargetTex[0].isValid()) + { + GFX->setViewport(RectI(Point2I::Zero, mTargetTex[0].getWidthHeight())); } else if(mTargetViewport == PFXTargetViewport_GFXViewport) { @@ -1509,8 +1564,19 @@ void PostEffect::process( const SceneRenderState *state, } } - if ( clearTarget ) - GFX->clear( GFXClearTarget, mTargetClearColor, 1.f, 0 ); + if (clearTarget) + { + LinearColorF clearColor = LinearColorF::BLACK; + for (U32 c = 0; c < NumMRTTargets; c++) + { + if (mTargetTex[c].isValid() && mTargetClear[c] != PFXTargetClear_None) + { + clearColor = mTargetClearColor[c]; + break; + } + } + GFX->clear(GFXClearTarget, clearColor, 1.f, 0); + } // Setup the shader and constants. if ( mShader ) @@ -1545,24 +1611,22 @@ void PostEffect::process( const SceneRenderState *state, // Allow PostEffecVis to hook in. PFXVIS->onPFXProcessed( this ); - if ( mTargetTex || mTargetDepthStencil ) + if (hasColorTarget || hasDepth) { mTarget->resolve(); GFX->popActiveRenderTarget(); } else { - // We wrote to the active back buffer, so release - // the current texture copy held by the manager. - // - // This ensures a new copy is made. PFXMGR->releaseBackBufferTex(); } - // Return and release our target texture. - inOutTex = mTargetTex; - if ( !mNamedTarget.isRegistered() ) - mTargetTex = NULL; + inOutTex = mTargetTex[0]; + for (U32 c = 0; c < NumMRTTargets; c++) + { + if (!mNamedTarget[c].isRegistered()) + mTargetTex[c] = NULL; + } // Restore the transforms before the children // are processed as it screws up the viewport. @@ -1842,19 +1906,22 @@ void PostEffect::_checkRequirements() } // First make sure the target format is supported. - if ( mNamedTarget.isRegistered() ) + for (U32 c = 0; c < NumMRTTargets; c++) { - Vector formats; - formats.push_back( mTargetFormat ); - GFXFormat format = GFX->selectSupportedFormat( &PostFxTargetProfile, - formats, - true, - false, - false ); - - // If we didn't get our format out then its unsupported! - if ( format != mTargetFormat ) - return; + if (mNamedTarget[c].isRegistered()) + { + Vector formats; + formats.push_back(mTargetFormat[c]); + GFXFormat format = GFX->selectSupportedFormat(&PostFxTargetProfile, + formats, + true, + false, + false); + + // If we didn't get our format out then its unsupported! + if (format != mTargetFormat[c]) + return; + } } // Gather macros specified on this PostEffect. @@ -1981,12 +2048,12 @@ void PostEffect::clearShaderMacros() mUpdateShader = true; } -GFXTextureObject* PostEffect::_getTargetTexture( U32 ) +GFXTextureObject* PostEffect::_getTargetTexture( U32 index) { // A TexGen PostEffect will generate its texture now if it // has not already. if ( mRenderTime == PFXTexGenOnDemand && - ( !mTargetTex || mUpdateShader ) ) + ( !mTargetTex[index] || mUpdateShader ) ) { GFXTexHandle chainTex; process( NULL, chainTex ); @@ -1996,7 +2063,7 @@ GFXTextureObject* PostEffect::_getTargetTexture( U32 ) // amount of non-swappable RTs in use. } - return mTargetTex.getPointer(); + return mTargetTex[index].getPointer(); } DefineEngineMethod( PostEffect, reload, void, (),, diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index 101f171dc..801db33c4 100644 --- a/Engine/source/postFx/postEffect.h +++ b/Engine/source/postFx/postEffect.h @@ -67,14 +67,6 @@ class Frustum; class SceneRenderState; class ConditionerFeature; - -/// -GFX_DeclareTextureProfile( PostFxTargetProfile ); - - - - -/// class PostEffect : public SimGroup { typedef SimGroup Parent; @@ -86,389 +78,317 @@ public: enum { NumTextures = 16, + + /// Maximum simultaneous color render target outputs (MRT) + NumMRTTargets = 4, }; protected: + //-------------------------------------------------------------------------- + // Input textures + //-------------------------------------------------------------------------- + DECLARE_IMAGEASSET_ARRAY(PostEffect, Texture, GFXStaticTextureSRGBProfile, NumTextures); - GFXTextureProfile* mTextureProfile[NumTextures]; - GFXTexHandle mTexture[NumTextures]; + GFXTextureProfile* mTextureProfile[NumTextures]; + GFXTexHandle mTexture[NumTextures]; + bool mTexSRGB[NumTextures]; - bool mTexSRGB[NumTextures]; + enum { NormalTextureType = 0, CubemapType, CubemapArrayType } mTextureType[NumTextures]; - enum - { - NormalTextureType = 0, - CubemapType, - CubemapArrayType, - } mTextureType[NumTextures]; - - GFXCubemapHandle mCubemapTextures[NumTextures]; + GFXCubemapHandle mCubemapTextures[NumTextures]; GFXCubemapArrayHandle mCubemapArrayTextures[NumTextures]; - NamedTexTarget mNamedTarget; - NamedTexTarget mNamedTargetDepthStencil; + GFXTextureObject* mActiveTextures[NumTextures]; + NamedTexTarget* mActiveNamedTarget[NumTextures]; + RectI mActiveTextureViewport[NumTextures]; - GFXTextureObject *mActiveTextures[NumTextures]; + //-------------------------------------------------------------------------- + // MRT color output targets + // + // Replaces the original single: mNamedTarget, mTargetName, mTargetTex, + // mTargetFormat, mTargetClearColor, mTargetClear + //-------------------------------------------------------------------------- - NamedTexTarget *mActiveNamedTarget[NumTextures]; + String mTargetName[NumMRTTargets]; ///< Per-slot output name. + GFXFormat mTargetFormat[NumMRTTargets]; ///< Per-slot texture format. + LinearColorF mTargetClearColor[NumMRTTargets]; ///< Per-slot clear colour. + PFXTargetClear mTargetClear[NumMRTTargets]; ///< Per-slot clear policy. - RectI mActiveTextureViewport[NumTextures]; + GFXTexHandle mTargetTex[NumMRTTargets]; ///< Runtime texture per slot. + NamedTexTarget mNamedTarget[NumMRTTargets]; ///< Named target per slot. - GFXStateBlockData *mStateBlockData; - - GFXStateBlockRef mStateBlock; - - String mShaderName; - - GFXShaderRef mShader; - - Vector mShaderMacros; - - GFXShaderConstBufferRef mShaderConsts; - - GFXShaderConstHandle *mRTSizeSC; - GFXShaderConstHandle *mOneOverRTSizeSC; - GFXShaderConstHandle* mRTRatioSC; - - GFXShaderConstHandle *mTexSizeSC[NumTextures]; - GFXShaderConstHandle *mRenderTargetParamsSC[NumTextures]; - GFXShaderConstHandle* mMipCountSC[NumTextures]; - - GFXShaderConstHandle *mViewportOffsetSC; - - GFXShaderConstHandle *mTargetViewportSC; - - GFXShaderConstHandle *mFogDataSC; - GFXShaderConstHandle *mFogColorSC; - GFXShaderConstHandle *mEyePosSC; - GFXShaderConstHandle *mMatWorldToScreenSC; - GFXShaderConstHandle *mMatScreenToWorldSC; - GFXShaderConstHandle *mMatPrevScreenToWorldSC; - GFXShaderConstHandle *mNearFarSC; - GFXShaderConstHandle *mInvNearFarSC; - GFXShaderConstHandle *mWorldToScreenScaleSC; - GFXShaderConstHandle *mProjectionOffsetSC; - GFXShaderConstHandle *mWaterColorSC; - GFXShaderConstHandle *mWaterFogDataSC; - GFXShaderConstHandle *mAmbientColorSC; - GFXShaderConstHandle *mWaterFogPlaneSC; - GFXShaderConstHandle *mWaterDepthGradMaxSC; - GFXShaderConstHandle *mScreenSunPosSC; - GFXShaderConstHandle *mLightDirectionSC; - GFXShaderConstHandle *mCameraForwardSC; - GFXShaderConstHandle *mAccumTimeSC; - GFXShaderConstHandle* mDampnessSC; - GFXShaderConstHandle *mDeltaTimeSC; - GFXShaderConstHandle *mInvCameraMatSC; - GFXShaderConstHandle *mMatCameraToWorldSC; - GFXShaderConstHandle *mInvCameraTransSC; - GFXShaderConstHandle *mMatCameraToScreenSC; - GFXShaderConstHandle *mMatScreenToCameraSC; - - GFXShaderConstHandle* mIsCapturingSC; - - bool mAllowReflectPass; - - /// If true update the shader. - bool mUpdateShader; + // These remain single values — shared across ALL active MRT slots. + Point2F mTargetScale; ///< Relative size vs current GFX render target. + Point2I mTargetSize; ///< Absolute size override; (0,0) = use mTargetScale. + PFXTargetViewport mTargetViewport; ///< How the viewport rect is derived. + /// Single GFXTextureTarget — ALL active MRT slots attach to this one object. GFXTextureTargetRef mTarget; - String mTargetName; - GFXTexHandle mTargetTex; S32 mMipCap; - String mTargetDepthStencilName; - GFXTexHandle mTargetDepthStencil; + //-------------------------------------------------------------------------- + // Depth stencil + //-------------------------------------------------------------------------- - /// If mTargetSize is zero then this scale is - /// used to make a relative texture size to the - /// active render target. - Point2F mTargetScale; + String mTargetDepthStencilName; + GFXTexHandle mTargetDepthStencil; + NamedTexTarget mNamedTargetDepthStencil; - /// If non-zero this is used as the absolute - /// texture target size. - /// @see mTargetScale - Point2I mTargetSize; + //-------------------------------------------------------------------------- + // State block / shader + //-------------------------------------------------------------------------- - GFXFormat mTargetFormat; + GFXStateBlockData* mStateBlockData; + GFXStateBlockRef mStateBlock; + String mShaderName; + GFXShaderRef mShader; + Vector mShaderMacros; + GFXShaderConstBufferRef mShaderConsts; - /// The color to prefill the named target when - /// first created by the effect. - LinearColorF mTargetClearColor; + //-------------------------------------------------------------------------- + // Auto shader constant handles + //-------------------------------------------------------------------------- + GFXShaderConstHandle* mRTSizeSC; + GFXShaderConstHandle* mOneOverRTSizeSC; + GFXShaderConstHandle* mRTRatioSC; + GFXShaderConstHandle* mTexSizeSC[NumTextures]; + GFXShaderConstHandle* mRenderTargetParamsSC[NumTextures]; + GFXShaderConstHandle* mMipCountSC[NumTextures]; + GFXShaderConstHandle* mViewportOffsetSC; + GFXShaderConstHandle* mTargetViewportSC; + GFXShaderConstHandle* mFogDataSC; + GFXShaderConstHandle* mFogColorSC; + GFXShaderConstHandle* mEyePosSC; + GFXShaderConstHandle* mMatWorldToScreenSC; + GFXShaderConstHandle* mMatScreenToWorldSC; + GFXShaderConstHandle* mMatPrevScreenToWorldSC; + GFXShaderConstHandle* mNearFarSC; + GFXShaderConstHandle* mInvNearFarSC; + GFXShaderConstHandle* mWorldToScreenScaleSC; + GFXShaderConstHandle* mProjectionOffsetSC; + GFXShaderConstHandle* mWaterColorSC; + GFXShaderConstHandle* mWaterFogDataSC; + GFXShaderConstHandle* mAmbientColorSC; + GFXShaderConstHandle* mWaterFogPlaneSC; + GFXShaderConstHandle* mWaterDepthGradMaxSC; + GFXShaderConstHandle* mScreenSunPosSC; + GFXShaderConstHandle* mLightDirectionSC; + GFXShaderConstHandle* mCameraForwardSC; + GFXShaderConstHandle* mAccumTimeSC; + GFXShaderConstHandle* mDampnessSC; + GFXShaderConstHandle* mDeltaTimeSC; + GFXShaderConstHandle* mInvCameraMatSC; + GFXShaderConstHandle* mMatCameraToWorldSC; + GFXShaderConstHandle* mInvCameraTransSC; + GFXShaderConstHandle* mMatCameraToScreenSC; + GFXShaderConstHandle* mMatScreenToCameraSC; + GFXShaderConstHandle* mIsCapturingSC; + + //-------------------------------------------------------------------------- + // Render scheduling + //-------------------------------------------------------------------------- + + bool mAllowReflectPass; + bool mUpdateShader; PFXRenderTime mRenderTime; - PFXTargetClear mTargetClear; - PFXTargetViewport mTargetViewport; + PFXTargetClear mTargetClear_unused; // kept for binary compat if needed — see arrays above + String mRenderBin; + S16 mRenderPriority; + bool mIsValid; + bool mEnabled; + bool mSkip; + bool mPreProcessed; + bool mOneFrameOnly; + bool mOnThisFrame; + U32 mShaderReloadKey; - String mRenderBin; - - S16 mRenderPriority; - - /// This is true if the effect has been succesfully - /// initialized and all requirements are met for use. - bool mIsValid; - - /// True if the effect has been enabled by the manager. - bool mEnabled; - - /// Skip processing of this PostEffect and its children even if its parent is enabled. - /// Parent and sibling PostEffects in the chain are still processed. - /// This is intended for debugging purposes. - bool mSkip; - bool mPreProcessed; - - bool mOneFrameOnly; - bool mOnThisFrame; - - U32 mShaderReloadKey; + //-------------------------------------------------------------------------- + // EffectConst + //-------------------------------------------------------------------------- class EffectConst { public: - - EffectConst( const String &name, const String &val ) - : mName( name ), - mHandle( NULL ), - mDirty( true ) - { - set( val ); - } - - EffectConst(const String &name, const F32 &val) - : mName(name), - mHandle(NULL), - mDirty(true) - { + EffectConst(const String& name, const String& val) + : mName(name), mHandle(NULL), mDirty(true) { + set(val); + } + EffectConst(const String& name, const F32& val) + : mName(name), mHandle(NULL), mDirty(true) { set(val); } - EffectConst(const String& name, const int& val) - : mName(name), - mHandle(NULL), - mDirty(true) - { + : mName(name), mHandle(NULL), mDirty(true) { + set(val); + } + EffectConst(const String& name, const Point4F& val) + : mName(name), mHandle(NULL), mDirty(true) { + set(val); + } + EffectConst(const String& name, const MatrixF& val) + : mName(name), mHandle(NULL), mDirty(true) { + set(val); + } + EffectConst(const String& name, const Vector& val) + : mName(name), mHandle(NULL), mDirty(true) { + set(val); + } + EffectConst(const String& name, const Vector& val) + : mName(name), mHandle(NULL), mDirty(true) { set(val); } - EffectConst(const String &name, const Point4F &val) - : mName(name), - mHandle(NULL), - mDirty(true) - { - set(val); - } - - EffectConst(const String &name, const MatrixF &val) - : mName(name), - mHandle(NULL), - mDirty(true) - { - set(val); - } - - EffectConst(const String &name, const Vector &val) - : mName(name), - mHandle(NULL), - mDirty(true) - { - set(val); - } - - EffectConst(const String &name, const Vector &val) - : mName(name), - mHandle(NULL), - mDirty(true) - { - set(val); - } - - void set( const String &newVal ); - void set(const F32 &newVal); + void set(const String& newVal); + void set(const F32& newVal); void set(const int& newVal); - void set(const Point4F &newVal); - void set(const MatrixF &newVal); - void set(const Vector &newVal); - void set(const Vector &newVal); - - void setToBuffer( GFXShaderConstBufferRef buff ); - - String mName; - - GFXShaderConstHandle *mHandle; - - String mStringVal; - - S32 mIntVal; - F32 mFloatVal; - Point4F mPointVal; - MatrixF mMatrixVal; + void set(const Point4F& newVal); + void set(const MatrixF& newVal); + void set(const Vector& newVal); + void set(const Vector& newVal); + void setToBuffer(GFXShaderConstBufferRef buff); + String mName; + GFXShaderConstHandle* mHandle; + String mStringVal; + S32 mIntVal; + F32 mFloatVal; + Point4F mPointVal; + MatrixF mMatrixVal; Vector mPointArrayVal; Vector mMatrixArrayVal; - enum - { - StringType, - IntType, - FloatType, - PointType, - MatrixType, - PointArrayType, - MatrixArrayType + enum { + StringType, IntType, FloatType, PointType, + MatrixType, PointArrayType, MatrixArrayType } mValueType; bool mDirty; }; - typedef HashTable EffectConstTable; - + typedef HashTable EffectConstTable; EffectConstTable mEffectConsts; - /// - virtual void _updateScreenGeometry( const Frustum &frustum, - GFXVertexBufferHandle *outVB ); + //-------------------------------------------------------------------------- + // Internal methods + //-------------------------------------------------------------------------- - /// - virtual void _setupStateBlock( const SceneRenderState *state ); - - /// - virtual void _setupConstants( const SceneRenderState *state ); - - /// + virtual void _updateScreenGeometry(const Frustum& frustum, GFXVertexBufferHandle* outVB); + virtual void _setupStateBlock(const SceneRenderState* state); + virtual void _setupConstants(const SceneRenderState* state); virtual void _setupTransforms(); + virtual void _setupTarget(const SceneRenderState* state, bool* outClearTarget); + virtual void _setupTexture(U32 slot, GFXTexHandle& inputTex, const RectI* inTexViewport); + virtual void _setupCubemapTexture(U32 stage, GFXCubemapHandle& inputTex); + virtual void _setupCubemapArrayTexture(U32 slot, GFXCubemapArrayHandle& inputTex); - /// - virtual void _setupTarget( const SceneRenderState *state, bool *outClearTarget ); + static bool _setIsEnabled(void* object, const char* index, const char* data); - /// - virtual void _setupTexture( U32 slot, GFXTexHandle &inputTex, const RectI *inTexViewport ); - virtual void _setupCubemapTexture(U32 stage, GFXCubemapHandle &inputTex); - virtual void _setupCubemapArrayTexture(U32 slot, GFXCubemapArrayHandle &inputTex); - - - /// Protected set method for toggling the enabled state. - static bool _setIsEnabled( void *object, const char *index, const char *data ); - - /// Called from the light manager activate signal. - /// @see LightManager::addActivateCallback - void _onLMActivate( const char*, bool activate ) + void _onLMActivate(const char*, bool activate) { - if ( activate ) - mUpdateShader = true; + if (activate) mUpdateShader = true; } - /// We handle texture events to release named rendered targets. - /// @see GFXTextureManager::addEventDelegate - void _onTextureEvent( GFXTexCallbackCode code ) + void _onTextureEvent(GFXTexCallbackCode code) { - if ( code == GFXZombify && (mNamedTarget.isRegistered() || mNamedTargetDepthStencil.isRegistered()) ) - _cleanTargets(); + if (code != GFXZombify) return; + bool anyNamed = mNamedTargetDepthStencil.isRegistered(); + for (U32 c = 0; c < NumMRTTargets && !anyNamed; c++) + anyNamed = mNamedTarget[c].isRegistered(); + if (anyNamed) _cleanTargets(); } - /// void _updateConditioners(); - - /// - void _cleanTargets( bool recurse = false ); - - /// + void _cleanTargets(bool recurse = false); void _checkRequirements(); + GFXTextureObject* _getTargetTexture(U32 index); - /// - GFXTextureObject* _getTargetTexture( U32 index ); + /// Map "$outTex" / "$outTex0".."$outTex3" to a slot index [0..NumMRTTargets-1]. + /// Returns -1 if the name is not an $outTexN pattern. + S32 _outTexSlotFromName(const String& name) + { + if (name.compare("$outTex", 0, String::NoCase) == 0) return 0; // backwards compat + if (name.compare("$outTex0", 0, String::NoCase) == 0) return 0; + if (name.compare("$outTex1", 0, String::NoCase) == 0) return 1; + if (name.compare("$outTex2", 0, String::NoCase) == 0) return 2; + if (name.compare("$outTex3", 0, String::NoCase) == 0) return 3; + return -1; + } + + S32 _inTexSlotFromName(const String& name) + { + if (name.compare("$inTex", 0, String::NoCase) == 0) return 0; // backwards compat + if (name.compare("$inTex0", 0, String::NoCase) == 0) return 0; + if (name.compare("$inTex1", 0, String::NoCase) == 0) return 1; + if (name.compare("$inTex2", 0, String::NoCase) == 0) return 2; + if (name.compare("$inTex3", 0, String::NoCase) == 0) return 3; + return -1; + } public: - /// Constructor. PostEffect(); - - /// Destructor. virtual ~PostEffect(); DECLARE_CONOBJECT(PostEffect); - // SimObject bool onAdd() override; void onRemove() override; static void initPersistFields(); - /// @name Callbacks - /// @{ + DECLARE_CALLBACK(void, onAdd, ()); + DECLARE_CALLBACK(void, preProcess, ()); + DECLARE_CALLBACK(void, setShaderConsts, ()); + DECLARE_CALLBACK(bool, onEnabled, ()); + DECLARE_CALLBACK(void, onDisabled, ()); - DECLARE_CALLBACK( void, onAdd, () ); - DECLARE_CALLBACK( void, preProcess, () ); - DECLARE_CALLBACK( void, setShaderConsts, () ); - DECLARE_CALLBACK( bool, onEnabled, () ); - DECLARE_CALLBACK( void, onDisabled, () ); + virtual void process(const SceneRenderState* state, + GFXTexHandle& inOutTex, + const RectI* inTexViewport = NULL); - /// @} - - virtual void process( const SceneRenderState *state, - GFXTexHandle &inOutTex, - const RectI *inTexViewport = NULL ); - - /// void reload(); - - /// void enable(); - - /// void disable(); - /// Dump the shader disassembly to a temporary text file. - /// Returns true and sets outFilename to the file if successful. - bool dumpShaderDisassembly( String &outFilename ) const; - - /// Returns the SimSet which contains all PostEffects. + bool dumpShaderDisassembly(String& outFilename) const; SimSet* getSet() const; - /// bool isEnabled() const { return mEnabled; } - - /// Is set to skip rendering. bool isSkipped() const { return mSkip; } - - /// Set the effect to skip rendering. - void setSkip( bool skip ) { mSkip = skip; } + void setSkip(bool s) { mSkip = s; } PFXRenderTime getRenderTime() const { return mRenderTime; } + const String& getRenderBin() const { return mRenderBin; } + F32 getPriority() const { return mRenderPriority; } - const String& getRenderBin() const { return mRenderBin; } - - F32 getPriority() const { return mRenderPriority; } - - void setTexture( U32 index, const String &filePath ); + void setTexture(U32 index, const String& filePath); void setTexture(U32 index, const GFXTexHandle& texHandle); - void setCubemapTexture(U32 index, const GFXCubemapHandle &cubemapHandle); - void setCubemapArrayTexture(U32 index, const GFXCubemapArrayHandle &cubemapArrayHandle); + void setCubemapTexture(U32 index, const GFXCubemapHandle& handle); + void setCubemapArrayTexture(U32 index, const GFXCubemapArrayHandle& handle); - void setShaderMacro( const String &name, const String &value = String::EmptyString ); - bool removeShaderMacro( const String &name ); + void setShaderMacro(const String& name, const String& value = String::EmptyString); + bool removeShaderMacro(const String& name); void clearShaderMacros(); - /// - void setShaderConst( const String &name, const String &val ); - void setShaderConst(const String &name, const F32 &val); + void setShaderConst(const String& name, const String& val); + void setShaderConst(const String& name, const F32& val); void setShaderConst(const String& name, const int& val); - void setShaderConst(const String &name, const Point4F &val); - void setShaderConst(const String &name, const MatrixF &val); - void setShaderConst(const String &name, const Vector &val); - void setShaderConst(const String &name, const Vector &val); + void setShaderConst(const String& name, const Point4F& val); + void setShaderConst(const String& name, const MatrixF& val); + void setShaderConst(const String& name, const Vector& val); + void setShaderConst(const String& name, const Vector& val); - void setOnThisFrame( bool enabled ) { mOnThisFrame = enabled; } + void setOnThisFrame(bool e) { mOnThisFrame = e; } bool isOnThisFrame() { return mOnThisFrame; } - void setOneFrameOnly( bool enabled ) { mOneFrameOnly = enabled; } - bool isOneFrameOnly() { return mOneFrameOnly; } + void setOneFrameOnly(bool e) { mOneFrameOnly = e; } + bool isOneFrameOnly() { return mOneFrameOnly; } - F32 getAspectRatio() const; - - GFXShaderRef getShader() { return mShader; } + F32 getAspectRatio() const; + GFXShaderRef getShader() { return mShader; } Vector* getShaderMacros() { return &mShaderMacros; } GFXShaderConstBufferRef getShaderConstBuffer() { return mShaderConsts; } - enum PostEffectRequirements { diff --git a/Engine/source/postFx/postEffectCommon.h b/Engine/source/postFx/postEffectCommon.h index d99800295..d3a031337 100644 --- a/Engine/source/postFx/postEffectCommon.h +++ b/Engine/source/postFx/postEffectCommon.h @@ -99,11 +99,10 @@ struct PFXFrameState }; /// +GFX_DeclareTextureProfile( PostFxTargetProfile) ; GFX_DeclareTextureProfile( PostFxTextureProfile ); GFX_DeclareTextureProfile( PostFxTextureSRGBProfile ); - GFX_DeclareTextureProfile( VRTextureProfile ); - GFX_DeclareTextureProfile( VRDepthProfile ); /// @@ -119,4 +118,4 @@ GFXDeclareVertexFormat( PFXVertex ) Point3F wsEyeRay; }; -#endif // _POSTEFFECTCOMMON_H_ \ No newline at end of file +#endif // _POSTEFFECTCOMMON_H_ diff --git a/Engine/source/postFx/postEffectVis.cpp b/Engine/source/postFx/postEffectVis.cpp index 4a7442b72..471727a3b 100644 --- a/Engine/source/postFx/postEffectVis.cpp +++ b/Engine/source/postFx/postEffectVis.cpp @@ -228,8 +228,8 @@ void PostEffectVis::onPFXProcessed( PostEffect *pfx ) GFXTextureObject *tex; - if ( pfx->mTargetTex ) - tex = pfx->mTargetTex; + if ( pfx->mTargetTex[0]) + tex = pfx->mTargetTex[0]; else tex = PFXMGR->getBackBufferTex(); @@ -245,7 +245,7 @@ void PostEffectVis::onPFXProcessed( PostEffect *pfx ) if ( tex ) - dSprintf( caption, 256, "%s[%i] target - %s [ %ix%i ]", name, pfx->getId(), pfx->mTargetName.c_str(), tex->getWidth(), tex->getHeight() ); + dSprintf( caption, 256, "%s[%i] target - %s [ %ix%i ]", name, pfx->getId(), pfx->mTargetName[0].c_str(), tex->getWidth(), tex->getHeight()); else dSprintf( caption, 256, "%s[%i] target", name, pfx->getId() );