فهرست منبع

fixes for reload and flush

marauder2k7 9 ماه پیش
والد
کامیت
1edfbcf447

+ 4 - 6
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;

+ 4 - 10
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;\

+ 5 - 0
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);
+

+ 1 - 3
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);

+ 38 - 3
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<BaseMatInstance*>::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<BaseMatInstance*>::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:

+ 11 - 4
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<String, String> MaterialMap;
@@ -169,6 +174,8 @@ protected:
    F32 mDampness;
 
    BaseMatInstance* mWarningInst;
+   BaseMaterialDefinition* mMatDefToFlush;
+   BaseMaterialDefinition* mMatDefToReload;
 
    /// The default max anisotropy used in texture filtering.
    S32 mDefaultAnisotropy;

+ 25 - 13
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())
       {