Fixed material property setting at runtime #214

Merged
Pycorax merged 4 commits from SP3-1-MaterialUpdate into main 2022-11-16 17:01:57 +08:00
4 changed files with 49 additions and 22 deletions

View File

@ -17,6 +17,7 @@ of DigiPen Institute of Technology is prohibited.
// Project Includes // Project Includes
#include "Resource/SHHandle.h" #include "Resource/SHHandle.h"
#include "SHCommonTypes.h" #include "SHCommonTypes.h"
#include "SH_API.h"
namespace SHADE namespace SHADE
{ {
@ -35,7 +36,7 @@ namespace SHADE
Describes a Pipeline along with it's associated properties for this instance. Describes a Pipeline along with it's associated properties for this instance.
*/ */
/***********************************************************************************/ /***********************************************************************************/
class SHMaterial class SH_API SHMaterial
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -43,9 +43,9 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
struct OverrideData struct OverrideData
{ {
size_t Index; uint32_t Index;
size_t DataSize; uint32_t DataSize;
size_t StoredDataOffset; uint32_t StoredDataOffset;
}; };
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -11,6 +11,7 @@ of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
#pragma once #pragma once
#include "SHMaterialInstance.h" #include "SHMaterialInstance.h"
#include "SHMaterial.h"
namespace SHADE namespace SHADE
{ {
@ -34,26 +35,39 @@ namespace SHADE
dataStore.reset(new char[dataStoreSize]); dataStore.reset(new char[dataStoreSize]);
} }
OverrideData od; // Check if this was stored before
od.Index = SHADER_INFO->GetVariableIndex(key); const uint32_t VAR_IDX = SHADER_INFO->GetVariableIndex(key);
od.DataSize = sizeof(T); auto existingOverride = std::find_if(overrideData.begin(), overrideData.end(), [&](const OverrideData& od)
if (overrideData.empty())
{ {
od.StoredDataOffset = 0; return od.Index == VAR_IDX;
} });
else
// Otherwise, create it
if (existingOverride == overrideData.end())
{ {
const OverrideData& lastInsertedData = overrideData.back(); OverrideData od;
od.StoredDataOffset = lastInsertedData.StoredDataOffset + lastInsertedData.DataSize; od.Index = VAR_IDX;
od.DataSize = sizeof(T);
if (overrideData.empty())
{
od.StoredDataOffset = 0;
}
else
{
const OverrideData& lastInsertedData = overrideData.back();
od.StoredDataOffset = lastInsertedData.StoredDataOffset + lastInsertedData.DataSize;
}
// Save the override data information
overrideData.emplace_back(std::move(od));
existingOverride = overrideData.end() - 1;
} }
// Get offset and modify the memory directly // Get offset and modify the memory directly
T* dataPtr = reinterpret_cast<T*>(dataStore.get() + od.StoredDataOffset); T* dataPtr = reinterpret_cast<T*>(dataStore.get() + existingOverride->StoredDataOffset);
*dataPtr = value; *dataPtr = value;
// Save the override data information
overrideData.emplace_back(std::move(od));
// Flag // Flag
dataWasChanged = true; dataWasChanged = true;
} }
@ -70,11 +84,22 @@ namespace SHADE
// Search Override Data for the property // Search Override Data for the property
uint32_t PROP_IDX = SHADER_INFO->GetVariableIndex(key); uint32_t PROP_IDX = SHADER_INFO->GetVariableIndex(key);
auto prop = std::find_if(overrideData.begin(), overrideData.end(), [&](const OverrideData& data) auto prop = std::find_if(overrideData.begin(), overrideData.end(), [&](const OverrideData& data)
{ {
return PROP_IDX == data.Index; return PROP_IDX == data.Index;
}); });
// No overrides, we get from the base material instead
if (prop == overrideData.end()) if (prop == overrideData.end())
throw std::invalid_argument("Attempted to get an property that was not set previously!"); {
if (baseMaterial)
{
return baseMaterial->GetProperty<T>(key);
}
else
{
throw std::invalid_argument("Attempted to get an property that was not set previously!");
}
}
// Get offset and return the memory directly // Get offset and return the memory directly
T* dataPtr = reinterpret_cast<T*>(dataStore.get() + prop->StoredDataOffset); T* dataPtr = reinterpret_cast<T*>(dataStore.get() + prop->StoredDataOffset);

View File

@ -91,6 +91,7 @@ namespace SHADE
{ {
SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>(); SHGraphicsSystem* gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
material = gfxSystem->AddMaterialInstanceCopy(sharedMaterial); material = gfxSystem->AddMaterialInstanceCopy(sharedMaterial);
matChanged = true;
} }
return material; return material;