Added serialization interfaces for Material (missing Shader)

This commit is contained in:
Kah Wei 2022-10-22 19:38:02 +08:00
parent 76f83068ba
commit 9d8dfd334f
7 changed files with 273 additions and 21 deletions

View File

@ -23,7 +23,7 @@ namespace SHADE
} }
// Allocate memory for properties // Allocate memory for properties
const Handle<SHShaderBlockInterface> SHADER_INFO = getShaderBlockInterface(); const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; propMemorySize = SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
if (propMemorySize <= 0) if (propMemorySize <= 0)
{ {
@ -59,14 +59,14 @@ namespace SHADE
size_t SHMaterial::GetPropertiesMemorySize() const noexcept size_t SHMaterial::GetPropertiesMemorySize() const noexcept
{ {
const Handle<SHShaderBlockInterface> SHADER_INFO = getShaderBlockInterface(); const Handle<SHShaderBlockInterface> SHADER_INFO = GetShaderBlockInterface();
return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0; return SHADER_INFO ? SHADER_INFO->GetBytesRequired() : 0;
} }
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> SHMaterial::getShaderBlockInterface() const noexcept Handle<SHShaderBlockInterface> SHMaterial::GetShaderBlockInterface() const noexcept
{ {
return pipeline->GetPipelineLayout()->GetShaderBlockInterface return pipeline->GetPipelineLayout()->GetShaderBlockInterface
( (

View File

@ -50,13 +50,24 @@ namespace SHADE
template<typename T> template<typename T>
void SetProperty(const std::string& key, const T& value); void SetProperty(const std::string& key, const T& value);
template<typename T> template<typename T>
void SetProperty(uint32_t memOffset, const T& value);
template<typename T>
T& GetProperty(const std::string& key); T& GetProperty(const std::string& key);
template<typename T> template<typename T>
const T& GetProperty(const std::string& key) const; const T& GetProperty(const std::string& key) const;
template<typename T>
T& GetProperty(uint32_t memOffset);
template<typename T>
const T& GetProperty(uint32_t memOffset) const;
void ResetProperties(); void ResetProperties();
void ExportProperties(void* dest) const noexcept; void ExportProperties(void* dest) const noexcept;
Byte GetPropertiesMemorySize() const noexcept; Byte GetPropertiesMemorySize() const noexcept;
/*-----------------------------------------------------------------------------*/
/* Query Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> GetShaderBlockInterface() const noexcept;
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
@ -64,11 +75,6 @@ namespace SHADE
Handle<SHVkPipeline> pipeline; Handle<SHVkPipeline> pipeline;
std::unique_ptr<char> propMemory; std::unique_ptr<char> propMemory;
Byte propMemorySize = 0; Byte propMemorySize = 0;
/*-----------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------*/
Handle<SHShaderBlockInterface> getShaderBlockInterface() const noexcept;
}; };
} }

View File

@ -25,7 +25,7 @@ namespace SHADE
template<typename T> template<typename T>
void SHMaterial::SetProperty(const std::string& key, const T& value) void SHMaterial::SetProperty(const std::string& key, const T& value)
{ {
const auto SHADER_INFO = getShaderBlockInterface(); const auto SHADER_INFO = GetShaderBlockInterface();
const auto PROP_INFO = SHADER_INFO->GetVariable(key); const auto PROP_INFO = SHADER_INFO->GetVariable(key);
if (PROP_INFO == nullptr) if (PROP_INFO == nullptr)
{ {
@ -36,14 +36,25 @@ namespace SHADE
T* dataPtr = propMemory.get() + PROP_INFO->offset; T* dataPtr = propMemory.get() + PROP_INFO->offset;
*dataPtr = value; *dataPtr = value;
} }
template<typename T>
void SHMaterial::SetProperty(uint32_t memOffset, const T& value)
{
// Check if out of bounds
if (memOffset + sizeof(T) > propMemorySize)
throw std::invalid_argument("Attempted to set an invalid property!");
// Set
(*reinterpret_cast<T*>(propMemory.get() + memOffset)) = value;
}
template<typename T> template<typename T>
T& SHMaterial::GetProperty(const std::string& key) T& SHMaterial::GetProperty(const std::string& key)
{ {
const auto SHADER_INFO = getShaderBlockInterface(); const auto SHADER_INFO = GetShaderBlockInterface();
const auto PROP_INFO = SHADER_INFO->GetVariable(key); const auto PROP_INFO = SHADER_INFO->GetVariable(key);
if (PROP_INFO == nullptr) if (PROP_INFO == nullptr)
{ {
throw std::invalid_argument("Attempted to set an invalid property!"); throw std::invalid_argument("Attempted to retrieve an invalid property!");
} }
// Get offset and return the memory directly // Get offset and return the memory directly
@ -56,4 +67,18 @@ namespace SHADE
return const_cast<const T&>(const_cast<SHMaterial*>(this)->GetProperty(key)); return const_cast<const T&>(const_cast<SHMaterial*>(this)->GetProperty(key));
} }
template<typename T>
const T& SHMaterial::GetProperty(uint32_t memOffset) const
{
// Check if out of bounds
if (memOffset + sizeof(T) > propMemorySize)
throw std::invalid_argument("Attempted to retrieve an invalid property!");
return *(reinterpret_cast<T*>(propMemory.get() + memOffset));
}
template<typename T>
T& SHMaterial::GetProperty(uint32_t memOffset)
{
return const_cast<const T&>(const_cast<SHMaterial*>(this)->GetProperty(memOffset));
}
} }

View File

@ -11,10 +11,117 @@
#include "Math/Vector/SHVec4.h" #include "Math/Vector/SHVec4.h"
#include "Resource/SHResourceManager.h" #include "Resource/SHResourceManager.h"
#include "Graphics/MiddleEnd/Interface/SHRenderable.h" #include "Graphics/MiddleEnd/Interface/SHRenderable.h"
#include "Graphics/MiddleEnd/Interface/SHMaterial.h"
#include "SHSerializationTools.h"
namespace YAML namespace YAML
{ {
using namespace SHADE; using namespace SHADE;
template<>
struct convert<SHMaterial>
{
static constexpr std::string_view VERT_SHADER_YAML_TAG = "VertexShader";
static constexpr std::string_view FRAG_SHADER_YAML_TAG = "FragmentShader";
static constexpr std::string_view PROPS_YAML_TAG = "Properties";
static YAML::Node encode(SHMaterial const& rhs)
{
// Write Properties
YAML::Node propertiesNode;
Handle<SHShaderBlockInterface> pipelineProperties = rhs.GetShaderBlockInterface();
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
{
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
if (!VARIABLE)
break;
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
YAML::Node propNode;
switch (VARIABLE->type)
{
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
propNode = rhs.GetProperty<float>(VARIABLE->offset);
break;
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
propNode = rhs.GetProperty<int>(VARIABLE->offset);
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
propNode = SHSerializationTools::ValToYAML(rhs.GetProperty<SHVec2>(VARIABLE->offset));
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
propNode = SHSerializationTools::ValToYAML(rhs.GetProperty<SHVec3>(VARIABLE->offset));
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
propNode = SHSerializationTools::ValToYAML(rhs.GetProperty<SHVec4>(VARIABLE->offset));
break;
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
default:
continue;
break;
}
propertiesNode[VAR_NAME.data()] = propNode;
}
// Write Material
YAML::Node node;
node[VERT_SHADER_YAML_TAG.data()] = 0;
node[FRAG_SHADER_YAML_TAG.data()] = 0;
node[PROPS_YAML_TAG.data()] = propertiesNode;
return node;
}
static bool decode(YAML::Node const& node, SHMaterial& rhs)
{
if (node[VERT_SHADER_YAML_TAG.data()])
{
// TODO
}
if (node[FRAG_SHADER_YAML_TAG.data()])
{
// TODO
}
if (node[PROPS_YAML_TAG.data()])
{
// Loop through all properties
Handle<SHShaderBlockInterface> pipelineProperties = rhs.GetShaderBlockInterface();
const YAML::Node& PROPS_NODE = node[PROPS_YAML_TAG.data()];
for (int i = 0; i < static_cast<int>(pipelineProperties->GetVariableCount()); ++i)
{
const std::string& PROP_NAME = pipelineProperties->GetVariableName(i);
const auto& PROP_NODE = PROPS_NODE[PROP_NAME.data()];
if (PROP_NODE)
{
const std::string& VAR_NAME = pipelineProperties->GetVariableName(i);
const SHShaderBlockInterface::Variable* VARIABLE = pipelineProperties->GetVariable(i);
switch (VARIABLE->type)
{
case SHADE::SHShaderBlockInterface::Variable::Type::FLOAT:
rhs.SetProperty(VARIABLE->offset, PROP_NODE.as<float>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::INT:
rhs.SetProperty(VARIABLE->offset, PROP_NODE.as<int>());
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR2:
rhs.SetProperty(VARIABLE->offset, SHSerializationTools::YAMLToVec2(PROP_NODE));
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR3:
rhs.SetProperty(VARIABLE->offset, SHSerializationTools::YAMLToVec3(PROP_NODE));
break;
case SHADE::SHShaderBlockInterface::Variable::Type::VECTOR4:
rhs.SetProperty(VARIABLE->offset, SHSerializationTools::YAMLToVec4(PROP_NODE));
break;
case SHADE::SHShaderBlockInterface::Variable::Type::OTHER:
default:
continue;
break;
}
}
}
}
return true;
}
};
template<> template<>
struct convert<SHRenderable> struct convert<SHRenderable>
{ {
@ -160,18 +267,15 @@ namespace SHADE
auto propType = prop.get_type(); auto propType = prop.get_type();
if (propType == rttr::type::get<SHVec4>()) if (propType == rttr::type::get<SHVec4>())
{ {
SHVec4 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>(), propertyNode["W"].as<float>() }; prop.set_value(component, SHSerializationTools::YAMLToVec4(propertyNode));
prop.set_value(component, vec);
} }
else if (propType == rttr::type::get<SHVec3>()) else if (propType == rttr::type::get<SHVec3>())
{ {
SHVec3 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>(), propertyNode["Z"].as<float>() }; prop.set_value(component, SHSerializationTools::YAMLToVec3(propertyNode));
prop.set_value(component, vec);
} }
else if (propType == rttr::type::get<SHVec2>()) else if (propType == rttr::type::get<SHVec2>())
{ {
SHVec2 vec{ propertyNode["X"].as<float>(), propertyNode["Y"].as<float>() }; prop.set_value(component, SHSerializationTools::YAMLToVec2(propertyNode));
prop.set_value(component, vec);
} }
else if (propType.is_arithmetic()) else if (propType.is_arithmetic())
{ {

View File

@ -0,0 +1,67 @@
/************************************************************************************//*!
\file SHSerializationTools.cpp
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 22, 2022
\brief Contains the definition of functions of the SHSerializationTools class.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#include "SHpch.h"
#include "SHSerializationTools.h"
namespace SHADE
{
/*-----------------------------------------------------------------------------------*/
/* YAML Serialization Functions */
/*-----------------------------------------------------------------------------------*/
YAML::Node SHSerializationTools::ValToYAML(const SHVec2& vec)
{
YAML::Node node;
node.SetStyle(YAML::EmitterStyle::Flow);
node["X"] = vec.x;
node["Y"] = vec.y;
return node;
}
YAML::Node SHSerializationTools::ValToYAML(const SHVec3& vec)
{
YAML::Node node;
node.SetStyle(YAML::EmitterStyle::Flow);
node["X"] = vec.x;
node["Y"] = vec.y;
node["Z"] = vec.z;
return node;
}
YAML::Node SHSerializationTools::ValToYAML(const SHVec4& vec)
{
YAML::Node node;
node.SetStyle(YAML::EmitterStyle::Flow);
node["X"] = vec.x;
node["Y"] = vec.y;
node["Z"] = vec.z;
node["W"] = vec.w;
return node;
}
/*-----------------------------------------------------------------------------------*/
/* YAML Deserialization Functions */
/*-----------------------------------------------------------------------------------*/
SHVec2 SHSerializationTools::YAMLToVec2(const YAML::Node& node)
{
return SHVec2 { node["X"].as<float>(), node["Y"].as<float>() };
}
SHVec3 SHSerializationTools::YAMLToVec3(const YAML::Node& node)
{
return SHVec3 { node["X"].as<float>(), node["Y"].as<float>(), node["Z"].as<float>() };
}
SHVec4 SHSerializationTools::YAMLToVec4(const YAML::Node& node)
{
return SHVec4 { node["X"].as<float>(), node["Y"].as<float>(), node["Z"].as<float>(), node["W"].as<float>() };
}
}

View File

@ -0,0 +1,54 @@
/************************************************************************************//*!
\file SHSerializationTools.h
\author Tng Kah Wei, kahwei.tng, 390009620
\par email: kahwei.tng\@digipen.edu
\date Oct 22, 2022
\brief Contains the class definition of SHSerializationTools.
Copyright (C) 2022 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/
#pragma once
// External Dependencies
#include <yaml-cpp/yaml.h>
// Project Includes
#include "SH_API.h"
#include "Math/Vector/SHVec2.h"
#include "Math/Vector/SHVec3.h"
#include "Math/Vector/SHVec4.h"
namespace SHADE
{
/*************************************************************************************/
/*!
\brief
Static class that contains useful functions for converting values to YAML Nodes
and vice versa.
*/
/*************************************************************************************/
class SH_API SHSerializationTools
{
public:
/*---------------------------------------------------------------------------------*/
/* Constructors */
/*---------------------------------------------------------------------------------*/
SHSerializationTools() = delete;
/*---------------------------------------------------------------------------------*/
/* YAML Serialization Functions */
/*---------------------------------------------------------------------------------*/
static YAML::Node ValToYAML(const SHVec2& vec);
static YAML::Node ValToYAML(const SHVec3& vec);
static YAML::Node ValToYAML(const SHVec4& vec);
/*---------------------------------------------------------------------------------*/
/* YAML Deserialization Functions */
/*---------------------------------------------------------------------------------*/
static SHVec2 YAMLToVec2(const YAML::Node& node);
static SHVec3 YAMLToVec3(const YAML::Node& node);
static SHVec4 YAMLToVec4(const YAML::Node& node);
};
}

View File

@ -184,10 +184,6 @@ namespace SHADE
void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node) void ReflectionUtilities::writeYamlIntoField(System::Reflection::FieldInfo^ fieldInfo, Object^ object, YAML::Node& node)
{ {
if (fieldInfo->FieldType == System::Int16::typeid)
{
fieldInfo->SetValue(object, node.as<int>());
}
if (fieldAssignYaml<System::Int16> (fieldInfo, object, node) || if (fieldAssignYaml<System::Int16> (fieldInfo, object, node) ||
fieldAssignYaml<System::Int32> (fieldInfo, object, node) || fieldAssignYaml<System::Int32> (fieldInfo, object, node) ||
fieldAssignYaml<System::Int64> (fieldInfo, object, node) || fieldAssignYaml<System::Int64> (fieldInfo, object, node) ||