Added full support for runtime editing of material properties #215

Merged
Pycorax merged 14 commits from SP3-1-MaterialEditSupport into main 2022-11-17 09:22:53 +08:00
11 changed files with 195 additions and 94 deletions
Showing only changes of commit 75f103c372 - Show all commits

View File

@ -710,6 +710,11 @@ namespace SHADE
return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial()); return resourceManager.Create<SHMaterialInstance>(materialInst->GetBaseMaterial());
} }
std::pair<typename SHResourceHub::dense_iterator<SHMaterialInstance>, typename SHResourceHub::dense_iterator<SHMaterialInstance>> SHGraphicsSystem::GetAllMaterialInstances()
{
return resourceManager.GetDenseAccess<SHMaterialInstance>();
}
void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance) void SHGraphicsSystem::RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance)
{ {
resourceManager.Free(materialInstance); resourceManager.Free(materialInstance);

View File

@ -156,6 +156,7 @@ namespace SHADE
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(); Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance();
Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material); Handle<SHMaterialInstance> AddOrGetBaseMaterialInstance(Handle<SHMaterial> material);
Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst); Handle<SHMaterialInstance> AddMaterialInstanceCopy(Handle<SHMaterialInstance> materialInst);
std::pair<typename SHResourceHub::dense_iterator<SHMaterialInstance>, typename SHResourceHub::dense_iterator<SHMaterialInstance>> GetAllMaterialInstances();
void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance); void RemoveMaterialInstance(Handle<SHMaterialInstance> materialInstance);
Handle<SHMaterial> GetDefaultMaterial() { return defaultMaterial; } Handle<SHMaterial> GetDefaultMaterial() { return defaultMaterial; }
Handle<SHMaterialInstance> GetDefaultMaterialInstance() { return AddOrGetBaseMaterialInstance(defaultMaterial); } Handle<SHMaterialInstance> GetDefaultMaterialInstance() { return AddOrGetBaseMaterialInstance(defaultMaterial); }
@ -166,10 +167,10 @@ namespace SHADE
/*******************************************************************************/ /*******************************************************************************/
/*! /*!
\brief \brief
Adds a mesh to the Mesh Library. But this does not mean that the meshes have Adds a mesh to the Mesh Library. But this does not mean that the meshes have
been added yet. A call to "BuildBuffers()" is required to transfer all been added yet. A call to "BuildBuffers()" is required to transfer all
meshes into the GPU. meshes into the GPU.
\param vertexCount \param vertexCount
Number of vertices in this Mesh. Number of vertices in this Mesh.

View File

@ -6,91 +6,113 @@
#include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h" #include "Graphics/Shaders/BlockInterface/SHShaderBlockInterface.h"
#include "Math/Vector/SHVec3.h" #include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "ECS_Base/Managers/SHSystemManager.h"
#include "SHGraphicsSystem.h"
#include "SHMaterialInstance.h"
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Pipeline Functions */ /* Pipeline Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void SHMaterial::SetPipeline(Handle<SHVkPipeline> _pipeline) void SHMaterial::SetPipeline(Handle<SHVkPipeline> _pipeline)
{ {
pipeline = _pipeline; // Reassignment, we ignore
if (_pipeline == pipeline)
return;
// Set up properties based on the pipeline pipeline = _pipeline;
if (!pipeline)
{
// Clear memory and all that
propMemory.reset();
return;
}
// Allocate memory for properties // Set up properties based on the pipeline
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface(); if (!pipeline)
propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
if (propMemorySize <= 0)
{
propMemory.reset();
}
else
{
propMemory.reset(new char[propMemorySize]);
}
ResetProperties();
}
Handle<SHVkPipeline> SHMaterial::GetPipeline() const
{
return pipeline;
}
/*---------------------------------------------------------------------------------*/
/* Property Functions */
/*---------------------------------------------------------------------------------*/
void SHMaterial::ResetProperties()
{ {
// Reset all the properties to default values // Clear memory and all that
if (propMemory) propMemory.reset();
memset(propMemory.get(), 0, propMemorySize); return;
// Initialize Vectors to all 1.0 by default
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
for (int i = 0; i < SHADER_INFO->GetVariableCount(); ++i)
{
const auto& VAR = SHADER_INFO->GetVariable(i);
switch (VAR->type)
{
case SHShaderBlockInterface::Variable::Type::VECTOR3:
setPropertyUnsafe(VAR->offset, SHVec3::One);
break;
case SHShaderBlockInterface::Variable::Type::VECTOR4:
setPropertyUnsafe(VAR->offset, SHVec4::One);
break;
}
}
} }
void SHMaterial::ExportProperties(void* dest) const noexcept // Allocate memory for properties
{ const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
if (propMemory) propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
memcpy(dest, propMemory.get(), propMemorySize); if (propMemorySize <= 0)
} {
propMemory.reset();
}
else
{
propMemory.reset(new char[propMemorySize]);
}
ResetProperties();
size_t SHMaterial::GetPropertiesMemorySize() const noexcept // Search all material instances for instances that use this base material
{ // to force a reset of properties
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface(); auto gfxSystem = SHSystemManager::GetSystem<SHGraphicsSystem>();
return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; if (gfxSystem)
} {
auto [matInstBegin, matInstEnd] = gfxSystem->GetAllMaterialInstances();
for (auto iter = matInstBegin; iter != matInstEnd; ++iter)
{
if (iter->GetBaseMaterial() == GetHandle())
{
iter->ResetProperties();
}
}
}
}
/*---------------------------------------------------------------------------------*/ Handle<SHVkPipeline> SHMaterial::GetPipeline() const
/* Helper Functions */ {
/*---------------------------------------------------------------------------------*/ return pipeline;
Handle<SHShaderBlockInterface> SHMaterial::GetShaderBlockInterface() const noexcept }
{
return pipeline->GetPipelineLayout()->GetShaderBlockInterface /*---------------------------------------------------------------------------------*/
( /* Property Functions */
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE, /*---------------------------------------------------------------------------------*/
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA, void SHMaterial::ResetProperties()
vk::ShaderStageFlagBits::eFragment {
); // Reset all the properties to default values
} if (propMemory)
memset(propMemory.get(), 0, propMemorySize);
// Initialize Vectors to all 1.0 by default
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
for (int i = 0; i < SHADER_INFO->GetVariableCount(); ++i)
{
const auto& VAR = SHADER_INFO->GetVariable(i);
switch (VAR->type)
{
case SHShaderBlockInterface::Variable::Type::VECTOR3:
setPropertyUnsafe(VAR->offset, SHVec3::One);
break;
case SHShaderBlockInterface::Variable::Type::VECTOR4:
setPropertyUnsafe(VAR->offset, SHVec4::One);
break;
}
}
}
void SHMaterial::ExportProperties(void* dest) const noexcept
{
if (propMemory)
memcpy(dest, propMemory.get(), propMemorySize);
}
size_t SHMaterial::GetPropertiesMemorySize() const noexcept
{
const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
}
/*---------------------------------------------------------------------------------*/
/* Helper Functions */
/*---------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterial::GetShaderBlockInterface() const noexcept
{
return pipeline->GetPipelineLayout()->GetShaderBlockInterface
(
SHGraphicsConstants::DescriptorSetIndex::PER_INSTANCE,
SHGraphicsConstants::DescriptorSetBindings::BATCHED_PER_INST_DATA,
vk::ShaderStageFlagBits::eFragment
);
}
} }

View File

@ -35,7 +35,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 SHMaterial : public ISelfHandle<SHMaterial>
{ {
public: public:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -31,7 +31,6 @@ namespace SHADE
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHMaterialInstance::ResetProperties() noexcept void SHMaterialInstance::ResetProperties() noexcept
{ {
// Reset all the properties to default values // Reset all the properties to default values
memset(dataStore.get(), 0, dataStoreSize); memset(dataStore.get(), 0, dataStoreSize);
overrideData.clear(); overrideData.clear();

View File

@ -34,7 +34,7 @@ namespace SHADE
{ {
colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState
{ {
.blendEnable = SHVkUtil::IsBlendCompatible (subpass->GetFormatFromAttachmentReference(att.attachment)) ? true : false, .blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)),
.srcColorBlendFactor = vk::BlendFactor::eSrcAlpha, .srcColorBlendFactor = vk::BlendFactor::eSrcAlpha,
.dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha,
.colorBlendOp = vk::BlendOp::eAdd, .colorBlendOp = vk::BlendOp::eAdd,

View File

@ -38,6 +38,11 @@ namespace SHADE
class SHResourceLibrary : public SHResourceLibraryBase class SHResourceLibrary : public SHResourceLibraryBase
{ {
public: public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
using dense_iterator = typename SparseSet<T>::dense_iterator;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructor */ /* Constructor */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -74,6 +79,16 @@ namespace SHADE
/// <returns>Read-only reference to the resource object.</returns> /// <returns>Read-only reference to the resource object.</returns>
const T& Get(Handle<T> handle) const; const T& Get(Handle<T> handle) const;
/*-----------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Provides access to the dense array of the SparseSet.
/// These iterators should not be used to manipulate the underlying vector.
/// </summary>
/// <returns>Pair of begin and end iterators to the dense vector.</returns>
std::pair<dense_iterator, dense_iterator> GetDenseAccess();
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -96,6 +111,12 @@ namespace SHADE
class SHResourceHub final class SHResourceHub final
{ {
public: public:
/*-----------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------*/
template<typename T>
using dense_iterator = typename SHResourceLibrary<T>::dense_iterator;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors/Destructors */ /* Constructors/Destructors */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -138,6 +159,18 @@ namespace SHADE
template<typename T> template<typename T>
const T& Get(Handle<T> handle) const; const T& Get(Handle<T> handle) const;
/*-----------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Provides access to the dense array of the SparseSet.
/// These iterators should not be used to manipulate the underlying vector.
/// </summary>
/// <typeparam name="T">Type of resource to access.</typeparam>
/// <returns>Pair of begin and end iterators to the dense vector.</returns>
template <typename T>
std::pair<dense_iterator<T>, dense_iterator<T>> GetDenseAccess();
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Type Definition */ /* Type Definition */

