-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathasset-loader.cpp
More file actions
154 lines (142 loc) · 6.41 KB
/
Copy pathasset-loader.cpp
File metadata and controls
154 lines (142 loc) · 6.41 KB
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
#include "asset-loader.hpp"
#include "audio/audio-buffer.hpp"
#include "audio/audio-utils.hpp"
#include "deserialize-utils.hpp"
#include "material/material.hpp"
#include "mesh/mesh-utils.hpp"
#include "mesh/mesh.hpp"
#include "shader/shader.hpp"
#include "texture/sampler.hpp"
#include "texture/texture-utils.hpp"
#include "texture/texture2d.hpp"
namespace our {
// This will load all the shaders defined in "data"
// data must be in the form:
// { shader_name : { "vs" : "path/to/vertex-shader", "fs" : "path/to/fragment-shader" }, ... }
template <>
void AssetLoader<ShaderProgram>::deserialize(const nlohmann::json& data) {
if (data.is_object()) {
for (auto& [name, desc] : data.items()) {
std::string vsPath = desc.value("vs", "");
std::string fsPath = desc.value("fs", "");
auto shader = new ShaderProgram();
shader->attach(vsPath, GL_VERTEX_SHADER);
shader->attach(fsPath, GL_FRAGMENT_SHADER);
shader->link();
assets[name] = shader;
}
}
};
// This will load all the textures defined in "data"
// data must be in the form:
// { texture_name : "path/to/image", ... }
template <>
void AssetLoader<Texture2D>::deserialize(const nlohmann::json& data) {
if (data.is_object()) {
for (auto& [name, desc] : data.items()) {
std::string path = desc.get<std::string>();
assets[name] = texture_utils::loadImage(path);
}
}
};
// This will load all the samplers defined in "data"
// data must be in the form:
// { sampler_name : parameters, ... }
// Where parameters is an object where:
// The key is the parameter name, e.g. "MAG_FILTER", "MIN_FILTER", "WRAP_S", "WRAP_T" or "MAX_ANISOTROPY"
// The value is the parameter value, e.g. "GL_NEAREST", "GL_REPEAT"
// For "MAX_ANISOTROPY", the value must be a float with a value >= 1.0f
template <>
void AssetLoader<Sampler>::deserialize(const nlohmann::json& data) {
if (data.is_object()) {
for (auto& [name, desc] : data.items()) {
auto sampler = new Sampler();
sampler->deserialize(desc);
assets[name] = sampler;
}
}
};
// This will load all the meshes defined in "data"
// data must be in the form:
// { mesh_name : "path/to/3d-model-file", ... }
template <>
void AssetLoader<Mesh>::deserialize(const nlohmann::json& data) {
if (data.is_object()) {
for (auto& [name, desc] : data.items()) {
std::string path = desc.get<std::string>();
assets[name] = mesh_utils::loadOBJ(path);
}
}
};
// This will load all the materials defined in "data"
// Material deserialization depends on shaders, textures and samplers
// so you must deserialize these 3 asset types before deserializing materials
// data must be in the form:
// { material_name : parameters, ... }
// Where parameters is an object where the keys can be:
// "type" where the value is a string defining the type of the material.
// the type will decide which class will be instanced in the function "createMaterialFromType" found in
// "material.hpp"
// "shader" where the value must be the name of a loaded shader
// "pipelineState" (optional) where the value is a json object that can be read by "PipelineState::deserialize"
// "transparent" (optional, default=false) where the value is a boolean indicating whether the material is
// transparent or not
// ... more keys/values can be added depending on the material type (e.g. "texture", "sampler", "tint")
template <>
void AssetLoader<Material>::deserialize(const nlohmann::json& data) {
if (data.is_object()) {
for (auto& [name, desc] : data.items()) {
std::string type = desc.value("type", "");
auto material = createMaterialFromType(type);
material->deserialize(desc);
assets[name] = material;
}
}
};
// This will load all the audio buffers defined in "data"
// data must be in the form:
// { sound_name : "path/to/audio-file", ... }
template <>
void AssetLoader<AudioBuffer>::deserialize(const nlohmann::json& data) {
if (data.is_object()) {
for (auto& [name, desc] : data.items()) {
std::string path = desc.get<std::string>();
AudioBuffer* buffer = audio_utils::loadWAV(path);
if (buffer) assets[name] = buffer;
}
}
}
template <>
void AssetLoader<our::Light>::deserialize(const nlohmann::json& data) {
if (data.is_object()) {
for (auto& [name, desc] : data.items()) {
our::Light* light = new our::Light();
light->deserialize(desc);
assets[name] = light;
}
}
};
void deserializeAllAssets(const nlohmann::json& assetData) {
if (!assetData.is_object()) return;
if (assetData.contains("shaders")) AssetLoader<ShaderProgram>::deserialize(assetData["shaders"]);
if (assetData.contains("textures")) AssetLoader<Texture2D>::deserialize(assetData["textures"]);
if (assetData.contains("samplers")) AssetLoader<Sampler>::deserialize(assetData["samplers"]);
if (assetData.contains("meshes")) AssetLoader<Mesh>::deserialize(assetData["meshes"]);
if (assetData.contains("materials")) AssetLoader<Material>::deserialize(assetData["materials"]);
if (assetData.contains("sounds")) AssetLoader<AudioBuffer>::deserialize(assetData["sounds"]);
if (assetData.contains("lights")) AssetLoader<our::Light>::deserialize(assetData["lights"]);
// setting some default assets if something is missing
if (!AssetLoader<Sampler>::get("default")) {
Sampler* defaultSampler = new Sampler();
AssetLoader<Sampler>::add("default", defaultSampler);
}
}
void clearAllAssets() {
AssetLoader<ShaderProgram>::clear();
AssetLoader<Texture2D>::clear();
AssetLoader<Sampler>::clear();
AssetLoader<Mesh>::clear();
AssetLoader<Material>::clear();
AssetLoader<AudioBuffer>::clear();
}
} // namespace our