1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
#pragma once
#include "EditorAttachment.hpp"
#include "RcPtr.hpp"
#include "Shader.hpp"
#include "Texture.hpp"
// #include "Ires.hpp"
#include <glad/glad.h>
#include <robin_hood.h>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <glm/glm.hpp>
#include <memory>
#include <span>
#include <string_view>
#include <vector>
// TODO migrate material editor to Ires
class MaterialManager;
class Material : public RefCounted {
public: // NOTE: public for internal helpers and editor
// NOTE: specialize between scalar vs matrix vs vector to save memory
enum UniformType : uint16_t {
UT_Scalar,
UT_Vector,
UT_Matrix,
};
struct UniformIndex {
UniformType type;
uint16_t index;
};
struct ScalarUniform {
union {
float floatValue;
int32_t intValue;
uint32_t uintValue;
};
GLenum actualType;
/* Transient */ int infoUniformIndex;
/* Transient */ GLint location;
};
struct VectorUniform {
float value[4];
int actualLength;
/* Transient */ int infoUniformIndex;
/* Transient */ GLint location;
};
struct MatrixUniform {
float value[16];
int actualWidth;
int actualHeight;
/* Transient */ int infoUniformIndex;
/* Transient */ GLint location;
};
struct TextureUniform {
RcPtr<Texture> value;
/* Transient */ int infoUniformIndex;
/* Transient */ GLint location;
};
std::string mName;
std::unique_ptr<EditorAttachment> mEditorAttachment;
RcPtr<Shader> mShader;
std::vector<ScalarUniform> mBoundScalars;
std::vector<VectorUniform> mBoundVectors;
std::vector<MatrixUniform> mBoundMatrices;
std::vector<TextureUniform> mBoundTextures;
public:
Material();
Material(std::string name);
void SetFloat(const char* name, float value);
void SetInt(const char* name, int32_t value);
void SetUInt(const char* name, uint32_t value);
/// Instanciated for length == 1, 2, 3, 4
template <int length>
void SetVector(const char* name, const glm::vec<length, float>& vec);
/// Instanciated for sizes (2,2) (3,3) (4,4) (2,3) (3,2) (2,4) (4,2) (3,4) (4,3)
template <int width, int height>
void SetMatrix(const char* name, const glm::mat<width, height, float>& mat);
void SetTexture(const char* name, Texture* texture);
std::span<const VectorUniform> GetVectors() const;
std::span<const MatrixUniform> GetMatrices() const;
std::span<const TextureUniform> GetTextures() const;
Shader* GetShader() const;
void SetShader(Shader* shader);
const std::string& GetName() const;
bool IsAnnoymous() const;
bool IsValid() const;
void UseUniforms() const;
EditorAttachment* GetEditorAttachment() const { return mEditorAttachment.get(); }
void SetEditorAttachment(EditorAttachment* attachment) { mEditorAttachment.reset(attachment); }
void GetDesignatedPath(char* buffer, int bufferSize);
std::filesystem::path GetDesignatedPath();
bool SaveToFile(const std::filesystem::path& filePath) const;
bool LoadFromFile(const std::filesystem::path& filePath);
};
// class IresMaterial : public IresObject {
// public:
// RcPtr<Material> mInstance;
// public:
// IresMaterial()
// : IresObject(KD_Spritesheet) {}
// bool IsValid() const;
// Material* CreateInstance() const;
// Material* GetInstance();
// void InvalidateInstance();
// void ShowEditor() override;
// void Write(rapidjson::Value& value, rapidjson::Document& root) const override;
// void Read(const rapidjson::Value& value) override;
// };
class MaterialManager {
public:
static inline MaterialManager* instance = nullptr;
private:
robin_hood::unordered_map<std::string_view, RcPtr<Material>> mMaterials;
public:
void DiscoverMaterials();
std::pair<Material*, bool> SaveMaterial(Material* mat);
void DeleteMaterial(Material* mat, bool onDisk = false);
Material* LoadMaterial(std::string_view name);
bool RenameMaterial(Material* mat, std::string newName);
const auto& GetMaterials() const { return mMaterials; }
Material* FindMaterial(std::string_view name);
};
|