mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-16 00:54:54 +00:00
Merge 7480ac9754 into 8407fa360c
This commit is contained in:
commit
051555f4e5
7 changed files with 549 additions and 577 deletions
|
|
@ -551,7 +551,7 @@ void ProjectedShadow::_renderToTexture( F32 camDist, const TSRenderState &rdata
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( smShadowFilter )
|
if ( smShadowFilter )
|
||||||
smShadowFilter->process( NULL, mShadowTexture );
|
smShadowFilter->process( NULL, &mShadowTexture );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Restore frustum
|
// Restore frustum
|
||||||
|
|
|
||||||
|
|
@ -137,9 +137,6 @@ GFX_ImplementTextureProfile( PostFxTargetProfile,
|
||||||
GFXTextureProfile::Pooled,
|
GFXTextureProfile::Pooled,
|
||||||
GFXTextureProfile::NONE );
|
GFXTextureProfile::NONE );
|
||||||
|
|
||||||
IMPLEMENT_CONOBJECT(PostEffect);
|
|
||||||
|
|
||||||
|
|
||||||
GFX_ImplementTextureProfile( PostFxTextureProfile,
|
GFX_ImplementTextureProfile( PostFxTextureProfile,
|
||||||
GFXTextureProfile::DiffuseMap,
|
GFXTextureProfile::DiffuseMap,
|
||||||
GFXTextureProfile::Static | GFXTextureProfile::PreserveSize,
|
GFXTextureProfile::Static | GFXTextureProfile::PreserveSize,
|
||||||
|
|
@ -162,6 +159,12 @@ GFX_ImplementTextureProfile( VRDepthProfile,
|
||||||
GFXTextureProfile::ZTarget,
|
GFXTextureProfile::ZTarget,
|
||||||
GFXTextureProfile::NONE );
|
GFXTextureProfile::NONE );
|
||||||
|
|
||||||
|
IMPLEMENT_CONOBJECT(PostEffect);
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// EffectConst
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
void PostEffect::EffectConst::set( const String &newVal )
|
void PostEffect::EffectConst::set( const String &newVal )
|
||||||
{
|
{
|
||||||
if ( mStringVal == newVal )
|
if ( mStringVal == newVal )
|
||||||
|
|
@ -445,69 +448,77 @@ void PostEffect::EffectConst::setToBuffer( GFXShaderConstBufferRef buff )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// EffectConst END
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// PostEffect
|
// PostEffect
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
PostEffect::PostEffect()
|
PostEffect::PostEffect()
|
||||||
: mRenderTime( PFXAfterDiffuse ),
|
: mRenderTime(PFXAfterDiffuse),
|
||||||
mRenderPriority( 1.0 ),
|
mRenderPriority(1.0),
|
||||||
mEnabled( false ),
|
mEnabled(false),
|
||||||
mStateBlockData( NULL ),
|
mStateBlockData(NULL),
|
||||||
mUpdateShader( true ),
|
mUpdateShader(true),
|
||||||
mSkip( false ),
|
mSkip(false),
|
||||||
mPreProcessed(false),
|
mPreProcessed(false),
|
||||||
mAllowReflectPass( false ),
|
mAllowReflectPass(false),
|
||||||
mTargetClear( PFXTargetClear_None ),
|
mTargetScale(Point2F::One),
|
||||||
mTargetScale( Point2F::One ),
|
mTargetSize(Point2I::Zero),
|
||||||
mTargetViewport( PFXTargetViewport_TargetSize ),
|
mTargetViewport(PFXTargetViewport_TargetSize),
|
||||||
mTargetSize( Point2I::Zero ),
|
mMipCap(1),
|
||||||
mTargetFormat( GFXFormatR8G8B8A8 ),
|
mOneFrameOnly(false),
|
||||||
mTargetClearColor( LinearColorF::BLACK ),
|
mOnThisFrame(true),
|
||||||
mOneFrameOnly( false ),
|
mRTSizeSC(NULL),
|
||||||
mOnThisFrame( true ),
|
mIsValid(false),
|
||||||
mRTSizeSC( NULL ),
|
mShaderReloadKey(0),
|
||||||
mIsValid( false ),
|
mOneOverRTSizeSC(NULL),
|
||||||
mShaderReloadKey( 0 ),
|
mViewportOffsetSC(NULL),
|
||||||
mOneOverRTSizeSC( NULL ),
|
mTargetViewportSC(NULL),
|
||||||
mViewportOffsetSC( NULL ),
|
mFogDataSC(NULL),
|
||||||
mTargetViewportSC( NULL ),
|
mFogColorSC(NULL),
|
||||||
mFogDataSC( NULL ),
|
mEyePosSC(NULL),
|
||||||
mFogColorSC( NULL ),
|
mMatWorldToScreenSC(NULL),
|
||||||
mEyePosSC( NULL ),
|
mMatScreenToWorldSC(NULL),
|
||||||
mMatWorldToScreenSC( NULL ),
|
mMatPrevScreenToWorldSC(NULL),
|
||||||
mMatScreenToWorldSC( NULL ),
|
mNearFarSC(NULL),
|
||||||
mMatPrevScreenToWorldSC( NULL ),
|
mInvNearFarSC(NULL),
|
||||||
mNearFarSC( NULL ),
|
mWorldToScreenScaleSC(NULL),
|
||||||
mInvNearFarSC( NULL ),
|
mProjectionOffsetSC(NULL),
|
||||||
mWorldToScreenScaleSC( NULL ),
|
mWaterColorSC(NULL),
|
||||||
mProjectionOffsetSC( NULL ),
|
mWaterFogDataSC(NULL),
|
||||||
mWaterColorSC( NULL ),
|
mAmbientColorSC(NULL),
|
||||||
mWaterFogDataSC( NULL ),
|
mWaterFogPlaneSC(NULL),
|
||||||
mAmbientColorSC( NULL ),
|
mWaterDepthGradMaxSC(NULL),
|
||||||
mWaterFogPlaneSC( NULL ),
|
mScreenSunPosSC(NULL),
|
||||||
mWaterDepthGradMaxSC( NULL ),
|
mLightDirectionSC(NULL),
|
||||||
mScreenSunPosSC( NULL ),
|
mCameraForwardSC(NULL),
|
||||||
mLightDirectionSC( NULL ),
|
mAccumTimeSC(NULL),
|
||||||
mCameraForwardSC( NULL ),
|
mDampnessSC(NULL),
|
||||||
mAccumTimeSC( NULL ),
|
mDeltaTimeSC(NULL),
|
||||||
mDampnessSC(NULL),
|
mInvCameraMatSC(NULL),
|
||||||
mDeltaTimeSC( NULL ),
|
mMatCameraToWorldSC(NULL),
|
||||||
mInvCameraMatSC( NULL ),
|
mInvCameraTransSC(NULL),
|
||||||
mMatCameraToWorldSC( NULL),
|
mMatCameraToScreenSC(NULL),
|
||||||
mInvCameraTransSC(NULL),
|
mMatScreenToCameraSC(NULL),
|
||||||
mMatCameraToScreenSC(NULL),
|
mIsCapturingSC(NULL)
|
||||||
mMatScreenToCameraSC(NULL),
|
|
||||||
mIsCapturingSC(NULL),
|
|
||||||
mMipCap(1)
|
|
||||||
{
|
{
|
||||||
dMemset( mTexSRGB, 0, sizeof(bool) * NumTextures);
|
// MRT arrays — slot 0 gets primary defaults, 1-3 are inactive.
|
||||||
dMemset( mActiveTextures, 0, sizeof( GFXTextureObject* ) * NumTextures );
|
for (U32 c = 0; c < NumMRTTargets; c++)
|
||||||
dMemset( mActiveNamedTarget, 0, sizeof( NamedTexTarget* ) * NumTextures );
|
{
|
||||||
dMemset( mActiveTextureViewport, 0, sizeof( RectI ) * NumTextures );
|
mTargetFormat[c] = GFXFormatR8G8B8A8;
|
||||||
dMemset( mTexSizeSC, 0, sizeof( GFXShaderConstHandle* ) * NumTextures );
|
mTargetClearColor[c] = LinearColorF::BLACK;
|
||||||
dMemset( mRenderTargetParamsSC, 0, sizeof( GFXShaderConstHandle* ) * NumTextures );
|
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);
|
dMemset(mMipCountSC, 0, sizeof(GFXShaderConstHandle*) * NumTextures);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -527,9 +538,18 @@ void PostEffect::initPersistFields()
|
||||||
addField( "stateBlock", TYPEID<GFXStateBlockData>(), Offset( mStateBlockData, PostEffect ),
|
addField( "stateBlock", TYPEID<GFXStateBlockData>(), Offset( mStateBlockData, PostEffect ),
|
||||||
"Name of a GFXStateBlockData for this effect." );
|
"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"
|
"String identifier of this effect's target texture.\n"
|
||||||
"@see PFXTextureIdentifiers" );
|
"@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 ),
|
addField( "targetDepthStencil", TypeRealString, Offset( mTargetDepthStencilName, PostEffect ),
|
||||||
"Optional string identifier for this effect's target depth/stencil texture.\n"
|
"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 ),
|
addField( "targetSize", TypePoint2I, Offset( mTargetSize, PostEffect ),
|
||||||
"If non-zero this is used as the absolute target size." );
|
"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 ),
|
addField( "targetViewport", TYPEID< PFXTargetViewport >(), Offset( mTargetViewport, PostEffect ),
|
||||||
"Specifies how the viewport should be set up for a target texture." );
|
"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?
|
// 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));
|
if (mTargetName[c].isNotEmpty() && mTargetName[c][0] == '#')
|
||||||
mNamedTarget.getTextureDelegate().bind( this, &PostEffect::_getTargetTexture );
|
{
|
||||||
|
mNamedTarget[c].registerWithName(mTargetName[c].substr(1));
|
||||||
|
mNamedTarget[c].getTextureDelegate().bind(this, &PostEffect::_getTargetTexture);
|
||||||
|
anyNamed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mTargetDepthStencilName.isNotEmpty() && mTargetDepthStencilName[0] == '#' )
|
if ( mTargetDepthStencilName.isNotEmpty() && mTargetDepthStencilName[0] == '#' )
|
||||||
mNamedTargetDepthStencil.registerWithName( mTargetDepthStencilName.substr( 1 ) );
|
mNamedTargetDepthStencil.registerWithName( mTargetDepthStencilName.substr( 1 ) );
|
||||||
|
|
||||||
if (mNamedTarget.isRegistered() || mNamedTargetDepthStencil.isRegistered())
|
if (anyNamed || mNamedTargetDepthStencil.isRegistered())
|
||||||
GFXTextureManager::addEventDelegate( this, &PostEffect::_onTextureEvent );
|
GFXTextureManager::addEventDelegate( this, &PostEffect::_onTextureEvent );
|
||||||
|
|
||||||
// Call onAdd in script
|
// Call onAdd in script
|
||||||
|
|
@ -661,15 +678,20 @@ void PostEffect::onRemove()
|
||||||
mShader = NULL;
|
mShader = NULL;
|
||||||
_cleanTargets();
|
_cleanTargets();
|
||||||
|
|
||||||
if ( mNamedTarget.isRegistered() || mNamedTargetDepthStencil.isRegistered() )
|
bool anyNamed = false;
|
||||||
GFXTextureManager::removeEventDelegate( this, &PostEffect::_onTextureEvent );
|
for (U32 c = 0; c < NumMRTTargets; c++)
|
||||||
|
|
||||||
if ( mNamedTarget.isRegistered() )
|
|
||||||
{
|
{
|
||||||
mNamedTarget.unregister();
|
if (mNamedTarget[c].isRegistered())
|
||||||
mNamedTarget.getTextureDelegate().clear();
|
{
|
||||||
|
mNamedTarget[c].unregister();
|
||||||
|
mNamedTarget[c].getTextureDelegate().clear();
|
||||||
|
anyNamed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (anyNamed || mNamedTargetDepthStencil.isRegistered() )
|
||||||
|
GFXTextureManager::removeEventDelegate( this, &PostEffect::_onTextureEvent );
|
||||||
|
|
||||||
if ( mNamedTargetDepthStencil.isRegistered() )
|
if ( mNamedTargetDepthStencil.isRegistered() )
|
||||||
mNamedTargetDepthStencil.unregister();
|
mNamedTargetDepthStencil.unregister();
|
||||||
}
|
}
|
||||||
|
|
@ -1147,7 +1169,10 @@ void PostEffect::_setupConstants( const SceneRenderState *state )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostEffect::_setupTexture( U32 stage, GFXTexHandle &inputTex, const RectI *inTexViewport )
|
void PostEffect::_setupTexture(U32 stage,
|
||||||
|
GFXTexHandle* inputTex,
|
||||||
|
U32 inputTexCount,
|
||||||
|
const RectI* inTexViewport)
|
||||||
{
|
{
|
||||||
const String &texFilename = mTextureAsset[stage].notNull() ? mTextureAsset[stage]->getImageFile() : "";
|
const String &texFilename = mTextureAsset[stage].notNull() ? mTextureAsset[stage]->getImageFile() : "";
|
||||||
|
|
||||||
|
|
@ -1156,17 +1181,17 @@ void PostEffect::_setupTexture( U32 stage, GFXTexHandle &inputTex, const RectI *
|
||||||
|
|
||||||
RectI viewport = GFX->getViewport();
|
RectI viewport = GFX->getViewport();
|
||||||
|
|
||||||
if ( texFilename.compare( "$inTex", 0, String::NoCase ) == 0 )
|
S32 inSlot = _inTexSlotFromName(texFilename);
|
||||||
|
if (inSlot >= 0)
|
||||||
{
|
{
|
||||||
theTex = inputTex;
|
if ((U32)inSlot < inputTexCount)
|
||||||
|
{
|
||||||
|
theTex = inputTex[inSlot];
|
||||||
|
|
||||||
if ( inTexViewport )
|
if (inSlot == 0 && inTexViewport)
|
||||||
{
|
viewport = *inTexViewport;
|
||||||
viewport = *inTexViewport;
|
else if (theTex)
|
||||||
}
|
viewport.set(0, 0, theTex->getWidth(), theTex->getHeight());
|
||||||
else if ( theTex )
|
|
||||||
{
|
|
||||||
viewport.set( 0, 0, theTex->getWidth(), theTex->getHeight() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( texFilename.compare( "$backBuffer", 0, String::NoCase ) == 0 )
|
else if ( texFilename.compare( "$backBuffer", 0, String::NoCase ) == 0 )
|
||||||
|
|
@ -1236,162 +1261,144 @@ void PostEffect::_setupTransforms()
|
||||||
|
|
||||||
void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarget )
|
void PostEffect::_setupTarget( const SceneRenderState *state, bool *outClearTarget )
|
||||||
{
|
{
|
||||||
if ( mNamedTarget.isRegistered() ||
|
Point2I targetSize;
|
||||||
mTargetName.compare( "$outTex", 0, String::NoCase ) == 0 )
|
if (!mTargetSize.isZero())
|
||||||
|
targetSize = mTargetSize;
|
||||||
|
else if (mActiveTextures[0])
|
||||||
{
|
{
|
||||||
// Size it relative to the texture of the first stage or
|
const Point3I& texSize = mActiveTextures[0]->getSize();
|
||||||
// if NULL then use the current target.
|
targetSize.set(texSize.x * mTargetScale.x, texSize.y * mTargetScale.y);
|
||||||
|
|
||||||
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 ] )
|
|
||||||
{
|
|
||||||
const Point3I &texSize = mActiveTextures[ 0 ]->getSize();
|
|
||||||
|
|
||||||
targetSize.set( texSize.x * mTargetScale.x,
|
|
||||||
texSize.y * mTargetScale.y );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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.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)
|
|
||||||
{
|
|
||||||
// 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 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 ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// PFXTargetViewport_TargetSize
|
|
||||||
mNamedTarget.setViewport( RectI( 0, 0, targetSize.x, targetSize.y ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mTargetTex = NULL;
|
|
||||||
|
|
||||||
// Do we have a named depthStencil target?
|
|
||||||
if ( mNamedTargetDepthStencil.isRegistered() )
|
|
||||||
{
|
{
|
||||||
// Size it relative to the texture of the first stage or
|
GFXTarget* oldTarget = GFX->getActiveRenderTarget();
|
||||||
// if NULL then use the current target.
|
const Point2I& oldTargetSize = oldTarget->getSize();
|
||||||
Point2I targetSize;
|
targetSize.set(oldTargetSize.x * mTargetScale.x, oldTargetSize.y * mTargetScale.y);
|
||||||
|
}
|
||||||
|
targetSize.setMax(Point2I::One);
|
||||||
|
|
||||||
// If we have an absolute target size then use that.
|
for (U32 c = 0; c < NumMRTTargets; c++)
|
||||||
if ( !mTargetSize.isZero() )
|
{
|
||||||
targetSize = mTargetSize;
|
if (mNamedTarget[c].isRegistered() || _outTexSlotFromName(mTargetName[c]) >= 0)
|
||||||
|
|
||||||
// Else generate a relative size using the target scale.
|
|
||||||
else if ( mActiveTextures[ 0 ] )
|
|
||||||
{
|
{
|
||||||
const Point3I &texSize = mActiveTextures[ 0 ]->getSize();
|
if (mNamedTarget[c].isRegistered() ||
|
||||||
|
!mTargetTex[c] ||
|
||||||
|
mTargetTex[c].getWidthHeight() != targetSize)
|
||||||
|
{
|
||||||
|
mTargetTex[c].set(targetSize.x, targetSize.y, mTargetFormat[c],
|
||||||
|
&PostFxTargetProfile, "PostEffect::_setupTarget", mMipCap);
|
||||||
|
|
||||||
targetSize.set( texSize.x * mTargetScale.x,
|
if (mTargetClear[c] == PFXTargetClear_OnCreate)
|
||||||
texSize.y * mTargetScale.y );
|
*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
|
||||||
|
{
|
||||||
|
mNamedTarget[c].setViewport(RectI(0, 0, targetSize.x, targetSize.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
mTargetTex[c] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool auxActive = false;
|
||||||
|
for (U32 c = 1; c < NumMRTTargets; c++)
|
||||||
|
{
|
||||||
|
if (mTargetTex[c].isValid())
|
||||||
{
|
{
|
||||||
GFXTarget *oldTarget = GFX->getActiveRenderTarget();
|
auxActive = true;
|
||||||
const Point2I &oldTargetSize = oldTarget->getSize();
|
break;
|
||||||
|
|
||||||
targetSize.set( oldTargetSize.x * mTargetScale.x,
|
|
||||||
oldTargetSize.y * mTargetScale.y );
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure its at least 1x1.
|
if (auxActive && !mTargetTex[0].isValid())
|
||||||
targetSize.setMax( Point2I::One );
|
{
|
||||||
|
/* If we have issues later on, uncomment this!
|
||||||
if ( mNamedTargetDepthStencil.isRegistered() &&
|
Con::warnf("PostEffect '%s': auxiliary MRT slots are active but target[0] "
|
||||||
mTargetDepthStencil.getWidthHeight() != targetSize )
|
"has no texture. Auto-promoting slot 0 to a temporary. "
|
||||||
{
|
"Use a named target (#name) on slot 0 for MRT setups.", getName());*/
|
||||||
mTargetDepthStencil.set( targetSize.x, targetSize.y, GFXFormatD24S8,
|
|
||||||
&GFXZTargetProfile, "PostEffect::_setupTarget" );
|
|
||||||
|
|
||||||
if ( mTargetClear == PFXTargetClear_OnCreate )
|
mTargetTex[0].set(targetSize.x, targetSize.y, mTargetFormat[0],
|
||||||
|
&PostFxTargetProfile, "PostEffect::MRTSlot[0]_auto", mMipCap);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNamedTargetDepthStencil.isRegistered())
|
||||||
|
{
|
||||||
|
if (mNamedTargetDepthStencil.isRegistered() && mTargetDepthStencil.getWidthHeight() != targetSize)
|
||||||
|
{
|
||||||
|
mTargetDepthStencil.set(targetSize.x, targetSize.y, GFXFormatD24S8,
|
||||||
|
&GFXZTargetProfile, "PostEffect::_setupTarget");
|
||||||
|
|
||||||
|
if (mTargetClear[0] == PFXTargetClear_OnCreate)
|
||||||
*outClearTarget = true;
|
*outClearTarget = true;
|
||||||
|
|
||||||
if(mTargetViewport == PFXTargetViewport_GFXViewport)
|
if (mTargetViewport == PFXTargetViewport_GFXViewport)
|
||||||
{
|
{
|
||||||
// We may need to scale the GFX viewport to fit within
|
// We may need to scale the GFX viewport to fit within
|
||||||
// our target texture size
|
// our target texture size
|
||||||
GFXTarget *oldTarget = GFX->getActiveRenderTarget();
|
GFXTarget* oldTarget = GFX->getActiveRenderTarget();
|
||||||
const Point2I &oldTargetSize = oldTarget->getSize();
|
const Point2I& oldTargetSize = oldTarget->getSize();
|
||||||
Point2F scale(targetSize.x / F32(oldTargetSize.x), targetSize.y / F32(oldTargetSize.y));
|
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
|
// 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));
|
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
|
else
|
||||||
{
|
{
|
||||||
// PFXTargetViewport_TargetSize
|
// PFXTargetViewport_TargetSize
|
||||||
mNamedTargetDepthStencil.setViewport( RectI( 0, 0, targetSize.x, targetSize.y ) );
|
mNamedTargetDepthStencil.setViewport(RectI(0, 0, targetSize.x, targetSize.y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mTargetDepthStencil = NULL;
|
mTargetDepthStencil = NULL;
|
||||||
|
|
||||||
if ( mTargetClear == PFXTargetClear_OnDraw )
|
if (mTargetClear[0] == PFXTargetClear_OnDraw)
|
||||||
*outClearTarget = true;
|
*outClearTarget = true;
|
||||||
|
|
||||||
if ( !mTarget && (mTargetTex || mTargetDepthStencil) )
|
bool hasAny = mTargetDepthStencil.isValid();
|
||||||
|
for (U32 c = 0; c < NumMRTTargets && !hasAny; c++)
|
||||||
|
hasAny = mTargetTex[c].isValid();
|
||||||
|
|
||||||
|
if (!mTarget && hasAny)
|
||||||
mTarget = GFX->allocRenderToTextureTarget();
|
mTarget = GFX->allocRenderToTextureTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostEffect::_cleanTargets( bool recurse )
|
void PostEffect::_cleanTargets( bool recurse )
|
||||||
{
|
{
|
||||||
mTargetTex = NULL;
|
for (U32 c = 0; c < NumMRTTargets; c++)
|
||||||
|
mTargetTex[c] = NULL;
|
||||||
|
|
||||||
mTargetDepthStencil = NULL;
|
mTargetDepthStencil = NULL;
|
||||||
mTarget = NULL;
|
mTarget = NULL;
|
||||||
|
|
||||||
|
|
@ -1406,9 +1413,10 @@ void PostEffect::_cleanTargets( bool recurse )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PostEffect::process( const SceneRenderState *state,
|
void PostEffect::process( const SceneRenderState* state,
|
||||||
GFXTexHandle &inOutTex,
|
GFXTexHandle* inOutTex,
|
||||||
const RectI *inTexViewport )
|
U32 inOutTexCount,
|
||||||
|
const RectI* inTexViewport)
|
||||||
{
|
{
|
||||||
// If the shader is forced to be skipped... then skip.
|
// If the shader is forced to be skipped... then skip.
|
||||||
if ( mSkip )
|
if ( mSkip )
|
||||||
|
|
@ -1444,11 +1452,16 @@ void PostEffect::process( const SceneRenderState *state,
|
||||||
}
|
}
|
||||||
GFXTransformSaver saver;
|
GFXTransformSaver saver;
|
||||||
|
|
||||||
|
GFXTexHandle chain[NumMRTTargets];
|
||||||
|
U32 texCount = getMin(inOutTexCount, (U32)NumMRTTargets);
|
||||||
|
for (U32 c = 0; c < texCount; c++)
|
||||||
|
chain[c] = inOutTex[c];
|
||||||
|
|
||||||
// Set the textures.
|
// Set the textures.
|
||||||
for (U32 i = 0; i < NumTextures; i++)
|
for (U32 i = 0; i < NumTextures; i++)
|
||||||
{
|
{
|
||||||
if (mTextureType[i] == NormalTextureType)
|
if (mTextureType[i] == NormalTextureType)
|
||||||
_setupTexture(i, inOutTex, inTexViewport);
|
_setupTexture(i, chain, texCount, inTexViewport);
|
||||||
else if (mTextureType[i] == CubemapType)
|
else if (mTextureType[i] == CubemapType)
|
||||||
_setupCubemapTexture(i, mCubemapTextures[i]);
|
_setupCubemapTexture(i, mCubemapTextures[i]);
|
||||||
else if (mTextureType[i] == CubemapArrayType)
|
else if (mTextureType[i] == CubemapArrayType)
|
||||||
|
|
@ -1461,27 +1474,57 @@ void PostEffect::process( const SceneRenderState *state,
|
||||||
bool clearTarget = false;
|
bool clearTarget = false;
|
||||||
_setupTarget( state, &clearTarget );
|
_setupTarget( state, &clearTarget );
|
||||||
|
|
||||||
if ( mTargetTex || mTargetDepthStencil )
|
const bool hasDepth = mTargetDepthStencil.isValid();
|
||||||
|
bool hasColorTarget = false;
|
||||||
|
|
||||||
|
U32 curTargetCount = 0;
|
||||||
|
for (U32 c = 0; c < NumMRTTargets; c++)
|
||||||
|
{
|
||||||
|
if (mTargetTex[c].isValid())
|
||||||
|
{
|
||||||
|
hasColorTarget = true;
|
||||||
|
curTargetCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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();
|
const RectI &oldViewport = GFX->getViewport();
|
||||||
GFXTarget *oldTarget = GFX->getActiveRenderTarget();
|
GFXTarget *oldTarget = GFX->getActiveRenderTarget();
|
||||||
|
|
||||||
GFX->pushActiveRenderTarget();
|
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.
|
// Set the right depth stencil target.
|
||||||
if ( !mTargetDepthStencil && mTargetTex.getWidthHeight() == GFX->getActiveRenderTarget()->getSize() )
|
if (!hasDepth && mTargetTex[0].isValid() && mTargetTex[0].getWidthHeight() == oldTarget->getSize())
|
||||||
mTarget->attachTexture( GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil );
|
mTarget->attachTexture(GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil);
|
||||||
else
|
else
|
||||||
mTarget->attachTexture( GFXTextureTarget::DepthStencil, mTargetDepthStencil );
|
mTarget->attachTexture(GFXTextureTarget::DepthStencil, mTargetDepthStencil);
|
||||||
|
|
||||||
// Set the render target but not its viewport. We'll do that below.
|
// Set the render target but not its viewport. We'll do that below.
|
||||||
GFX->setActiveRenderTarget( mTarget, false );
|
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[0].getViewport());
|
||||||
GFX->setViewport(mNamedTarget.getViewport());
|
}
|
||||||
|
else if (mTargetTex[0].isValid())
|
||||||
|
{
|
||||||
|
GFX->setViewport(RectI(Point2I::Zero, mTargetTex[0].getWidthHeight()));
|
||||||
}
|
}
|
||||||
else if(mTargetViewport == PFXTargetViewport_GFXViewport)
|
else if(mTargetViewport == PFXTargetViewport_GFXViewport)
|
||||||
{
|
{
|
||||||
|
|
@ -1509,8 +1552,19 @@ void PostEffect::process( const SceneRenderState *state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( clearTarget )
|
if (clearTarget)
|
||||||
GFX->clear( GFXClearTarget, mTargetClearColor, 1.f, 0 );
|
{
|
||||||
|
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.
|
// Setup the shader and constants.
|
||||||
if ( mShader )
|
if ( mShader )
|
||||||
|
|
@ -1545,35 +1599,36 @@ void PostEffect::process( const SceneRenderState *state,
|
||||||
// Allow PostEffecVis to hook in.
|
// Allow PostEffecVis to hook in.
|
||||||
PFXVIS->onPFXProcessed( this );
|
PFXVIS->onPFXProcessed( this );
|
||||||
|
|
||||||
if ( mTargetTex || mTargetDepthStencil )
|
if (hasColorTarget || hasDepth)
|
||||||
{
|
{
|
||||||
mTarget->resolve();
|
mTarget->resolve();
|
||||||
GFX->popActiveRenderTarget();
|
GFX->popActiveRenderTarget();
|
||||||
}
|
}
|
||||||
else
|
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();
|
PFXMGR->releaseBackBufferTex();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return and release our target texture.
|
for (U32 c = 0; c < NumMRTTargets; c++)
|
||||||
inOutTex = mTargetTex;
|
{
|
||||||
if ( !mNamedTarget.isRegistered() )
|
if (c < texCount)
|
||||||
mTargetTex = NULL;
|
chain[c] = mTargetTex[c];
|
||||||
|
|
||||||
|
if (!mNamedTarget[c].isRegistered())
|
||||||
|
mTargetTex[c] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Restore the transforms before the children
|
// Restore the transforms before the children
|
||||||
// are processed as it screws up the viewport.
|
// are processed as it screws up the viewport.
|
||||||
saver.restore();
|
saver.restore();
|
||||||
|
|
||||||
|
const U32 nextTexCount = getMax(getMax(texCount, curTargetCount), 1u);
|
||||||
// Now process my children.
|
// Now process my children.
|
||||||
iterator i = begin();
|
iterator i = begin();
|
||||||
for ( ; i != end(); i++ )
|
for ( ; i != end(); i++ )
|
||||||
{
|
{
|
||||||
PostEffect *effect = static_cast<PostEffect*>(*i);
|
PostEffect *effect = static_cast<PostEffect*>(*i);
|
||||||
effect->process( state, inOutTex );
|
effect->process( state, chain, nextTexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( mOneFrameOnly )
|
if ( mOneFrameOnly )
|
||||||
|
|
@ -1842,19 +1897,22 @@ void PostEffect::_checkRequirements()
|
||||||
}
|
}
|
||||||
|
|
||||||
// First make sure the target format is supported.
|
// First make sure the target format is supported.
|
||||||
if ( mNamedTarget.isRegistered() )
|
for (U32 c = 0; c < NumMRTTargets; c++)
|
||||||
{
|
{
|
||||||
Vector<GFXFormat> formats;
|
if (mNamedTarget[c].isRegistered())
|
||||||
formats.push_back( mTargetFormat );
|
{
|
||||||
GFXFormat format = GFX->selectSupportedFormat( &PostFxTargetProfile,
|
Vector<GFXFormat> formats;
|
||||||
formats,
|
formats.push_back(mTargetFormat[c]);
|
||||||
true,
|
GFXFormat format = GFX->selectSupportedFormat(&PostFxTargetProfile,
|
||||||
false,
|
formats,
|
||||||
false );
|
true,
|
||||||
|
false,
|
||||||
// If we didn't get our format out then its unsupported!
|
false);
|
||||||
if ( format != mTargetFormat )
|
|
||||||
return;
|
// If we didn't get our format out then its unsupported!
|
||||||
|
if (format != mTargetFormat[c])
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gather macros specified on this PostEffect.
|
// Gather macros specified on this PostEffect.
|
||||||
|
|
@ -1981,22 +2039,16 @@ void PostEffect::clearShaderMacros()
|
||||||
mUpdateShader = true;
|
mUpdateShader = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GFXTextureObject* PostEffect::_getTargetTexture( U32 )
|
GFXTextureObject* PostEffect::_getTargetTexture(U32 index)
|
||||||
{
|
{
|
||||||
// A TexGen PostEffect will generate its texture now if it
|
if (mRenderTime == PFXTexGenOnDemand
|
||||||
// has not already.
|
&& (!mTargetTex[index] || mUpdateShader))
|
||||||
if ( mRenderTime == PFXTexGenOnDemand &&
|
|
||||||
( !mTargetTex || mUpdateShader ) )
|
|
||||||
{
|
{
|
||||||
GFXTexHandle chainTex;
|
GFXTexHandle chainTex[NumMRTTargets]; // zero-initialised by GFXTexHandle ctor
|
||||||
process( NULL, chainTex );
|
process(NULL, chainTex, NumMRTTargets);
|
||||||
|
|
||||||
// TODO: We should add a conditional copy
|
|
||||||
// to a non-RT texture here to reduce the
|
|
||||||
// amount of non-swappable RTs in use.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mTargetTex.getPointer();
|
return mTargetTex[index].getPointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
DefineEngineMethod( PostEffect, reload, void, (),,
|
DefineEngineMethod( PostEffect, reload, void, (),,
|
||||||
|
|
|
||||||
|
|
@ -67,14 +67,6 @@ class Frustum;
|
||||||
class SceneRenderState;
|
class SceneRenderState;
|
||||||
class ConditionerFeature;
|
class ConditionerFeature;
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
GFX_DeclareTextureProfile( PostFxTargetProfile );
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
class PostEffect : public SimGroup
|
class PostEffect : public SimGroup
|
||||||
{
|
{
|
||||||
typedef SimGroup Parent;
|
typedef SimGroup Parent;
|
||||||
|
|
@ -86,389 +78,318 @@ public:
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
NumTextures = 16,
|
NumTextures = 16,
|
||||||
|
|
||||||
|
/// Maximum simultaneous color render target outputs (MRT)
|
||||||
|
NumMRTTargets = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Input textures
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
DECLARE_IMAGEASSET_ARRAY(PostEffect, Texture, GFXStaticTextureSRGBProfile, NumTextures);
|
DECLARE_IMAGEASSET_ARRAY(PostEffect, Texture, GFXStaticTextureSRGBProfile, NumTextures);
|
||||||
GFXTextureProfile* mTextureProfile[NumTextures];
|
GFXTextureProfile* mTextureProfile[NumTextures];
|
||||||
GFXTexHandle mTexture[NumTextures];
|
GFXTexHandle mTexture[NumTextures];
|
||||||
|
bool mTexSRGB[NumTextures];
|
||||||
|
|
||||||
bool mTexSRGB[NumTextures];
|
enum { NormalTextureType = 0, CubemapType, CubemapArrayType } mTextureType[NumTextures];
|
||||||
|
|
||||||
enum
|
GFXCubemapHandle mCubemapTextures[NumTextures];
|
||||||
{
|
|
||||||
NormalTextureType = 0,
|
|
||||||
CubemapType,
|
|
||||||
CubemapArrayType,
|
|
||||||
} mTextureType[NumTextures];
|
|
||||||
|
|
||||||
GFXCubemapHandle mCubemapTextures[NumTextures];
|
|
||||||
GFXCubemapArrayHandle mCubemapArrayTextures[NumTextures];
|
GFXCubemapArrayHandle mCubemapArrayTextures[NumTextures];
|
||||||
|
|
||||||
NamedTexTarget mNamedTarget;
|
GFXTextureObject* mActiveTextures[NumTextures];
|
||||||
NamedTexTarget mNamedTargetDepthStencil;
|
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;
|
// These remain single values — shared across ALL active MRT slots.
|
||||||
|
Point2F mTargetScale; ///< Relative size vs current GFX render target.
|
||||||
GFXStateBlockRef mStateBlock;
|
Point2I mTargetSize; ///< Absolute size override; (0,0) = use mTargetScale.
|
||||||
|
PFXTargetViewport mTargetViewport; ///< How the viewport rect is derived.
|
||||||
String mShaderName;
|
|
||||||
|
|
||||||
GFXShaderRef mShader;
|
|
||||||
|
|
||||||
Vector<GFXShaderMacro> 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;
|
|
||||||
|
|
||||||
|
/// Single GFXTextureTarget — ALL active MRT slots attach to this one object.
|
||||||
GFXTextureTargetRef mTarget;
|
GFXTextureTargetRef mTarget;
|
||||||
|
|
||||||
String mTargetName;
|
|
||||||
GFXTexHandle mTargetTex;
|
|
||||||
S32 mMipCap;
|
S32 mMipCap;
|
||||||
|
|
||||||
String mTargetDepthStencilName;
|
//--------------------------------------------------------------------------
|
||||||
GFXTexHandle mTargetDepthStencil;
|
// Depth stencil
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
/// If mTargetSize is zero then this scale is
|
String mTargetDepthStencilName;
|
||||||
/// used to make a relative texture size to the
|
GFXTexHandle mTargetDepthStencil;
|
||||||
/// active render target.
|
NamedTexTarget mNamedTargetDepthStencil;
|
||||||
Point2F mTargetScale;
|
|
||||||
|
|
||||||
/// If non-zero this is used as the absolute
|
//--------------------------------------------------------------------------
|
||||||
/// texture target size.
|
// State block / shader
|
||||||
/// @see mTargetScale
|
//--------------------------------------------------------------------------
|
||||||
Point2I mTargetSize;
|
|
||||||
|
|
||||||
GFXFormat mTargetFormat;
|
GFXStateBlockData* mStateBlockData;
|
||||||
|
GFXStateBlockRef mStateBlock;
|
||||||
|
String mShaderName;
|
||||||
|
GFXShaderRef mShader;
|
||||||
|
Vector<GFXShaderMacro> mShaderMacros;
|
||||||
|
GFXShaderConstBufferRef mShaderConsts;
|
||||||
|
|
||||||
/// The color to prefill the named target when
|
//--------------------------------------------------------------------------
|
||||||
/// first created by the effect.
|
// Auto shader constant handles
|
||||||
LinearColorF mTargetClearColor;
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
|
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;
|
PFXRenderTime mRenderTime;
|
||||||
PFXTargetClear mTargetClear;
|
PFXTargetClear mTargetClear_unused; // kept for binary compat if needed — see arrays above
|
||||||
PFXTargetViewport mTargetViewport;
|
String mRenderBin;
|
||||||
|
S16 mRenderPriority;
|
||||||
|
bool mIsValid;
|
||||||
|
bool mEnabled;
|
||||||
|
bool mSkip;
|
||||||
|
bool mPreProcessed;
|
||||||
|
bool mOneFrameOnly;
|
||||||
|
bool mOnThisFrame;
|
||||||
|
U32 mShaderReloadKey;
|
||||||
|
|
||||||
String mRenderBin;
|
//--------------------------------------------------------------------------
|
||||||
|
// EffectConst
|
||||||
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;
|
|
||||||
|
|
||||||
class EffectConst
|
class EffectConst
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
EffectConst(const String& name, const String& val)
|
||||||
EffectConst( const String &name, const String &val )
|
: mName(name), mHandle(NULL), mDirty(true) {
|
||||||
: mName( name ),
|
set(val);
|
||||||
mHandle( NULL ),
|
}
|
||||||
mDirty( true )
|
EffectConst(const String& name, const F32& val)
|
||||||
{
|
: mName(name), mHandle(NULL), mDirty(true) {
|
||||||
set( val );
|
|
||||||
}
|
|
||||||
|
|
||||||
EffectConst(const String &name, const F32 &val)
|
|
||||||
: mName(name),
|
|
||||||
mHandle(NULL),
|
|
||||||
mDirty(true)
|
|
||||||
{
|
|
||||||
set(val);
|
set(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
EffectConst(const String& name, const int& val)
|
EffectConst(const String& name, const int& val)
|
||||||
: mName(name),
|
: mName(name), mHandle(NULL), mDirty(true) {
|
||||||
mHandle(NULL),
|
set(val);
|
||||||
mDirty(true)
|
}
|
||||||
{
|
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<Point4F>& val)
|
||||||
|
: mName(name), mHandle(NULL), mDirty(true) {
|
||||||
|
set(val);
|
||||||
|
}
|
||||||
|
EffectConst(const String& name, const Vector<MatrixF>& val)
|
||||||
|
: mName(name), mHandle(NULL), mDirty(true) {
|
||||||
set(val);
|
set(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
EffectConst(const String &name, const Point4F &val)
|
void set(const String& newVal);
|
||||||
: mName(name),
|
void set(const F32& newVal);
|
||||||
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<Point4F> &val)
|
|
||||||
: mName(name),
|
|
||||||
mHandle(NULL),
|
|
||||||
mDirty(true)
|
|
||||||
{
|
|
||||||
set(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
EffectConst(const String &name, const Vector<MatrixF> &val)
|
|
||||||
: mName(name),
|
|
||||||
mHandle(NULL),
|
|
||||||
mDirty(true)
|
|
||||||
{
|
|
||||||
set(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set( const String &newVal );
|
|
||||||
void set(const F32 &newVal);
|
|
||||||
void set(const int& newVal);
|
void set(const int& newVal);
|
||||||
void set(const Point4F &newVal);
|
void set(const Point4F& newVal);
|
||||||
void set(const MatrixF &newVal);
|
void set(const MatrixF& newVal);
|
||||||
void set(const Vector<Point4F> &newVal);
|
void set(const Vector<Point4F>& newVal);
|
||||||
void set(const Vector<MatrixF> &newVal);
|
void set(const Vector<MatrixF>& newVal);
|
||||||
|
void setToBuffer(GFXShaderConstBufferRef buff);
|
||||||
void setToBuffer( GFXShaderConstBufferRef buff );
|
|
||||||
|
|
||||||
String mName;
|
|
||||||
|
|
||||||
GFXShaderConstHandle *mHandle;
|
|
||||||
|
|
||||||
String mStringVal;
|
|
||||||
|
|
||||||
S32 mIntVal;
|
|
||||||
F32 mFloatVal;
|
|
||||||
Point4F mPointVal;
|
|
||||||
MatrixF mMatrixVal;
|
|
||||||
|
|
||||||
|
String mName;
|
||||||
|
GFXShaderConstHandle* mHandle;
|
||||||
|
String mStringVal;
|
||||||
|
S32 mIntVal;
|
||||||
|
F32 mFloatVal;
|
||||||
|
Point4F mPointVal;
|
||||||
|
MatrixF mMatrixVal;
|
||||||
Vector<Point4F> mPointArrayVal;
|
Vector<Point4F> mPointArrayVal;
|
||||||
Vector<MatrixF> mMatrixArrayVal;
|
Vector<MatrixF> mMatrixArrayVal;
|
||||||
|
|
||||||
enum
|
enum {
|
||||||
{
|
StringType, IntType, FloatType, PointType,
|
||||||
StringType,
|
MatrixType, PointArrayType, MatrixArrayType
|
||||||
IntType,
|
|
||||||
FloatType,
|
|
||||||
PointType,
|
|
||||||
MatrixType,
|
|
||||||
PointArrayType,
|
|
||||||
MatrixArrayType
|
|
||||||
} mValueType;
|
} mValueType;
|
||||||
|
|
||||||
bool mDirty;
|
bool mDirty;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef HashTable<StringCase,EffectConst*> EffectConstTable;
|
typedef HashTable<StringCase, EffectConst*> EffectConstTable;
|
||||||
|
|
||||||
EffectConstTable mEffectConsts;
|
EffectConstTable mEffectConsts;
|
||||||
|
|
||||||
///
|
//--------------------------------------------------------------------------
|
||||||
virtual void _updateScreenGeometry( const Frustum &frustum,
|
// Internal methods
|
||||||
GFXVertexBufferHandle<PFXVertex> *outVB );
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
///
|
virtual void _updateScreenGeometry(const Frustum& frustum, GFXVertexBufferHandle<PFXVertex>* outVB);
|
||||||
virtual void _setupStateBlock( const SceneRenderState *state );
|
virtual void _setupStateBlock(const SceneRenderState* state);
|
||||||
|
virtual void _setupConstants(const SceneRenderState* state);
|
||||||
///
|
|
||||||
virtual void _setupConstants( const SceneRenderState *state );
|
|
||||||
|
|
||||||
///
|
|
||||||
virtual void _setupTransforms();
|
virtual void _setupTransforms();
|
||||||
|
virtual void _setupTarget(const SceneRenderState* state, bool* outClearTarget);
|
||||||
|
virtual void _setupTexture(U32 stage, GFXTexHandle* inputTex, U32 inputTexCount, const RectI* inTexViewport);
|
||||||
|
virtual void _setupCubemapTexture(U32 stage, GFXCubemapHandle& inputTex);
|
||||||
|
virtual void _setupCubemapArrayTexture(U32 slot, GFXCubemapArrayHandle& inputTex);
|
||||||
|
|
||||||
///
|
static bool _setIsEnabled(void* object, const char* index, const char* data);
|
||||||
virtual void _setupTarget( const SceneRenderState *state, bool *outClearTarget );
|
|
||||||
|
|
||||||
///
|
void _onLMActivate(const char*, bool activate)
|
||||||
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 )
|
|
||||||
{
|
{
|
||||||
if ( activate )
|
if (activate) mUpdateShader = true;
|
||||||
mUpdateShader = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We handle texture events to release named rendered targets.
|
void _onTextureEvent(GFXTexCallbackCode code)
|
||||||
/// @see GFXTextureManager::addEventDelegate
|
|
||||||
void _onTextureEvent( GFXTexCallbackCode code )
|
|
||||||
{
|
{
|
||||||
if ( code == GFXZombify && (mNamedTarget.isRegistered() || mNamedTargetDepthStencil.isRegistered()) )
|
if (code != GFXZombify) return;
|
||||||
_cleanTargets();
|
bool anyNamed = mNamedTargetDepthStencil.isRegistered();
|
||||||
|
for (U32 c = 0; c < NumMRTTargets && !anyNamed; c++)
|
||||||
|
anyNamed = mNamedTarget[c].isRegistered();
|
||||||
|
if (anyNamed) _cleanTargets();
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
void _updateConditioners();
|
void _updateConditioners();
|
||||||
|
void _cleanTargets(bool recurse = false);
|
||||||
///
|
|
||||||
void _cleanTargets( bool recurse = false );
|
|
||||||
|
|
||||||
///
|
|
||||||
void _checkRequirements();
|
void _checkRequirements();
|
||||||
|
GFXTextureObject* _getTargetTexture(U32 index);
|
||||||
|
|
||||||
///
|
/// Map "$outTex" / "$outTex0".."$outTex3" to a slot index [0..NumMRTTargets-1].
|
||||||
GFXTextureObject* _getTargetTexture( U32 index );
|
/// 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:
|
public:
|
||||||
|
|
||||||
/// Constructor.
|
|
||||||
PostEffect();
|
PostEffect();
|
||||||
|
|
||||||
/// Destructor.
|
|
||||||
virtual ~PostEffect();
|
virtual ~PostEffect();
|
||||||
|
|
||||||
DECLARE_CONOBJECT(PostEffect);
|
DECLARE_CONOBJECT(PostEffect);
|
||||||
|
|
||||||
// SimObject
|
|
||||||
bool onAdd() override;
|
bool onAdd() override;
|
||||||
void onRemove() override;
|
void onRemove() override;
|
||||||
static void initPersistFields();
|
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, () );
|
virtual void process(const SceneRenderState* state,
|
||||||
DECLARE_CALLBACK( void, preProcess, () );
|
GFXTexHandle* inOutTex,
|
||||||
DECLARE_CALLBACK( void, setShaderConsts, () );
|
U32 inOutTexCount = 1,
|
||||||
DECLARE_CALLBACK( bool, onEnabled, () );
|
const RectI* inTexViewport = NULL);
|
||||||
DECLARE_CALLBACK( void, onDisabled, () );
|
|
||||||
|
|
||||||
/// @}
|
|
||||||
|
|
||||||
virtual void process( const SceneRenderState *state,
|
|
||||||
GFXTexHandle &inOutTex,
|
|
||||||
const RectI *inTexViewport = NULL );
|
|
||||||
|
|
||||||
///
|
|
||||||
void reload();
|
void reload();
|
||||||
|
|
||||||
///
|
|
||||||
void enable();
|
void enable();
|
||||||
|
|
||||||
///
|
|
||||||
void disable();
|
void disable();
|
||||||
|
|
||||||
/// Dump the shader disassembly to a temporary text file.
|
bool dumpShaderDisassembly(String& outFilename) const;
|
||||||
/// Returns true and sets outFilename to the file if successful.
|
|
||||||
bool dumpShaderDisassembly( String &outFilename ) const;
|
|
||||||
|
|
||||||
/// Returns the SimSet which contains all PostEffects.
|
|
||||||
SimSet* getSet() const;
|
SimSet* getSet() const;
|
||||||
|
|
||||||
///
|
|
||||||
bool isEnabled() const { return mEnabled; }
|
bool isEnabled() const { return mEnabled; }
|
||||||
|
|
||||||
/// Is set to skip rendering.
|
|
||||||
bool isSkipped() const { return mSkip; }
|
bool isSkipped() const { return mSkip; }
|
||||||
|
void setSkip(bool s) { mSkip = s; }
|
||||||
/// Set the effect to skip rendering.
|
|
||||||
void setSkip( bool skip ) { mSkip = skip; }
|
|
||||||
|
|
||||||
PFXRenderTime getRenderTime() const { return mRenderTime; }
|
PFXRenderTime getRenderTime() const { return mRenderTime; }
|
||||||
|
const String& getRenderBin() const { return mRenderBin; }
|
||||||
|
F32 getPriority() const { return mRenderPriority; }
|
||||||
|
|
||||||
const String& getRenderBin() const { return mRenderBin; }
|
void setTexture(U32 index, const String& filePath);
|
||||||
|
|
||||||
F32 getPriority() const { return mRenderPriority; }
|
|
||||||
|
|
||||||
void setTexture( U32 index, const String &filePath );
|
|
||||||
void setTexture(U32 index, const GFXTexHandle& texHandle);
|
void setTexture(U32 index, const GFXTexHandle& texHandle);
|
||||||
void setCubemapTexture(U32 index, const GFXCubemapHandle &cubemapHandle);
|
void setCubemapTexture(U32 index, const GFXCubemapHandle& handle);
|
||||||
void setCubemapArrayTexture(U32 index, const GFXCubemapArrayHandle &cubemapArrayHandle);
|
void setCubemapArrayTexture(U32 index, const GFXCubemapArrayHandle& handle);
|
||||||
|
|
||||||
void setShaderMacro( const String &name, const String &value = String::EmptyString );
|
void setShaderMacro(const String& name, const String& value = String::EmptyString);
|
||||||
bool removeShaderMacro( const String &name );
|
bool removeShaderMacro(const String& name);
|
||||||
void clearShaderMacros();
|
void clearShaderMacros();
|
||||||
|
|
||||||
///
|
void setShaderConst(const String& name, const String& val);
|
||||||
void setShaderConst( const String &name, const String &val );
|
void setShaderConst(const String& name, const F32& val);
|
||||||
void setShaderConst(const String &name, const F32 &val);
|
|
||||||
void setShaderConst(const String& name, const int& val);
|
void setShaderConst(const String& name, const int& val);
|
||||||
void setShaderConst(const String &name, const Point4F &val);
|
void setShaderConst(const String& name, const Point4F& val);
|
||||||
void setShaderConst(const String &name, const MatrixF &val);
|
void setShaderConst(const String& name, const MatrixF& val);
|
||||||
void setShaderConst(const String &name, const Vector<Point4F> &val);
|
void setShaderConst(const String& name, const Vector<Point4F>& val);
|
||||||
void setShaderConst(const String &name, const Vector<MatrixF> &val);
|
void setShaderConst(const String& name, const Vector<MatrixF>& val);
|
||||||
|
|
||||||
void setOnThisFrame( bool enabled ) { mOnThisFrame = enabled; }
|
void setOnThisFrame(bool e) { mOnThisFrame = e; }
|
||||||
bool isOnThisFrame() { return mOnThisFrame; }
|
bool isOnThisFrame() { return mOnThisFrame; }
|
||||||
void setOneFrameOnly( bool enabled ) { mOneFrameOnly = enabled; }
|
void setOneFrameOnly(bool e) { mOneFrameOnly = e; }
|
||||||
bool isOneFrameOnly() { return mOneFrameOnly; }
|
bool isOneFrameOnly() { return mOneFrameOnly; }
|
||||||
|
|
||||||
F32 getAspectRatio() const;
|
F32 getAspectRatio() const;
|
||||||
|
GFXShaderRef getShader() { return mShader; }
|
||||||
GFXShaderRef getShader() { return mShader; }
|
|
||||||
Vector<GFXShaderMacro>* getShaderMacros() { return &mShaderMacros; }
|
Vector<GFXShaderMacro>* getShaderMacros() { return &mShaderMacros; }
|
||||||
GFXShaderConstBufferRef getShaderConstBuffer() { return mShaderConsts; }
|
GFXShaderConstBufferRef getShaderConstBuffer() { return mShaderConsts; }
|
||||||
|
|
||||||
|
|
||||||
enum PostEffectRequirements
|
enum PostEffectRequirements
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -99,11 +99,10 @@ struct PFXFrameState
|
||||||
};
|
};
|
||||||
|
|
||||||
///
|
///
|
||||||
|
GFX_DeclareTextureProfile( PostFxTargetProfile) ;
|
||||||
GFX_DeclareTextureProfile( PostFxTextureProfile );
|
GFX_DeclareTextureProfile( PostFxTextureProfile );
|
||||||
GFX_DeclareTextureProfile( PostFxTextureSRGBProfile );
|
GFX_DeclareTextureProfile( PostFxTextureSRGBProfile );
|
||||||
|
|
||||||
GFX_DeclareTextureProfile( VRTextureProfile );
|
GFX_DeclareTextureProfile( VRTextureProfile );
|
||||||
|
|
||||||
GFX_DeclareTextureProfile( VRDepthProfile );
|
GFX_DeclareTextureProfile( VRDepthProfile );
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
@ -119,4 +118,4 @@ GFXDeclareVertexFormat( PFXVertex )
|
||||||
Point3F wsEyeRay;
|
Point3F wsEyeRay;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _POSTEFFECTCOMMON_H_
|
#endif // _POSTEFFECTCOMMON_H_
|
||||||
|
|
|
||||||
|
|
@ -284,14 +284,14 @@ void PostEffectManager::renderEffects( const SceneRenderState *state,
|
||||||
|
|
||||||
// This is used to pass the output texture
|
// This is used to pass the output texture
|
||||||
// of one effect into the next effect.
|
// of one effect into the next effect.
|
||||||
GFXTexHandle chainTex;
|
GFXTexHandle chainTex[PostEffect::NumMRTTargets];
|
||||||
|
|
||||||
// Process the effects.
|
// Process the effects.
|
||||||
for ( U32 i = 0; i < effects->size(); i++ )
|
for ( U32 i = 0; i < effects->size(); i++ )
|
||||||
{
|
{
|
||||||
PostEffect *effect = (*effects)[i];
|
PostEffect *effect = (*effects)[i];
|
||||||
AssertFatal( effect != NULL, "Somehow this happened" );
|
AssertFatal( effect != NULL, "Somehow this happened" );
|
||||||
effect->process( state, chainTex );
|
effect->process(state, chainTex, PostEffect::NumMRTTargets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ void PostEffectVis::open( PostEffect *pfx )
|
||||||
// Only allocate window/bitmaps for input textures that are actually used.
|
// Only allocate window/bitmaps for input textures that are actually used.
|
||||||
if ( i > Target )
|
if ( i > Target )
|
||||||
{
|
{
|
||||||
if ( pfx->mTextureAsset[i-1].notNull() && pfx->mTextureAsset[i - 1]->getImageFile() == StringTable->EmptyString())
|
if ( pfx->mTextureAsset[i-1].isNull())
|
||||||
{
|
{
|
||||||
window.window[i] = NULL;
|
window.window[i] = NULL;
|
||||||
window.bmp[i] = NULL;
|
window.bmp[i] = NULL;
|
||||||
|
|
@ -197,7 +197,7 @@ void PostEffectVis::onStartOfFrame()
|
||||||
if ( !itr->bmp[i] || itr->pfx->getRenderTime() == PFXTexGenOnDemand )
|
if ( !itr->bmp[i] || itr->pfx->getRenderTime() == PFXTexGenOnDemand )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
itr->bmp[i]->setBitmap( NULL );
|
itr->bmp[i]->setBitmap( "");
|
||||||
_setDefaultCaption( *itr, i );
|
_setDefaultCaption( *itr, i );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -225,32 +225,32 @@ void PostEffectVis::onPFXProcessed( PostEffect *pfx )
|
||||||
{
|
{
|
||||||
pBmpCtrl = itr->bmp[Target];
|
pBmpCtrl = itr->bmp[Target];
|
||||||
pWinCtrl = itr->window[Target];
|
pWinCtrl = itr->window[Target];
|
||||||
|
String caption;
|
||||||
|
|
||||||
GFXTextureObject *tex;
|
for (U32 c = 0; c < PostEffect::NumMRTTargets; c++)
|
||||||
|
{
|
||||||
|
GFXTextureObject* tex;
|
||||||
|
|
||||||
if ( pfx->mTargetTex )
|
if (pfx->mTargetTex[c])
|
||||||
tex = pfx->mTargetTex;
|
tex = pfx->mTargetTex[c];
|
||||||
else
|
else
|
||||||
tex = PFXMGR->getBackBufferTex();
|
tex = PFXMGR->getBackBufferTex();
|
||||||
|
|
||||||
pBmpCtrl->setBitmapHandle( tex );
|
pBmpCtrl->setBitmapHandle(tex);
|
||||||
|
|
||||||
char caption[256];
|
if (pfx->getName() == NULL || dStrlen(pfx->getName()) == 0)
|
||||||
char name[256];
|
caption += "(none)";
|
||||||
|
else
|
||||||
if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 )
|
caption += String::ToString(pfx->getName());
|
||||||
dSprintf( name, 256, "(none)" );
|
|
||||||
else
|
|
||||||
dSprintf( name, 256, "%s", pfx->getName() );
|
|
||||||
|
|
||||||
|
|
||||||
if ( tex )
|
if (tex)
|
||||||
dSprintf( caption, 256, "%s[%i] target - %s [ %ix%i ]", name, pfx->getId(), pfx->mTargetName.c_str(), tex->getWidth(), tex->getHeight() );
|
caption += String::ToString("[%i] target - %s [ %ix%i ]", pfx->getId(), pfx->mTargetName[c].c_str(), tex->getWidth(), tex->getHeight());
|
||||||
else
|
else
|
||||||
dSprintf( caption, 256, "%s[%i] target", name, pfx->getId() );
|
caption += String::ToString("[%i] target", pfx->getId());
|
||||||
|
}
|
||||||
|
|
||||||
pWinCtrl->setDataField( StringTable->insert("text"), NULL, caption );
|
pWinCtrl->setDataField( StringTable->insert("text"), NULL, caption.c_str() );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( U32 i = Input1; i < TexCount; i++ )
|
for ( U32 i = Input1; i < TexCount; i++ )
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ void RenderFormatToken::process(SceneRenderState *state, RenderPassStateBin *cal
|
||||||
|
|
||||||
// Run the PostEffect which copies data into the new target.
|
// Run the PostEffect which copies data into the new target.
|
||||||
if ( mCopyPostEffect.isValid() )
|
if ( mCopyPostEffect.isValid() )
|
||||||
mCopyPostEffect->process( state, curBackBuffer, &mTarget.getViewport() );
|
mCopyPostEffect->process( state, &curBackBuffer,1, &mTarget.getViewport() );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -174,7 +174,7 @@ void RenderFormatToken::process(SceneRenderState *state, RenderPassStateBin *cal
|
||||||
{
|
{
|
||||||
// Need to create a texhandle here, since inOutTex gets assigned during process()
|
// Need to create a texhandle here, since inOutTex gets assigned during process()
|
||||||
GFXTexHandle inOutTex = mTargetColorTexture[mTargetChainIdx];
|
GFXTexHandle inOutTex = mTargetColorTexture[mTargetChainIdx];
|
||||||
mResolvePostEffect->process( state, inOutTex, &mTarget.getViewport() );
|
mResolvePostEffect->process( state, &inOutTex, 1, &mTarget.getViewport() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue