16#include "aeongames/Material.hpp"
17#include "aeongames/ProtoBufUtils.hpp"
19#include "aeongames/ProtoBufHelpers.hpp"
22#pragma warning( push )
23#pragma warning( disable : PROTOBUF_WARNINGS )
25#include "material.pb.h"
40 mVariables = aMaterial.mVariables;
41 mSamplers = aMaterial.mSamplers;
47 return mUniformBuffer;
50 size_t Material::LoadVariables (
const MaterialMsg& aMaterialMsg )
53 mVariables.reserve ( aMaterialMsg.property().size() );
54 for (
auto& i : aMaterialMsg.property() )
56 switch ( i.value_case() )
58 case PropertyMsg::ValueCase::kScalarFloat:
59 size += ( size %
sizeof ( float ) ) ?
sizeof (
float ) - ( size %
sizeof ( float ) ) : 0;
60 mVariables.emplace_back ( i.name(), size );
61 size +=
sizeof ( float );
63 case PropertyMsg::ValueCase::kScalarUint:
64 size += ( size %
sizeof ( uint32_t ) ) ?
sizeof ( uint32_t ) - ( size %
sizeof ( uint32_t ) ) : 0;
65 mVariables.emplace_back ( i.name(), size );
66 size +=
sizeof ( uint32_t );
68 case PropertyMsg::ValueCase::kScalarInt:
69 size += ( size %
sizeof ( int32_t ) ) ?
sizeof ( int32_t ) - ( size %
sizeof ( int32_t ) ) : 0;
70 mVariables.emplace_back ( i.name(), size );
71 size +=
sizeof ( int32_t );
73 case PropertyMsg::ValueCase::kVector2:
74 size += ( size % (
sizeof ( float ) * 2 ) ) ? (
sizeof (
float ) * 2 ) - ( size % (
sizeof ( float ) * 2 ) ) : 0;
75 mVariables.emplace_back ( i.name(), size );
76 size +=
sizeof ( float ) * 2;
78 case PropertyMsg::ValueCase::kVector3:
79 size += ( size % (
sizeof ( float ) * 4 ) ) ? (
sizeof (
float ) * 4 ) - ( size % (
sizeof ( float ) * 4 ) ) : 0;
80 mVariables.emplace_back ( i.name(), size );
81 size +=
sizeof ( float ) * 3;
83 case PropertyMsg::ValueCase::kVector4:
84 size += ( size % (
sizeof ( float ) * 4 ) ) ? (
sizeof (
float ) * 4 ) - ( size % (
sizeof ( float ) * 4 ) ) : 0;
85 mVariables.emplace_back ( i.name(), size );
86 size +=
sizeof ( float ) * 4;
88 case PropertyMsg::ValueCase::kMatrix4X4:
89 size += ( size % (
sizeof ( float ) * 4 ) ) ? (
sizeof (
float ) * 4 ) - ( size % (
sizeof ( float ) * 4 ) ) : 0;
90 mVariables.emplace_back ( i.name(), size );
91 size +=
sizeof ( float ) * 16;
97 size += ( size % (
sizeof ( float ) * 4 ) ) ? (
sizeof (
float ) * 4 ) - ( size % (
sizeof ( float ) * 4 ) ) : 0;
101 void Material::LoadSamplers (
const MaterialMsg& aMaterialMsg )
103 mSamplers.reserve ( aMaterialMsg.sampler().size() );
104 for (
auto& i : aMaterialMsg.sampler() )
106 std::get<1> ( mSamplers.emplace_back (
crc32i ( i.name().c_str(), i.name().size() ), ResourceId{
"Texture"_crc32, GetReferenceMsgId ( i.image() ) } ) ).Store();
112 return std::visit ( [&aLastOffset] (
auto&& arg )
114 size_t value_size =
sizeof ( std::decay_t<
decltype ( arg ) > );
115 size_t size = aLastOffset;
116 aLastOffset += value_size;
117 if ( value_size <= 4 )
119 size += ( size % 4 ) ? 4 - ( size % 4 ) : 0;
121 else if ( value_size <= 8 )
123 size += ( size % 8 ) ? 8 - ( size % 8 ) : 0;
127 size += ( size % 16 ) ? 16 - ( size % 16 ) : 0;
133 size_t Material::LoadVariables ( std::initializer_list<UniformKeyValue> aUniforms )
136 mVariables.reserve ( aUniforms.size() );
137 for (
auto& i : aUniforms )
139 mVariables.emplace_back ( std::get<0> ( i ), GetUniformValueOffset ( std::get<1> ( i ), size ) );
141 size += ( size % ( 16 ) ) ? ( 16 ) - ( size % ( 16 ) ) : 0;
145 void Material::LoadSamplers ( std::initializer_list<SamplerKeyValue> aSamplers )
147 mSamplers.reserve ( aSamplers.size() );
148 for (
auto& i : aSamplers )
150 std::get<1> ( mSamplers.emplace_back ( std::get<0> ( i ), std::get<1> ( i ) ) ).Store();
156 return std::visit ( [] (
auto&& arg )
158 return sizeof ( std::decay_t<
decltype ( arg ) > );
164 if ( std::holds_alternative<Vector2> ( aValue ) )
166 return std::get<Vector2> ( aValue ).GetVector();
168 else if ( std::holds_alternative<Vector3> ( aValue ) )
170 return std::get<Vector3> ( aValue ).GetVector3();
172 if ( std::holds_alternative<Vector4> ( aValue ) )
174 return std::get<Vector4> ( aValue ).GetVector4();
176 if ( std::holds_alternative<Matrix4x4> ( aValue ) )
178 return std::get<Matrix4x4> ( aValue ).GetMatrix4x4();
180 return std::visit ( [] (
const auto & value )
182 return reinterpret_cast<const void*
> ( &value );
193 size_t size = LoadVariables ( aMaterialMsg );
196 mUniformBuffer.resize ( size );
197 for (
auto& i : aMaterialMsg.property() )
202 LoadSamplers ( aMaterialMsg );
212 auto i = std::find_if ( mVariables.begin(), mVariables.end(),
213 [&aValue] (
const UniformVariable & variable )
215 return variable.GetName() == std::get<std::string> ( aValue );
217 if ( i != mVariables.end() )
222 if ( ( ( j != mVariables.end() ) ? ( j->GetOffset() - i->GetOffset() ) : ( mUniformBuffer.size() - i->GetOffset() ) ) < value_size )
224 std::cout <<
LogLevel::Error <<
"Value type size exceeds original type size." << std::endl;
225 throw std::runtime_error (
"Value type size exceeds original type size." );
227 memcpy ( mUniformBuffer.data() + i->GetOffset(),
GetUniformValuePointer ( std::get<UniformValue> ( aValue ) ), value_size );
233 uint32_t name_hash =
crc32i ( aName.c_str(), aName.size() );
234 auto i = std::find_if ( mSamplers.begin(), mSamplers.end(),
237 return std::get<0> ( aTuple ) == name_hash;
239 if ( i != mSamplers.end() )
241 std::get<1> ( *i ) = aValue;
252 uint32_t name_hash =
crc32i ( aName.c_str(), aName.size() );
253 auto i = std::find_if ( mSamplers.begin(), mSamplers.end(),
256 return std::get<0> ( aTuple ) == name_hash;
258 if ( i != mSamplers.end() )
260 return std::get<1> ( *i );
269 mUniformBuffer.clear();
Defines log severity levels and stream output for the AeonGames engine.
Provides the DLL_PROTOBUF export/import macro for protobuf wrapper classes.
DLL void SetSampler(const std::string &aName, const ResourceId &aValue)
Set a sampler binding by name.
DLL void Unload() final
Unload material data and release resources.
std::variant< uint32_t, int32_t, float, Vector2, Vector3, Vector4, Matrix4x4 > UniformValue
Variant type holding any supported uniform value.
DLL void Set(size_t aIndex, const UniformValue &aValue)
Set a uniform value by index.
DLL const std::vector< uint8_t > & GetUniformBuffer() const
Get the raw uniform buffer.
std::tuple< std::string, UniformValue > UniformKeyValue
Key-value pair mapping a uniform name to its value.
DLL void LoadFromMemory(const void *aBuffer, size_t aBufferSize) final
Load material data from a raw memory buffer.
DLL Material()
Default constructor.
DLL ResourceId GetSampler(const std::string &aName)
Get the resource id of a sampler by name.
DLL void LoadFromPBMsg(const MaterialMsg &aMaterialMsg)
Load material data from a protobuf message.
DLL ~Material() final
Destructor.
DLL const std::vector< std::tuple< uint32_t, ResourceId > > & GetSamplers() const
Get all sampler bindings.
std::tuple< uint32_t, ResourceId > SamplerKeyValue
Key-value pair mapping a sampler binding index to an image resource id.
DLL Material & operator=(const Material &aMaterial)
Assignment operator due to rule of zero/three/five.
Identifies a resource by its type and path CRC32 hashes.
<- This is here just for the literals
uint32_t crc32i(const char *message, size_t size, uint32_t previous_crc)
Compute the CRC32 of a given message, continuing from a previous CRC value.
DLL const void * GetUniformValuePointer(const Material::UniformValue &aValue)
Get a pointer to the raw data of a uniform value.
DLL Material::UniformKeyValue PropertyToKeyValue(const PropertyMsg &aProperty)
Convert a PropertyMsg to a Material uniform key-value pair.
DLL size_t GetUniformValueSize(const Material::UniformValue &aValue)
Get the byte size of a uniform value.
void LoadFromProtoBufObject(T &aTarget, const void *aBuffer, size_t aBufferSize)
Loads a Protocol Buffer message from a buffer and populates a target object.