diff --git a/Engine/source/T3D/assets/ImageAsset.cpp b/Engine/source/T3D/assets/ImageAsset.cpp index 89088f7fe8..162626b84d 100644 --- a/Engine/source/T3D/assets/ImageAsset.cpp +++ b/Engine/source/T3D/assets/ImageAsset.cpp @@ -274,6 +274,20 @@ U32 ImageAsset::load() if (mLoadedState == AssetErrCode::Ok) return mLoadedState; if (mImagePath) { + // this is a target. + if (mImageFileName[0] == '$' || mImageFileName[0] == '#') + { + NamedTexTargetRef namedTarget = NamedTexTarget::find(mImageFileName + 1); + if (namedTarget) { + mLoadedState = Ok; + mIsValidImage = true; + return mLoadedState; + } + else + { + Con::errorf("ImageAsset::initializeAsset: Attempted find named target %s failed.", mImageFileName); + } + } if (!Torque::FS::IsFile(mImagePath)) { Con::errorf("ImageAsset::initializeAsset: Attempted to load file %s but it was not valid!", mImageFileName); @@ -295,12 +309,26 @@ void ImageAsset::initializeAsset() { ResourceManager::get().getChangedSignal().notify(this, &ImageAsset::_onResourceChanged); - mImagePath = getOwned() ? expandAssetFilePath(mImageFileName) : mImagePath; + if (mImageFileName[0] != '$' && mImageFileName[0] != '#') + { + mImagePath = getOwned() ? expandAssetFilePath(mImageFileName) : mImagePath; + } + else + { + mImagePath = mImageFileName; + } } void ImageAsset::onAssetRefresh() { - mImagePath = getOwned() ? expandAssetFilePath(mImageFileName) : mImagePath; + if (mImageFileName[0] != '$' && mImageFileName[0] != '#') + { + mImagePath = getOwned() ? expandAssetFilePath(mImageFileName) : mImagePath; + } + else + { + mImagePath = mImageFileName; + } AssetManager::typeAssetDependsOnHash::Iterator assetDependenciesItr = mpOwningAssetManager->getDependedOnAssets()->find(mpAssetDefinition->mAssetId); // Iterate all dependencies. @@ -334,6 +362,7 @@ void ImageAsset::setImageFileName(const char* pScriptFile) GFXTexHandle ImageAsset::getTexture(GFXTextureProfile* requestedProfile) { + load(); if (mResourceMap.contains(requestedProfile)) { mLoadedState = Ok; @@ -341,21 +370,35 @@ GFXTexHandle ImageAsset::getTexture(GFXTextureProfile* requestedProfile) } else { - //If we don't have an existing map case to the requested format, we'll just create it and insert it in - GFXTexHandle newTex = TEXMGR->createTexture(mImagePath, requestedProfile); - if (newTex) + // this is a target. + if (mImageFileName[0] == '$' || mImageFileName[0] == '#') { - mResourceMap.insert(requestedProfile, newTex); mLoadedState = Ok; - return newTex; + NamedTexTargetRef namedTarget = NamedTexTarget::find(mImageFileName + 1); + if (namedTarget.isValid() && namedTarget->getTexture()) + { + mNamedTarget = namedTarget; + mIsValidImage = true; + mResourceMap.insert(requestedProfile, mNamedTarget->getTexture()); + mChangeSignal.trigger(); + return mNamedTarget->getTexture(); + } } else - mLoadedState = BadFileReference; + { + //If we don't have an existing map case to the requested format, we'll just create it and insert it in + GFXTexHandle newTex = TEXMGR->createTexture(mImagePath, requestedProfile); + if (newTex) + { + mResourceMap.insert(requestedProfile, newTex); + mLoadedState = Ok; + return newTex; + } + else + mLoadedState = BadFileReference; + } } - //if (mTexture.isValid()) - // return mTexture; - return nullptr; } diff --git a/Engine/source/T3D/assets/ImageAsset.h b/Engine/source/T3D/assets/ImageAsset.h index 03bbaa556f..027dfbac11 100644 --- a/Engine/source/T3D/assets/ImageAsset.h +++ b/Engine/source/T3D/assets/ImageAsset.h @@ -50,6 +50,11 @@ #include "assetMacroHelpers.h" #include "gfx/gfxDevice.h" + +#ifndef _MATTEXTURETARGET_H_ +#include "materials/matTextureTarget.h" +#endif + //----------------------------------------------------------------------------- class ImageAsset : public AssetBase { @@ -95,6 +100,7 @@ class ImageAsset : public AssetBase protected: StringTableEntry mImageFileName; StringTableEntry mImagePath; + NamedTexTargetRef mNamedTarget; bool mIsValidImage; bool mUseMips; @@ -205,7 +211,7 @@ public: \ }\ else if(_in[0] == '$' || _in[0] == '#')\ {\ - m##name##Name = _in;\ + m##name##Name = _in;\ m##name##AssetId = StringTable->EmptyString();\ m##name##Asset = NULL;\ m##name.free();\ @@ -250,7 +256,9 @@ public: \ m##name##Asset->getChangedSignal().notify(this, &className::changeFunc);\ }\ \ - m##name.set(get##name(), m##name##Profile, avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__));\ + if (get##name()[0] != '$' && get##name()[0] != '#') {\ + m##name.set(get##name(), m##name##Profile, avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__));\ + }\ }\ else\ {\ @@ -278,7 +286,10 @@ public: \ const StringTableEntry get##name() const\ {\ if (m##name##Asset && (m##name##Asset->getImageFileName() != StringTable->EmptyString()))\ - return Platform::makeRelativePathName(m##name##Asset->getImagePath(), Platform::getMainDotCsDir());\ + if (m##name##Asset->getImageFileName()[0] == '#' || m##name##Asset->getImageFileName()[0] == '$')\ + return m##name##Asset->getImageFileName();\ + else\ + return Platform::makeRelativePathName(m##name##Asset->getImagePath(), Platform::getMainDotCsDir());\ else if (m##name##AssetId != StringTable->EmptyString())\ return m##name##AssetId;\ else if (m##name##Name != StringTable->EmptyString())\ @@ -288,6 +299,8 @@ public: \ }\ GFXTexHandle get##name##Resource() \ {\ + if (m##name##Asset && (m##name##Asset->getImageFileName() != StringTable->EmptyString()))\ + return m##name##Asset->getTexture(m##name##Profile);\ return m##name;\ }\ bool name##Valid() {return (get##name() != StringTable->EmptyString() && m##name##Asset->getStatus() == AssetBase::Ok); } @@ -323,7 +336,7 @@ if (m##name##AssetId != StringTable->EmptyString())\ #pragma region Arrayed Asset Macros //Arrayed Assets -#define DECLARE_IMAGEASSET_ARRAY(className, name, max) public: \ +#define DECLARE_IMAGEASSET_ARRAY(className, name, max, changeFunc) public: \ static const U32 sm##name##Count = max;\ GFXTexHandle m##name[max];\ StringTableEntry m##name##Name[max]; \ @@ -353,7 +366,7 @@ public: \ }\ else if(_in[0] == '$' || _in[0] == '#')\ {\ - m##name##Name[index] = _in;\ + m##name##Name[index] = _in;\ m##name##AssetId[index] = StringTable->EmptyString();\ m##name##Asset[index] = NULL;\ m##name[index].free();\ @@ -393,7 +406,9 @@ public: \ }\ if (get##name(index) != StringTable->EmptyString() && m##name##Name[index] != StringTable->insert("texhandle"))\ {\ - m##name[index].set(get##name(index), m##name##Profile[index], avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__));\ + m##name##Asset[index]->getChangedSignal().notify(this, &className::changeFunc);\ + if (get##name(index)[0] != '$' && get##name(index)[0] != '#')\ + m##name[index].set(get##name(index), m##name##Profile[index], avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__));\ }\ else\ {\ @@ -421,7 +436,10 @@ public: \ const StringTableEntry get##name(const U32& index) const\ {\ if (m##name##Asset[index] && (m##name##Asset[index]->getImageFileName() != StringTable->EmptyString()))\ - return Platform::makeRelativePathName(m##name##Asset[index]->getImagePath(), Platform::getMainDotCsDir());\ + if (m##name##Asset[index]->getImageFileName()[0] == '#' || m##name##Asset[index]->getImageFileName()[0] == '$')\ + return m##name##Asset[index]->getImageFileName();\ + else\ + return Platform::makeRelativePathName(m##name##Asset[index]->getImagePath(), Platform::getMainDotCsDir());\ else if (m##name##AssetId[index] != StringTable->EmptyString())\ return m##name##AssetId[index];\ else if (m##name##Name[index] != StringTable->EmptyString())\ @@ -438,6 +456,8 @@ public: \ {\ if(index >= sm##name##Count || index < 0)\ return nullptr;\ + if (m##name##Asset[index] && (m##name##Asset[index]->getImageFileName() != StringTable->EmptyString()))\ + return m##name##Asset[index]->getTexture(m##name##Profile[index]);\ return m##name[index];\ }\ bool name##Valid(const U32& id) {return (get##name(id) != StringTable->EmptyString() && m##name##Asset[id]->getStatus() == AssetBase::Ok); } diff --git a/Engine/source/T3D/fx/splash.h b/Engine/source/T3D/fx/splash.h index 754103cc5c..de98a5bca4 100644 --- a/Engine/source/T3D/fx/splash.h +++ b/Engine/source/T3D/fx/splash.h @@ -122,8 +122,9 @@ class SplashData : public GameBaseData F32 times[ NUM_TIME_KEYS ]; LinearColorF colors[ NUM_TIME_KEYS ]; - DECLARE_IMAGEASSET_ARRAY(SplashData, Texture, NUM_TEX); + DECLARE_IMAGEASSET_ARRAY(SplashData, Texture, NUM_TEX, onTextureChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(SplashData, Texture) + void onTextureChanged() {} ExplosionData* explosion; S32 explosionId; diff --git a/Engine/source/environment/basicClouds.h b/Engine/source/environment/basicClouds.h index 982b9cf9cc..bd67d1362a 100644 --- a/Engine/source/environment/basicClouds.h +++ b/Engine/source/environment/basicClouds.h @@ -94,9 +94,9 @@ class BasicClouds : public SceneObject static U32 smVertCount; static U32 smTriangleCount; - DECLARE_IMAGEASSET_ARRAY(BasicClouds, Texture, TEX_COUNT); + DECLARE_IMAGEASSET_ARRAY(BasicClouds, Texture, TEX_COUNT, onTextureChanged); DECLARE_IMAGEASSET_ARRAY_NET_SETGET(BasicClouds, Texture, -1); - + void onTextureChanged() {} GFXStateBlockRef mStateblock; GFXShaderRef mShader; diff --git a/Engine/source/gfx/sim/cubemapData.h b/Engine/source/gfx/sim/cubemapData.h index dd35918e20..c79dd42890 100644 --- a/Engine/source/gfx/sim/cubemapData.h +++ b/Engine/source/gfx/sim/cubemapData.h @@ -76,9 +76,10 @@ class CubemapData : public SimObject DECLARE_IMAGEASSET(CubemapData, CubeMap, onCubemapChanged, GFXStaticTextureSRGBProfile); DECLARE_ASSET_SETGET(CubemapData, CubeMap); - DECLARE_IMAGEASSET_ARRAY(CubemapData, CubeMapFace, 6); + DECLARE_IMAGEASSET_ARRAY(CubemapData, CubeMapFace, 6, onCubeMapFaceChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(CubemapData, CubeMapFace); + void onCubeMapFaceChanged() {} GFXTexHandle mDepthBuff; GFXTextureTargetRef mRenderTarget; diff --git a/Engine/source/gui/controls/guiPopUpCtrl.h b/Engine/source/gui/controls/guiPopUpCtrl.h index 40b129274b..12568d2c66 100644 --- a/Engine/source/gui/controls/guiPopUpCtrl.h +++ b/Engine/source/gui/controls/guiPopUpCtrl.h @@ -126,9 +126,9 @@ class GuiPopUpMenuCtrl : public GuiTextCtrl NumBitmapModes = 2 }; - DECLARE_IMAGEASSET_ARRAY(GuiPopUpMenuCtrl, Bitmap, NumBitmapModes); + DECLARE_IMAGEASSET_ARRAY(GuiPopUpMenuCtrl, Bitmap, NumBitmapModes, onBitmapChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(GuiPopUpMenuCtrl, Bitmap); - + void onBitmapChanged() {} Point2I mBitmapBounds; // Added S32 mIdMax; diff --git a/Engine/source/gui/controls/guiPopUpCtrlEx.h b/Engine/source/gui/controls/guiPopUpCtrlEx.h index 5a361565b5..f389de3e7d 100644 --- a/Engine/source/gui/controls/guiPopUpCtrlEx.h +++ b/Engine/source/gui/controls/guiPopUpCtrlEx.h @@ -131,9 +131,9 @@ class GuiPopUpMenuCtrlEx : public GuiTextCtrl NumBitmapModes = 2 }; - DECLARE_IMAGEASSET_ARRAY(GuiPopUpMenuCtrlEx, Bitmap, NumBitmapModes); + DECLARE_IMAGEASSET_ARRAY(GuiPopUpMenuCtrlEx, Bitmap, NumBitmapModes, onBitmapChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(GuiPopUpMenuCtrlEx, Bitmap); - + void onBitmapChanged() {} Point2I mBitmapBounds; // Added S32 mIdMax; diff --git a/Engine/source/materials/materialDefinition.cpp b/Engine/source/materials/materialDefinition.cpp index 8c5201b472..c9a09bd0d8 100644 --- a/Engine/source/materials/materialDefinition.cpp +++ b/Engine/source/materials/materialDefinition.cpp @@ -243,6 +243,11 @@ Material::Material() mReverbSoundOcclusion = 1.0; } +void Material::onImageAssetChanged() +{ + flush(); + reload(); +} void Material::initPersistFields() { @@ -857,3 +862,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 f3ef304e81..e17bdd317a 100644 --- a/Engine/source/materials/materialDefinition.h +++ b/Engine/source/materials/materialDefinition.h @@ -208,49 +208,51 @@ class Material : public BaseMaterialDefinition //----------------------------------------------------------------------- // Data //----------------------------------------------------------------------- - DECLARE_IMAGEASSET_ARRAY(Material, DiffuseMap, MAX_STAGES); + void onImageAssetChanged(); + + DECLARE_IMAGEASSET_ARRAY(Material, DiffuseMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, DiffuseMap); bool mDiffuseMapSRGB[MAX_STAGES]; // SRGB diffuse - DECLARE_IMAGEASSET_ARRAY(Material, OverlayMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, OverlayMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, OverlayMap); - DECLARE_IMAGEASSET_ARRAY(Material, LightMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, LightMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, LightMap); - DECLARE_IMAGEASSET_ARRAY(Material, ToneMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, ToneMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, ToneMap); - DECLARE_IMAGEASSET_ARRAY(Material, DetailMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, DetailMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, DetailMap); - DECLARE_IMAGEASSET_ARRAY(Material, NormalMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, NormalMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, NormalMap); - DECLARE_IMAGEASSET_ARRAY(Material, ORMConfigMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, ORMConfigMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, ORMConfigMap); bool mIsSRGb[MAX_STAGES]; - DECLARE_IMAGEASSET_ARRAY(Material, AOMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, AOMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, AOMap); F32 mAOChan[MAX_STAGES]; - DECLARE_IMAGEASSET_ARRAY(Material, RoughMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, RoughMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, RoughMap); bool mInvertRoughness[MAX_STAGES]; F32 mRoughnessChan[MAX_STAGES]; - DECLARE_IMAGEASSET_ARRAY(Material, MetalMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, MetalMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, MetalMap); F32 mMetalChan[MAX_STAGES]; - DECLARE_IMAGEASSET_ARRAY(Material, GlowMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, GlowMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, GlowMap); F32 mGlowMul[MAX_STAGES]; /// A second normal map which repeats at the detail map /// scale and blended with the base normal map. - DECLARE_IMAGEASSET_ARRAY(Material, DetailNormalMap, MAX_STAGES); + DECLARE_IMAGEASSET_ARRAY(Material, DetailNormalMap, MAX_STAGES, onImageAssetChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(Material, DetailNormalMap); /// The strength scalar for the detail normal map. diff --git a/Engine/source/materials/materialManager.cpp b/Engine/source/materials/materialManager.cpp index d2979d8ebe..87ce2bef2d 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) +{ + mMatDefToReload = target; + mMatDefShouldReload = true; } -void MaterialManager::reInitInstance( BaseMaterialDefinition *target ) +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 6f1889c266..2d983da7a4 100644 --- a/Engine/source/materials/materialManager.h +++ b/Engine/source/materials/materialManager.h @@ -116,11 +116,7 @@ class MaterialManager : public ManagedSingleton /// 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 @@ class MaterialManager : public ManagedSingleton 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 @@ class MaterialManager : public ManagedSingleton /// 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 @@ class MaterialManager : public ManagedSingleton 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 682011fec1..a4841ac6dd 100644 --- a/Engine/source/materials/processedMaterial.cpp +++ b/Engine/source/materials/processedMaterial.cpp @@ -395,11 +395,12 @@ 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)) { - // Load a debug texture to make it clear to the user - // that the texture for this stage was missing. + // 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("$")) + mMaterial->logError("Failed to load diffuse map %s for stage %i", mMaterial->mDiffuseMapAsset[i]->getImageFileName(), i); + mStages[i].setTex(MFT_DiffuseMap, _createTexture(GFXTextureManager::getMissingTexturePath().c_str(), &GFXStaticTextureSRGBProfile)); } } @@ -408,9 +409,8 @@ void ProcessedMaterial::_setStageData() 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("#")) + //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->mDiffuseMapName[i]).startsWith("#") && !String(mMaterial->mDiffuseMapName[i]).startsWith("$")) mMaterial->logError("Failed to load diffuse map %s for stage %i", mMaterial->mDiffuseMapName[i], i); // Load a debug texture to make it clear to the user @@ -418,7 +418,6 @@ void ProcessedMaterial::_setStageData() mStages[i].setTex(MFT_DiffuseMap, _createTexture(GFXTextureManager::getMissingTexturePath().c_str(), &GFXStaticTextureSRGBProfile)); } } - // OverlayMap if (mMaterial->getOverlayMap(i) != StringTable->EmptyString()) { diff --git a/Engine/source/postFx/postEffect.h b/Engine/source/postFx/postEffect.h index 89c4b74277..702fed0a82 100644 --- a/Engine/source/postFx/postEffect.h +++ b/Engine/source/postFx/postEffect.h @@ -90,8 +90,9 @@ class PostEffect : public SimGroup protected: - DECLARE_IMAGEASSET_ARRAY(PostEffect, Texture, NumTextures); + DECLARE_IMAGEASSET_ARRAY(PostEffect, Texture, NumTextures, onTextureChanged); DECLARE_IMAGEASSET_ARRAY_SETGET(PostEffect, Texture); + void onTextureChanged() {} bool mTexSRGB[NumTextures];