From 1edfbcf44776598018751563a5d05ea5b072ce70 Mon Sep 17 00:00:00 2001 From: marauder2k7 Date: Sat, 14 Dec 2024 13:37:23 +0000 Subject: [PATCH] fixes for reload and flush --- Engine/source/T3D/assets/ImageAsset.cpp | 10 ++--- Engine/source/T3D/assets/ImageAsset.h | 14 ++----- .../source/materials/materialDefinition.cpp | 5 +++ Engine/source/materials/materialDefinition.h | 4 +- Engine/source/materials/materialManager.cpp | 41 +++++++++++++++++-- Engine/source/materials/materialManager.h | 15 +++++-- Engine/source/materials/processedMaterial.cpp | 38 +++++++++++------ 7 files changed, 88 insertions(+), 39 deletions(-) diff --git a/Engine/source/T3D/assets/ImageAsset.cpp b/Engine/source/T3D/assets/ImageAsset.cpp index 8808d40e6..25520e138 100644 --- a/Engine/source/T3D/assets/ImageAsset.cpp +++ b/Engine/source/T3D/assets/ImageAsset.cpp @@ -377,12 +377,10 @@ GFXTexHandle ImageAsset::getTexture(GFXTextureProfile* requestedProfile) NamedTexTargetRef namedTarget = NamedTexTarget::find(mImageFileName + 1); if (namedTarget.isValid() && namedTarget->getTexture()) { - if (mNamedTarget == NULL) { - mNamedTarget = namedTarget; - mResourceMap.insert(requestedProfile, mNamedTarget->getTexture()); - mIsValidImage = true; - mChangeSignal.trigger(); - } + mNamedTarget = namedTarget; + mIsValidImage = true; + mResourceMap.insert(requestedProfile, mNamedTarget->getTexture()); + mChangeSignal.trigger(); } if (mNamedTarget == NULL) return nullptr; diff --git a/Engine/source/T3D/assets/ImageAsset.h b/Engine/source/T3D/assets/ImageAsset.h index 850032909..169bf0cdf 100644 --- a/Engine/source/T3D/assets/ImageAsset.h +++ b/Engine/source/T3D/assets/ImageAsset.h @@ -212,7 +212,7 @@ public: \ else if(_in[0] == '$' || _in[0] == '#')\ {\ m##name##Name = _in;\ - m##name##AssetId = _in;\ + m##name##AssetId = StringTable->EmptyString();\ m##name##Asset = NULL;\ m##name.free();\ m##name = NULL;\ @@ -256,15 +256,9 @@ public: \ m##name##Asset->getChangedSignal().notify(this, &className::changeFunc);\ }\ \ - if (get##name()[0] == '$' || get##name()[0] == '#') {\ - NamedTexTargetRef namedTarget = NamedTexTarget::find(get##name() + 1);\ - if (namedTarget.isValid())\ - {\ - m##name = namedTarget->getTexture(0);\ - }\ + if (get##name()[0] != '$' && get##name()[0] != '#') {\ + m##name.set(get##name(), m##name##Profile, avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__));\ }\ - else\ - m##name.set(get##name(), m##name##Profile, avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__));\ }\ else\ {\ @@ -373,7 +367,7 @@ public: \ else if(_in[0] == '$' || _in[0] == '#')\ {\ m##name##Name[index] = _in;\ - m##name##AssetId[index] = _in;\ + m##name##AssetId[index] = StringTable->EmptyString();\ m##name##Asset[index] = NULL;\ m##name[index].free();\ m##name[index] = NULL;\ diff --git a/Engine/source/materials/materialDefinition.cpp b/Engine/source/materials/materialDefinition.cpp index 8c5201b47..feb23c81c 100644 --- a/Engine/source/materials/materialDefinition.cpp +++ b/Engine/source/materials/materialDefinition.cpp @@ -243,6 +243,10 @@ Material::Material() mReverbSoundOcclusion = 1.0; } +void Material::onImageAssetChanged() +{ + reload(); +} void Material::initPersistFields() { @@ -857,3 +861,4 @@ DEF_IMAGEASSET_ARRAY_BINDS(Material, AOMap); DEF_IMAGEASSET_ARRAY_BINDS(Material, MetalMap); DEF_IMAGEASSET_ARRAY_BINDS(Material, GlowMap); DEF_IMAGEASSET_ARRAY_BINDS(Material, DetailNormalMap); + diff --git a/Engine/source/materials/materialDefinition.h b/Engine/source/materials/materialDefinition.h index 7d4b78108..e17bdd317 100644 --- a/Engine/source/materials/materialDefinition.h +++ b/Engine/source/materials/materialDefinition.h @@ -208,9 +208,7 @@ public: //----------------------------------------------------------------------- // Data //----------------------------------------------------------------------- - void onImageAssetChanged() { - reload(); - } + void onImageAssetChanged(); DECLARE_IMAGEASSET_ARRAY(Material, DiffuseMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, DiffuseMap); diff --git a/Engine/source/materials/materialManager.cpp b/Engine/source/materials/materialManager.cpp index d2979d8eb..87ce2bef2 100644 --- a/Engine/source/materials/materialManager.cpp +++ b/Engine/source/materials/materialManager.cpp @@ -61,6 +61,8 @@ MaterialManager::MaterialManager() mLastTime = 0; mDampness = 0.0f; mWarningInst = NULL; + mMatDefToFlush = NULL; + mMatDefToReload = NULL; GFXDevice::getDeviceEventSignal().notify( this, &MaterialManager::_handleGFXEvent ); @@ -73,6 +75,8 @@ MaterialManager::MaterialManager() mUsingDeferred = false; mFlushAndReInit = false; + mMatDefShouldFlush = false; + mMatDefShouldReload = false; mDefaultAnisotropy = 1; Con::addVariable( "$pref::Video::defaultAnisotropy", TypeS32, &mDefaultAnisotropy, @@ -324,6 +328,12 @@ String MaterialManager::getMapEntry(const String & textureName) const } void MaterialManager::flushAndReInitInstances() +{ + // delay flushes and reinits until the start of the next frame. + mFlushAndReInit = true; +} + +void MaterialManager::_flushAndReInitInstances() { // Clear the flag if its set. mFlushAndReInit = false; @@ -359,8 +369,15 @@ void MaterialManager::flushAndReInitInstances() } // Used in the materialEditor. This flushes the material preview object so it can be reloaded easily. -void MaterialManager::flushInstance( BaseMaterialDefinition *target ) +void MaterialManager::flushInstance(BaseMaterialDefinition* target) { + mMatDefToFlush = target; + mMatDefShouldFlush = true; +} + +void MaterialManager::_flushInstance( BaseMaterialDefinition *target ) +{ + mMatDefShouldFlush = false; Vector::iterator iter = mMatInstanceList.begin(); while ( iter != mMatInstanceList.end() ) { @@ -371,16 +388,26 @@ void MaterialManager::flushInstance( BaseMaterialDefinition *target ) } iter++; } + + mMatDefToFlush = NULL; } -void MaterialManager::reInitInstance( BaseMaterialDefinition *target ) +void MaterialManager::reInitInstance(BaseMaterialDefinition* target) { + mMatDefToReload = target; + mMatDefShouldReload = true; +} + +void MaterialManager::_reInitInstance( BaseMaterialDefinition *target ) +{ + mMatDefShouldReload = false; Vector::iterator iter = mMatInstanceList.begin(); for ( ; iter != mMatInstanceList.end(); iter++ ) { if ( (*iter)->getMaterial() == target ) (*iter)->reInit(); } + mMatDefToReload = NULL; } void MaterialManager::updateTime() @@ -499,7 +526,15 @@ bool MaterialManager::_handleGFXEvent( GFXDevice::GFXDeviceEventType event_ ) case GFXDevice::deStartOfFrame: if ( mFlushAndReInit ) - flushAndReInitInstances(); + _flushAndReInitInstances(); + if (mMatDefShouldFlush) + { + _flushInstance(mMatDefToFlush); + } + if (mMatDefShouldReload) + { + _reInitInstance(mMatDefToReload); + } break; default: diff --git a/Engine/source/materials/materialManager.h b/Engine/source/materials/materialManager.h index 6f1889c26..2d983da7a 100644 --- a/Engine/source/materials/materialManager.h +++ b/Engine/source/materials/materialManager.h @@ -116,11 +116,7 @@ public: /// Returns the signal used to notify systems that the /// procedural shaders have been flushed. FlushSignal& getFlushSignal() { return mFlushSignal; } - - /// Flushes all the procedural shaders and re-initializes all - /// the active materials instances immediately. void flushAndReInitInstances(); - // Flush the instance void flushInstance( BaseMaterialDefinition *target ); @@ -133,7 +129,14 @@ protected: friend class MatInstance; void _track(MatInstance*); void _untrack(MatInstance*); + /// Flushes all the procedural shaders and re-initializes all + /// the active materials instances immediately. + void _flushAndReInitInstances(); + // Flush the instance + void _flushInstance(BaseMaterialDefinition* target); + /// Re-initializes the material instances for a specific target material. + void _reInitInstance(BaseMaterialDefinition* target); /// @see LightManager::smActivateSignal void _onLMActivate( const char *lm, bool activate ); @@ -155,6 +158,8 @@ protected: /// If set we flush and reinitialize all materials at the /// start of the next rendered frame. bool mFlushAndReInit; + bool mMatDefShouldReload; + bool mMatDefShouldFlush; // material map typedef Map MaterialMap; @@ -169,6 +174,8 @@ protected: F32 mDampness; BaseMatInstance* mWarningInst; + BaseMaterialDefinition* mMatDefToFlush; + BaseMaterialDefinition* mMatDefToReload; /// The default max anisotropy used in texture filtering. S32 mDefaultAnisotropy; diff --git a/Engine/source/materials/processedMaterial.cpp b/Engine/source/materials/processedMaterial.cpp index f477d80d6..1fa542c84 100644 --- a/Engine/source/materials/processedMaterial.cpp +++ b/Engine/source/materials/processedMaterial.cpp @@ -395,30 +395,42 @@ void ProcessedMaterial::_setStageData() if (mMaterial->mDiffuseMapAsset[i] && !mMaterial->mDiffuseMapAsset[i].isNull()) { mStages[i].setTex(MFT_DiffuseMap, mMaterial->getDiffuseMapResource(i)); - //mStages[i].setTex(MFT_DiffuseMap, _createTexture(mMaterial->getDiffuseMap(i), &GFXStaticTextureSRGBProfile)); if (!mStages[i].getTex(MFT_DiffuseMap)) { + // If we start with a #, we're probably actually attempting to hit a named target and it may not get a hit on the first pass. if (String(mMaterial->mDiffuseMapAsset[i]->getImageFileName()).startsWith("#") || String(mMaterial->mDiffuseMapAsset[i]->getImageFileName()).startsWith("$")) { - NamedTexTarget* namedTarget = NamedTexTarget::find(mMaterial->mDiffuseMapAsset[i]->getImageFileName() + 1); - if (namedTarget) - mStages[i].setTex(MFT_DiffuseMap, namedTarget->getTexture(0)); - if (mStages[i].getTex(MFT_DiffuseMap)) - { - mMaterial->mDiffuseMap[i] = namedTarget->getTexture(0); - } - - if (!mStages[i].getTex(MFT_DiffuseMap)) - mHasSetStageData = false; + mMaterial->logError("Named Target not ready %s for stage %i", mMaterial->mDiffuseMapAsset[i]->getImageFileName(), i); + mHasSetStageData = false; } - else { + else + { + // Load a debug texture to make it clear to the user + // that the texture for this stage was missing. + mStages[i].setTex(MFT_DiffuseMap, _createTexture(GFXTextureManager::getMissingTexturePath().c_str(), &GFXStaticTextureSRGBProfile)); + } + } + } + else if (mMaterial->mDiffuseMapName[i] != StringTable->EmptyString()) + { + mStages[i].setTex(MFT_DiffuseMap, _createTexture(mMaterial->mDiffuseMapName[i], &GFXStaticTextureSRGBProfile)); + if (!mStages[i].getTex(MFT_DiffuseMap)) + { + //If we start with a #, we're probably actually attempting to hit a named target and it may not get a hit on the first pass. So we'll + //pass on the error rather than spamming the console + if (String(mMaterial->mDiffuseMapName[i]).startsWith("#") || String(mMaterial->mDiffuseMapName[i]).startsWith("$")) + { + mMaterial->logError("Named Target not ready %s for stage %i", mMaterial->mDiffuseMapName[i], i); + mHasSetStageData = false; + } + else + { // Load a debug texture to make it clear to the user // that the texture for this stage was missing. mStages[i].setTex(MFT_DiffuseMap, _createTexture(GFXTextureManager::getMissingTexturePath().c_str(), &GFXStaticTextureSRGBProfile)); } } } - // OverlayMap if (mMaterial->getOverlayMap(i) != StringTable->EmptyString()) {