1+ #pragma once
2+
3+ #include " AssetSerializeTraits.h"
4+
5+ #include " Mahakam/BinarySerialization/AssetIDSerialization.h"
6+ #include " Mahakam/BinarySerialization/ContainerSerialization.h"
7+ #include " Mahakam/BinarySerialization/MathSerialization.h"
8+
9+ #include " Mahakam/Renderer/Material.h"
10+ #include " Mahakam/Renderer/Shader.h"
11+
12+ namespace Mahakam ::Serialization
13+ {
14+ template <>
15+ struct AssetSerializeTraits <Material>
16+ {
17+ template <auto F, typename Stream>
18+ static bool write_value (Stream& stream, const Material& material, const std::string& name) noexcept
19+ {
20+ return stream.serialize ((material.*F)(name));
21+ }
22+
23+ template <auto F, typename T, typename Stream>
24+ static bool read_value (Stream& stream, Material& material, const std::string& name) noexcept
25+ {
26+ T value;
27+ if (!stream.serialize (value))
28+ return false ;
29+
30+ (material.*F)(name, value);
31+
32+ return true ;
33+ }
34+
35+ template <typename Stream>
36+ static bool serialize (Stream& stream, inout<Stream, Asset<Material>> material) noexcept
37+ {
38+ if constexpr (Stream::writing)
39+ {
40+ MH_SER_ASSERT (stream.serialize (material->GetShader ()));
41+
42+ auto & properties = material->GetShader ()->GetProperties ();
43+ for (auto & kv : properties)
44+ {
45+ switch (kv.second .DataType )
46+ {
47+ case ShaderDataType::Float: MH_SER_ASSERT (write_value<&Material::GetFloat>(stream, *material, kv.first )); break ;
48+ case ShaderDataType::Float2: MH_SER_ASSERT (write_value<&Material::GetFloat2>(stream, *material, kv.first )); break ;
49+ case ShaderDataType::Float3: MH_SER_ASSERT (write_value<&Material::GetFloat3>(stream, *material, kv.first )); break ;
50+ case ShaderDataType::Float4: MH_SER_ASSERT (write_value<&Material::GetFloat4>(stream, *material, kv.first )); break ;
51+ case ShaderDataType::Mat3: MH_SER_ASSERT (write_value<&Material::GetMat3>(stream, *material, kv.first )); break ;
52+ case ShaderDataType::Mat4: MH_SER_ASSERT (write_value<&Material::GetMat4>(stream, *material, kv.first )); break ;
53+ case ShaderDataType::Int: MH_SER_ASSERT (write_value<&Material::GetInt>(stream, *material, kv.first )); break ;
54+ case ShaderDataType::Sampler2D: MH_SER_ASSERT (write_value<&Material::GetTexture>(stream, *material, kv.first )); break ;
55+ case ShaderDataType::SamplerCube: MH_SER_ASSERT (write_value<&Material::GetTexture>(stream, *material, kv.first )); break ;
56+ default : break ;
57+ }
58+ }
59+ }
60+ else
61+ {
62+ Asset<Shader> shader;
63+ MH_SER_ASSERT (stream.serialize (shader));
64+
65+ material = Material::Create (shader);
66+
67+ auto & properties = shader->GetProperties ();
68+ for (auto & kv : properties)
69+ {
70+ switch (kv.second .DataType )
71+ {
72+ case ShaderDataType::Float: MH_SER_ASSERT (read_value<&Material::SetFloat, float >(stream, *material, kv.first )); break ;
73+ case ShaderDataType::Float2: MH_SER_ASSERT (read_value<&Material::SetFloat2, glm::vec2>(stream, *material, kv.first )); break ;
74+ case ShaderDataType::Float3: MH_SER_ASSERT (read_value<&Material::SetFloat3, glm::vec3>(stream, *material, kv.first )); break ;
75+ case ShaderDataType::Float4: MH_SER_ASSERT (read_value<&Material::SetFloat4, glm::vec4>(stream, *material, kv.first )); break ;
76+ case ShaderDataType::Mat3: MH_SER_ASSERT (read_value<&Material::SetMat3, glm::mat3>(stream, *material, kv.first )); break ;
77+ case ShaderDataType::Mat4: MH_SER_ASSERT (read_value<&Material::SetMat4, glm::mat4>(stream, *material, kv.first )); break ;
78+ case ShaderDataType::Int: MH_SER_ASSERT (read_value<&Material::SetInt, int32_t >(stream, *material, kv.first )); break ;
79+ case ShaderDataType::Sampler2D:
80+ case ShaderDataType::SamplerCube:
81+ {
82+ Asset<Texture> texture;
83+ MH_SER_ASSERT (stream.serialize (texture));
84+ material->SetTexture (kv.first , 0 , texture);
85+ break ;
86+ }
87+ default : break ;
88+ }
89+ }
90+ }
91+
92+ return true ;
93+ }
94+ };
95+ }
0 commit comments