Fix MaterialParams sync bug

This commit is contained in:
Wojtek Figat
2021-02-21 17:40:37 +01:00
parent a1d4e50e98
commit 919bd4ee1b
3 changed files with 82 additions and 75 deletions

View File

@@ -23,17 +23,25 @@ void MaterialInstance::OnBaseSet()
_baseMaterial->OnUnloaded.Bind<MaterialInstance, &MaterialInstance::OnBaseUnloaded>(this);
_baseMaterial->ParamsChanged.Bind<MaterialInstance, &MaterialInstance::OnBaseParamsChanged>(this);
// Sync parameters with the base parameters to ensure all data is valid for rendering (constants offset and resource register)
MaterialParams& baseParams = _baseMaterial->Params;
bool validParams = Params.Count() == baseParams.Count();
for (int32 i = 0; validParams && i < Params.Count(); i++)
Params._versionHash = 0;
if (Params.Count() != baseParams.Count())
{
// Params changed
OnBaseParamsChanged();
return;
}
for (int32 i = 0; i < Params.Count(); i++)
{
MaterialParameter& param = Params[i];
MaterialParameter& baseParam = baseParams[i];
if (param.GetID() != baseParam.GetID() || param.GetParameterType() != baseParam.GetParameterType())
{
validParams = false;
break;
// Params changed
OnBaseParamsChanged();
return;
}
param._isPublic = baseParam._isPublic;
@@ -41,21 +49,14 @@ void MaterialInstance::OnBaseSet()
param._offset = baseParam._offset;
param._name = baseParam._name;
}
if (validParams)
{
Params._versionHash = baseParams._versionHash;
ParamsChanged();
}
else
{
OnBaseParamsChanged();
}
// Params are valid
Params._versionHash = baseParams._versionHash;
ParamsChanged();
}
void MaterialInstance::OnBaseUnset()
{
ScopeLock lock(_baseMaterial->Locker);
_baseMaterial->RemoveReference();
_baseMaterial->OnUnloaded.Unbind<MaterialInstance, &MaterialInstance::OnBaseUnloaded>(this);
_baseMaterial->ParamsChanged.Unbind<MaterialInstance, &MaterialInstance::OnBaseParamsChanged>(this);

View File

@@ -431,6 +431,67 @@ String MaterialParameter::ToString() const
return String::Format(TEXT("\'{0}\' ({1}:{2}:{3})"), _name, ::ToString(_type), _paramId, _isPublic);
}
MaterialParameter* MaterialParams::Get(const Guid& id)
{
MaterialParameter* result = nullptr;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetParameterID() == id)
{
result = &At(i);
break;
}
}
return result;
}
MaterialParameter* MaterialParams::Get(const StringView& name)
{
MaterialParameter* result = nullptr;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetName() == name)
{
result = &At(i);
break;
}
}
return result;
}
int32 MaterialParams::Find(const Guid& id)
{
int32 result = -1;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetParameterID() == id)
{
result = i;
break;
}
}
return result;
}
int32 MaterialParams::Find(const StringView& name)
{
int32 result = -1;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetName() == name)
{
result = i;
break;
}
}
return result;
}
int32 MaterialParams::GetVersionHash() const
{
return _versionHash;
}
void MaterialParams::Bind(MaterialParamsLink* link, MaterialParameter::BindMeta& meta)
{
ASSERT(link && link->This);

View File

@@ -366,72 +366,17 @@ private:
public:
MaterialParameter* Get(const Guid& id)
{
MaterialParameter* result = nullptr;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetParameterID() == id)
{
result = &At(i);
break;
}
}
return result;
}
MaterialParameter* Get(const StringView& name)
{
MaterialParameter* result = nullptr;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetName() == name)
{
result = &At(i);
break;
}
}
return result;
}
int32 Find(const Guid& id)
{
int32 result = -1;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetParameterID() == id)
{
result = i;
break;
}
}
return result;
}
int32 Find(const StringView& name)
{
int32 result = -1;
for (int32 i = 0; i < Count(); i++)
{
if (At(i).GetName() == name)
{
result = i;
break;
}
}
return result;
}
MaterialParameter* Get(const Guid& id);
MaterialParameter* Get(const StringView& name);
int32 Find(const Guid& id);
int32 Find(const StringView& name);
public:
/// <summary>
/// Gets the parameters version hash. Every time the parameters are modified (loaded, edited, etc.) the hash changes. Can be used to sync instanced parameters collection.
/// </summary>
/// <returns>The hash.</returns>
FORCE_INLINE int32 GetVersionHash() const
{
return _versionHash;
}
int32 GetVersionHash() const;
public: