Skip to content

Commit 6aab04c

Browse files
authored
Add ResourceInspector (#62)
* Add ResourceInspector * Use ResourceInspector in SceneInspector - Dispatch texture inspection in materials to `ResourceInspector`.
1 parent e7d02d5 commit 6aab04c

File tree

13 files changed

+169
-42
lines changed

13 files changed

+169
-42
lines changed

lib/engine/include/facade/engine/editor/inspector.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77
#include <limits>
88

99
namespace facade {
10+
struct Camera;
1011
struct Mesh;
1112
struct Lights;
13+
struct SceneResources;
1214
class Scene;
1315

1416
namespace editor {
@@ -58,6 +60,24 @@ class SceneInspector : public Inspector {
5860

5961
private:
6062
Scene& m_scene;
63+
NotClosed<Window> m_target;
64+
};
65+
66+
class ResourceInspector {
67+
public:
68+
ResourceInspector(NotClosed<Window>, SceneResources const& resources);
69+
70+
void display() const;
71+
void display(Camera const& camera, std::size_t index, std::string_view prefix = {}) const;
72+
void display(Texture const& texture, std::size_t index, std::string_view prefix = {}) const;
73+
void display(Material const& material, std::size_t const index, std::string_view prefix = {}) const;
74+
void display(Mesh const& mesh, std::size_t const index, std::string_view prefix = {}) const;
75+
76+
private:
77+
void display(LitMaterial const& lit) const;
78+
void display(UnlitMaterial const& unlit) const;
79+
80+
SceneResources const& m_resources;
6181
};
6282
} // namespace editor
6383
} // namespace facade

lib/engine/src/editor/inspector.cpp

Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ bool Inspector::do_inspect(Transform& out_transform, Bool& out_unified_scaling,
163163
return ret.value;
164164
}
165165

166-
SceneInspector::SceneInspector(NotClosed<Window> target, Scene& scene) : Inspector(target), m_scene(scene) {}
166+
SceneInspector::SceneInspector(NotClosed<Window> target, Scene& scene) : Inspector(target), m_scene(scene), m_target(target) {}
167167

168168
bool SceneInspector::inspect(NotClosed<TreeNode>, UnlitMaterial& out_material) const {
169169
auto ret = Modified{};
@@ -177,15 +177,14 @@ bool SceneInspector::inspect(NotClosed<TreeNode>, LitMaterial& out_material) con
177177
ret(ImGui::SliderFloat("Roughness", &out_material.roughness, 0.0f, 1.0f));
178178
ret(inspect_rgb("Albedo", out_material.albedo));
179179
if (out_material.base_colour || out_material.roughness_metallic) {
180-
if (auto tn = TreeNode{"Textures"}) {
181-
if (out_material.base_colour) {
182-
auto const* tex = m_scene.find(*out_material.base_colour);
183-
TreeNode::leaf(FixedString{"Albedo: {} ({})", tex->name, *out_material.base_colour}.c_str());
184-
}
185-
if (out_material.roughness_metallic) {
186-
auto const* tex = m_scene.find(*out_material.roughness_metallic);
187-
TreeNode::leaf(FixedString{"Roughness-Metallic: {} ({})", tex->name, *out_material.roughness_metallic}.c_str());
188-
}
180+
auto const ri = ResourceInspector{m_target, m_scene.resources()};
181+
if (out_material.base_colour) {
182+
auto const* tex = m_scene.find(*out_material.base_colour);
183+
ri.display(*tex, *out_material.base_colour, "Base Colour: ");
184+
}
185+
if (out_material.roughness_metallic) {
186+
auto const* tex = m_scene.find(*out_material.roughness_metallic);
187+
ri.display(*tex, *out_material.roughness_metallic, "Roughness Metallic: ");
189188
}
190189
}
191190
return ret.value;
@@ -228,4 +227,92 @@ bool SceneInspector::inspect(Id<Node> node_id, Bool& out_unified_scaling) const
228227
if (auto const* mesh_id = node->find<Id<Mesh>>()) { ret(inspect(*mesh_id)); }
229228
return ret.value;
230229
}
230+
231+
namespace {
232+
template <typename Named>
233+
void display_resource(Named const& named, std::size_t const index, std::string_view prefix = {}) {
234+
editor::TreeNode::leaf(FixedString<128>{"{}{} ({})", prefix, named.name(), index}.c_str());
235+
}
236+
} // namespace
237+
238+
ResourceInspector::ResourceInspector(NotClosed<Window>, Scene::Resources const& resources) : m_resources(resources) {}
239+
240+
void ResourceInspector::display() const {
241+
static constexpr auto flags_v = ImGuiTreeNodeFlags_Framed;
242+
if (auto tn = editor::TreeNode("Cameras", flags_v)) {
243+
for (auto const [camera, index] : enumerate(m_resources.cameras)) { display(camera, index); }
244+
}
245+
if (auto tn = editor::TreeNode("Samplers", flags_v)) {
246+
for (auto const [sampler, index] : enumerate(m_resources.samplers)) { display_resource(sampler, index); }
247+
}
248+
if (auto tn = editor::TreeNode("Textures", flags_v)) {
249+
for (auto const [texture, index] : enumerate(m_resources.textures)) { display(texture, index); }
250+
}
251+
if (auto tn = editor::TreeNode("Materials", flags_v)) {
252+
for (auto const [material, index] : enumerate(m_resources.materials)) { display(*material, index); }
253+
}
254+
if (auto tn = editor::TreeNode("Static Meshes", flags_v)) {
255+
for (auto const [mesh, index] : enumerate(m_resources.static_meshes)) { display_resource(mesh, index); }
256+
}
257+
if (auto tn = editor::TreeNode("Meshes", flags_v)) {
258+
for (auto const [mesh, index] : enumerate(m_resources.meshes)) { display(mesh, index); }
259+
}
260+
}
261+
262+
void ResourceInspector::display(Camera const& camera, std::size_t index, std::string_view prefix) const {
263+
if (auto tn = editor::TreeNode{FixedString<128>{"{}{} ({})", prefix, camera.name, index}.c_str()}) {
264+
auto const visitor = Visitor{
265+
[](Camera::Orthographic const& o) {
266+
ImGui::Text("%s", FixedString{"Near Plane: {}", o.view_plane.near}.c_str());
267+
ImGui::Text("%s", FixedString{"Far Plane: {}", o.view_plane.near}.c_str());
268+
},
269+
[](Camera::Perspective const& p) {
270+
ImGui::Text("%s", FixedString{"FoV: {}", p.field_of_view}.c_str());
271+
ImGui::Text("%s", FixedString{"Near Plane: {}", p.view_plane.near}.c_str());
272+
ImGui::Text("%s", FixedString{"Far Plane: {}", p.view_plane.near}.c_str());
273+
},
274+
};
275+
std::visit(visitor, camera.type);
276+
}
277+
}
278+
279+
void ResourceInspector::display(Texture const& texture, std::size_t index, std::string_view prefix) const {
280+
if (auto tn = editor::TreeNode{FixedString<128>{"{}{} ({})", prefix, texture.name(), index}.c_str()}) {
281+
auto const view = texture.view();
282+
editor::TreeNode::leaf(FixedString{"Extent: {}x{}", view.extent.width, view.extent.height}.c_str());
283+
editor::TreeNode::leaf(FixedString{"Mip levels: {}", texture.mip_levels()}.c_str());
284+
auto const cs = texture.colour_space() == ColourSpace::eLinear ? "linear" : "sRGB";
285+
editor::TreeNode::leaf(FixedString{"Colour Space: {}", cs}.c_str());
286+
}
287+
}
288+
289+
void ResourceInspector::display(Material const& material, std::size_t const index, std::string_view prefix) const {
290+
if (auto tn = editor::TreeNode{FixedString<128>{"{}{} ({})", prefix, material.name, index}.c_str()}) {
291+
if (auto const* lit = dynamic_cast<LitMaterial const*>(&material)) { return display(*lit); }
292+
if (auto const* unlit = dynamic_cast<UnlitMaterial const*>(&material)) { return display(*unlit); }
293+
}
294+
}
295+
296+
void ResourceInspector::display(Mesh const& mesh, std::size_t const index, std::string_view prefix) const {
297+
if (auto tn = editor::TreeNode{FixedString<128>{"{}{} ({})", prefix, mesh.name, index}.c_str()}) {
298+
for (auto const primitive : mesh.primitives) {
299+
display_resource(m_resources.static_meshes[primitive.static_mesh], primitive.static_mesh, "Static Mesh: ");
300+
if (primitive.material) { display(*m_resources.materials[*primitive.material], *primitive.material, "Material: "); }
301+
}
302+
}
303+
}
304+
305+
void ResourceInspector::display(LitMaterial const& lit) const {
306+
ImGui::Text("Albedo: ");
307+
ImGui::SameLine();
308+
ImGui::ColorButton("Albedo", {lit.albedo.x, lit.albedo.y, lit.albedo.z, 1.0f});
309+
ImGui::Text("%s", FixedString{"Metallic: {:.2f}", lit.metallic}.c_str());
310+
ImGui::Text("%s", FixedString{"Roughness: {:.2f}", lit.roughness}.c_str());
311+
if (lit.base_colour) { display(m_resources.textures[*lit.base_colour], *lit.base_colour, "Base Colour: "); }
312+
if (lit.roughness_metallic) { display(m_resources.textures[*lit.roughness_metallic], *lit.roughness_metallic, "Roughness Metallic: "); }
313+
}
314+
315+
void ResourceInspector::display(UnlitMaterial const& unlit) const {
316+
if (unlit.texture) { display(m_resources.textures[*unlit.texture], *unlit.texture, "Texture: "); }
317+
}
231318
} // namespace facade::editor

lib/scene/include/facade/scene/mesh.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct Mesh {
2424
std::optional<Id<Material>> material{};
2525
};
2626

27+
std::string name{"(unnamed)"};
2728
///
2829
/// \brief List of primitives in this mesh.
2930
///

lib/scene/include/facade/scene/scene.hpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ struct AtomicLoadStatus {
4343
}
4444
};
4545