View File

@ -79,6 +79,15 @@ namespace SHADE
return objects[handle.GetId().Data.Index]; return objects[handle.GetId().Data.Index];
} }
/*---------------------------------------------------------------------------------*/
/* ResourceLibrary - Direct Dense Access Functions */
/*---------------------------------------------------------------------------------*/
template<typename T>
std::pair<typename SHResourceLibrary<T>::dense_iterator, typename SHResourceLibrary<T>::dense_iterator> SHResourceLibrary<T>::GetDenseAccess()
{
return objects.GetDenseAccess();
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ResourceLibrary - Helper Functions */ /* ResourceLibrary - Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -105,7 +114,7 @@ namespace SHADE
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* ResourceManager - Usage Functions */ /* ResourceHub - Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
template <typename T, typename ... Args> template <typename T, typename ... Args>
Handle<T> SHResourceHub::Create(Args&&... args) Handle<T> SHResourceHub::Create(Args&&... args)
@ -132,7 +141,7 @@ namespace SHADE
} }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* ResourceManager - Helper Functions */ /* ResourceHub - Helper Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
template <typename T> template <typename T>
SHResourceLibrary<T>& SHResourceHub::getLibrary() SHResourceLibrary<T>& SHResourceHub::getLibrary()
@ -161,4 +170,13 @@ namespace SHADE
{ {
return const_cast<SHResourceHub*>(this).getLibrary<T>(); return const_cast<SHResourceHub*>(this).getLibrary<T>();
} }
/*---------------------------------------------------------------------------------*/
/* ResourceHub - Direct Dense Access Functions */
/*---------------------------------------------------------------------------------*/
template <typename T>
std::pair<typename SHResourceHub::dense_iterator<T>, typename SHResourceHub::dense_iterator<T>> SHResourceHub::GetDenseAccess()
{
return getLibrary<T>().GetDenseAccess();
}
} }

View File

@ -13,8 +13,6 @@ of DigiPen Institute of Technology is prohibited.
// STL Includes // STL Includes
#include <unordered_map> #include <unordered_map>
namespace SHADE { class SHMaterial; }
// Project Includes // Project Includes
#include "SH_API.h" #include "SH_API.h"
#include "SHResourceLibrary.h" #include "SHResourceLibrary.h"
@ -31,17 +29,26 @@ namespace SHADE { class SHMaterial; }
namespace SHADE namespace SHADE
{ {
/*-----------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-----------------------------------------------------------------------------------*/
class SHMaterial;
/*-----------------------------------------------------------------------------------*/
/* Type Definitions */
/*-----------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Template structs that maps a resource to their loaded asset representation type. /// Template structs that maps a resource to their loaded asset representation type.
/// </summary> /// </summary>
template<typename T = void> template<typename T = void>
struct SHResourceLoader { using AssetType = void; }; struct SHResourceLoader { using AssetType = void; };
template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshData; }; template<> struct SHResourceLoader<SHMesh> { using AssetType = SHMeshData; };
template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; }; template<> struct SHResourceLoader<SHTexture> { using AssetType = SHTextureAsset; };
template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; }; template<> struct SHResourceLoader<SHVkShaderModule> { using AssetType = SHShaderAsset; };
template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; }; template<> struct SHResourceLoader<SHMaterialSpec> { using AssetType = SHMaterialAsset; };
template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; }; template<> struct SHResourceLoader<SHMaterial> { using AssetType = SHMaterialSpec; };
/// <summary>
/// <summary>
/// Static class responsible for loading and caching runtime resources from their /// Static class responsible for loading and caching runtime resources from their
/// serialised Asset IDs. /// serialised Asset IDs.
/// </summary> /// </summary>

View File

@ -49,6 +49,7 @@ namespace SHADE
using const_pointer = const T*; using const_pointer = const T*;
using reference = T&; using reference = T&;
using const_reference = const T&; using const_reference = const T&;
using dense_iterator = typename std::vector<T>::iterator;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constructors/Destructors */ /* Constructors/Destructors */
@ -59,10 +60,6 @@ namespace SHADE
SparseSet(); SparseSet();
~SparseSet() = default; ~SparseSet() = default;
//// Disallow moving or copying
//SparseSet(const SparseSet&) = delete;
//SparseSet(SparseSet&&) = delete;
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Usage Functions */ /* Usage Functions */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -192,6 +189,16 @@ namespace SHADE
/// </exception> /// </exception>
const T& operator[](index_type idx) const; const T& operator[](index_type idx) const;
/*-----------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Provides access to the dense array of the SparseSet.
/// These iterators should not be used to manipulate the underlying vector.
/// </summary>
/// <returns>Pair of begin and end iterators to the dense vector.</returns>
std::pair<dense_iterator, dense_iterator> GetDenseAccess();
protected: protected:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Constants */ /* Constants */

View File

@ -143,4 +143,13 @@ namespace SHADE
{ {
return at(idx); return at(idx);
} }
/*---------------------------------------------------------------------------------*/
/* Direct Dense Access Functions */
/*---------------------------------------------------------------------------------*/
template<typename T>
std::pair<typename SparseSet<T>::dense_iterator, typename SparseSet<T>::dense_iterator> SparseSet<T>::GetDenseAccess()
{
return { denseArray.begin(), denseArray.end() };
}
} }