46+
///
47+
/// \brief Immutable view of the resources stored in the scene.
48+
///
49+
struct SceneResources {
50+
std::span<Camera const> cameras{};
51+
std::span<Sampler const> samplers{};
52+
std::span<std::unique_ptr<Material> const> materials{};
53+
std::span<StaticMesh const> static_meshes{};
54+
std::span<Texture const> textures{};
55+
std::span<Mesh const> meshes{};
56+
};
57+
4658
///
4759
/// \brief Models a 3D scene.
4860
///
@@ -51,23 +63,13 @@ struct AtomicLoadStatus {
5163
///
5264
class Scene {
5365
public:
66+
using Resources = SceneResources;
67+
5468
///
5569
/// \brief Represents a single GTLF scene.
5670
///
5771
struct Tree {};
5872

59-
///
60-
/// \brief Immutable view of the resources stored in the scene.
61-
///
62-
struct Resources {
63-
std::span<Camera const> cameras{};
64-
std::span<Sampler const> samplers{};
65-
std::span<std::unique_ptr<Material> const> materials{};
66-
std::span<StaticMesh const> static_meshes{};
67-
std::span<Texture const> textures{};
68-
std::span<Mesh const> meshes{};
69-
};
70-
7173
///
7274
/// \brief "Null" Id for a Node: refers to no Node.
7375
///
@@ -118,7 +120,7 @@ class Scene {
118120
/// \param geometry Geometry to initialize StaticMesh with
119121
/// \returns Id to stored StaticMesh
120122
///
121-
Id<StaticMesh> add(Geometry const& geometry);
123+
Id<StaticMesh> add(Geometry const& geometry, std::string name = "(unnamed)");
122124
///
123125
/// \brief Add a Texture.
124126
/// \param image Image to use for the Texture

lib/scene/src/detail/gltf.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ struct Mesh {
8282
std::optional<std::size_t> material{};
8383
};
8484

85-
std::string name{};
85+
std::string name{"(unnamed)"};
8686
std::vector<Primitive> primitives{};
8787
};
8888

lib/scene/src/scene.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ std::unique_ptr<Material> to_material(gltf::Material const& material) {
6666
return ret;
6767
}
6868

69-
Mesh to_mesh(gltf::Mesh const& mesh) {
70-
auto ret = Mesh{};
69+
Mesh to_mesh(gltf::Mesh mesh) {
70+
auto ret = Mesh{.name = std::move(mesh.name)};
7171
for (auto const& primitive : mesh.primitives) {
7272
ret.primitives.push_back(Mesh::Primitive{.static_mesh = primitive.geometry, .material = primitive.material});
7373
}
@@ -182,8 +182,9 @@ bool Scene::load_gltf(dj::Json const& root, DataProvider const& provider, Atomic
182182
return m_storage.samplers[*sampler_id].sampler();
183183
};
184184
for (auto& texture : asset.textures) {
185-
auto const tci = Texture::CreateInfo{.mip_mapped = true, .colour_space = texture.colour_space};
186-
m_storage.textures.emplace_back(m_gfx, get_sampler(texture.sampler), images.at(texture.source), tci).name = std::move(texture.name);
185+
bool const mip_mapped = texture.colour_space == ColourSpace::eSrgb;
186+
auto const tci = Texture::CreateInfo{.name = std::move(texture.name), .mip_mapped = mip_mapped, .colour_space = texture.colour_space};
187+
m_storage.textures.emplace_back(m_gfx, get_sampler(texture.sampler), images.at(texture.source), tci);
187188
if (out_status) { ++out_status->done; }
188189
}
189190

@@ -201,7 +202,7 @@ bool Scene::load_gltf(dj::Json const& root, DataProvider const& provider, Atomic
201202
}
202203
for (auto const& sampler : asset.samplers) { add(to_sampler_info(sampler)); }
203204
for (auto const& material : asset.materials) { add(to_material(material)); }
204-
for (auto const& mesh : asset.meshes) { add(to_mesh(mesh)); }
205+
for (auto& mesh : asset.meshes) { add(to_mesh(std::move(mesh))); }
205206

206207
m_storage.data.nodes = std::move(asset.nodes);
207208
for (auto& scene : asset.scenes) { m_storage.data.trees.push_back(TreeImpl::Data{.roots = std::move(scene.root_nodes)}); }
@@ -231,9 +232,9 @@ Id<Material> Scene::add(std::unique_ptr<Material> material) {
231232
return id;
232233
}
233234

234-
Id<StaticMesh> Scene::add(Geometry const& geometry) {
235+
Id<StaticMesh> Scene::add(Geometry const& geometry, std::string name) {
235236
auto const id = m_storage.static_meshes.size();
236-
m_storage.static_meshes.emplace_back(m_gfx, geometry);
237+
m_storage.static_meshes.emplace_back(m_gfx, geometry, std::move(name));
237238
return id;
238239
}
239240

lib/vk/include/facade/vk/static_mesh.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ struct Geometry;
88

99
class StaticMesh {
1010
public:
11-
StaticMesh(Gfx const& gfx, Geometry const& geometry);
11+
StaticMesh(Gfx const& gfx, Geometry const& geometry, std::string name = "(unnamed)");
1212

13+
std::string_view name() const { return m_name; }
1314
MeshView view() const;
1415
operator MeshView() const { return view(); }
1516

1617
private:
1718
BufferView vbo() const;
1819
BufferView ibo() const;
1920

21+
std::string m_name{};
2022
Defer<UniqueBuffer> m_buffer{};
2123
std::size_t m_vbo_size{};
2224
std::uint32_t m_vertices{};

lib/vk/include/facade/vk/texture.hpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77

88
namespace facade {
99
struct SamplerCreateInfo {
10+
std::string name{"(unnamed)"};
1011
vk::SamplerAddressMode mode_s{vk::SamplerAddressMode::eRepeat};
1112
vk::SamplerAddressMode mode_t{vk::SamplerAddressMode::eRepeat};
1213
vk::Filter min{vk::Filter::eLinear};
1314
vk::Filter mag{vk::Filter::eLinear};
1415
};
1516

1617
struct TextureCreateInfo {
18+
std::string name{"(unnamed)"};
1719
bool mip_mapped{true};
1820
ColourSpace colour_space{ColourSpace::eSrgb};
1921
};
@@ -22,11 +24,13 @@ class Sampler {
2224
public:
2325
using CreateInfo = SamplerCreateInfo;
2426

25-
explicit Sampler(Gfx const& gfx, CreateInfo const& info = {});
27+
explicit Sampler(Gfx const& gfx, CreateInfo info = {});
2628

29+
std::string_view name() const { return m_name; }
2730
vk::Sampler sampler() const { return *m_sampler.get(); }
2831

2932
private:
33+
std::string m_name{};
3034
Defer<vk::UniqueSampler> m_sampler{};
3135
};
3236

@@ -36,20 +40,21 @@ class Texture {
3640

3741
static std::uint32_t mip_levels(vk::Extent2D extent);
3842

39-
Texture(Gfx const& gfx, vk::Sampler sampler, Image::View image, CreateInfo const& info = {});
43+
Texture(Gfx const& gfx, vk::Sampler sampler, Image::View image, CreateInfo info = {});
4044

45+
std::string_view name() const { return m_name; }
4146
ImageView view() const { return m_image.get().get().image_view(); }
4247
DescriptorImage descriptor_image() const { return {*m_image.get().get().view, sampler}; }
4348
std::uint32_t mip_levels() const { return m_info.mip_levels; }
4449
ColourSpace colour_space() const { return is_linear(m_info.format) ? ColourSpace::eLinear : ColourSpace::eSrgb; }
4550

46-
std::string name{"(Unnamed)"};
4751
vk::Sampler sampler{};
4852

4953
private:
5054
Defer<UniqueImage> m_image{};
5155
Gfx m_gfx{};
5256
ImageCreateInfo m_info{};
5357
vk::ImageLayout m_layout{vk::ImageLayout::eUndefined};
58+
std::string m_name{};
5459
};
5560
} // namespace facade

lib/vk/src/static_mesh.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace {
88
constexpr auto flags_v = vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst;
99
} // namespace
1010

11-
StaticMesh::StaticMesh(Gfx const& gfx, Geometry const& geometry) : m_buffer{gfx.shared->defer_queue} {
11+
StaticMesh::StaticMesh(Gfx const& gfx, Geometry const& geometry, std::string name) : m_name(std::move(name)), m_buffer{gfx.shared->defer_queue} {
1212
auto const vertices = std::span<Vertex const>{geometry.vertices};
1313
auto const indices = std::span<std::uint32_t const>{geometry.indices};
1414
m_vertices = static_cast<std::uint32_t>(vertices.size());

lib/vk/src/texture.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ bool can_mip(vk::PhysicalDevice const gpu, vk::Format const format) {
8888
}
8989
} // namespace
9090

91-
Sampler::Sampler(Gfx const& gfx, CreateInfo const& info) {
91+
Sampler::Sampler(Gfx const& gfx, CreateInfo info) {
9292
auto sci = vk::SamplerCreateInfo{};
9393
sci.minFilter = info.min;
9494
sci.magFilter = info.mag;
@@ -101,11 +101,12 @@ Sampler::Sampler(Gfx const& gfx, CreateInfo const& info) {
101101
sci.addressModeW = info.mode_s;
102102
sci.maxLod = VK_LOD_CLAMP_NONE;
103103
m_sampler = {gfx.device.createSamplerUnique(sci), gfx.shared->defer_queue};
104+
m_name = std::move(info.name);
104105
}
105106

106107
std::uint32_t Texture::mip_levels(vk::Extent2D extent) { return static_cast<std::uint32_t>(std::floor(std::log2(std::max(extent.width, extent.height)))) + 1U; }
107108

108-
Texture::Texture(Gfx const& gfx, vk::Sampler sampler, Image::View image, CreateInfo const& info) : sampler{sampler}, m_gfx{gfx} {
109+
Texture::Texture(Gfx const& gfx, vk::Sampler sampler, Image::View image, CreateInfo info) : sampler{sampler}, m_gfx{gfx}, m_name(std::move(info.name)) {
109110
static constexpr std::uint8_t magenta_v[] = {0xff, 0x0, 0xff, 0xff};
110111
m_info.format = info.colour_space == ColourSpace::eLinear ? vk::Format::eR8G8B8A8Unorm : vk::Format::eR8G8B8A8Srgb;
111112
bool mip_mapped = info.mip_mapped;

0 commit comments

Comments
 (0)