Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions lib/engine/include/facade/engine/editor/inspector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
#include <limits>

namespace facade {
struct Camera;
struct Mesh;
struct Lights;
struct SceneResources;
class Scene;

namespace editor {
Expand Down Expand Up @@ -58,6 +60,24 @@ class SceneInspector : public Inspector {

private:
Scene& m_scene;
NotClosed<Window> m_target;
};

class ResourceInspector {
public:
ResourceInspector(NotClosed<Window>, SceneResources const& resources);

void display() const;
void display(Camera const& camera, std::size_t index, std::string_view prefix = {}) const;
void display(Texture const& texture, std::size_t index, std::string_view prefix = {}) const;
void display(Material const& material, std::size_t const index, std::string_view prefix = {}) const;
void display(Mesh const& mesh, std::size_t const index, std::string_view prefix = {}) const;

private:
void display(LitMaterial const& lit) const;
void display(UnlitMaterial const& unlit) const;

SceneResources const& m_resources;
};
} // namespace editor
} // namespace facade
107 changes: 97 additions & 10 deletions lib/engine/src/editor/inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ bool Inspector::do_inspect(Transform& out_transform, Bool& out_unified_scaling,
return ret.value;
}

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

bool SceneInspector::inspect(NotClosed<TreeNode>, UnlitMaterial& out_material) const {
auto ret = Modified{};
Expand All @@ -177,15 +177,14 @@ bool SceneInspector::inspect(NotClosed<TreeNode>, LitMaterial& out_material) con
ret(ImGui::SliderFloat("Roughness", &out_material.roughness, 0.0f, 1.0f));
ret(inspect_rgb("Albedo", out_material.albedo));
if (out_material.base_colour || out_material.roughness_metallic) {
if (auto tn = TreeNode{"Textures"}) {
if (out_material.base_colour) {
auto const* tex = m_scene.find(*out_material.base_colour);
TreeNode::leaf(FixedString{"Albedo: {} ({})", tex->name, *out_material.base_colour}.c_str());
}
if (out_material.roughness_metallic) {
auto const* tex = m_scene.find(*out_material.roughness_metallic);
TreeNode::leaf(FixedString{"Roughness-Metallic: {} ({})", tex->name, *out_material.roughness_metallic}.c_str());
}
auto const ri = ResourceInspector{m_target, m_scene.resources()};
if (out_material.base_colour) {
auto const* tex = m_scene.find(*out_material.base_colour);
ri.display(*tex, *out_material.base_colour, "Base Colour: ");
}
if (out_material.roughness_metallic) {
auto const* tex = m_scene.find(*out_material.roughness_metallic);
ri.display(*tex, *out_material.roughness_metallic, "Roughness Metallic: ");
}
}
return ret.value;
Expand Down Expand Up @@ -228,4 +227,92 @@ bool SceneInspector::inspect(Id<Node> node_id, Bool& out_unified_scaling) const
if (auto const* mesh_id = node->find<Id<Mesh>>()) { ret(inspect(*mesh_id)); }
return ret.value;
}

namespace {
template <typename Named>
void display_resource(Named const& named, std::size_t const index, std::string_view prefix = {}) {
editor::TreeNode::leaf(FixedString<128>{"{}{} ({})", prefix, named.name(), index}.c_str());
}
} // namespace

ResourceInspector::ResourceInspector(NotClosed<Window>, Scene::Resources const& resources) : m_resources(resources) {}

void ResourceInspector::display() const {
static constexpr auto flags_v = ImGuiTreeNodeFlags_Framed;
if (auto tn = editor::TreeNode("Cameras", flags_v)) {
for (auto const [camera, index] : enumerate(m_resources.cameras)) { display(camera, index); }
}
if (auto tn = editor::TreeNode("Samplers", flags_v)) {
for (auto const [sampler, index] : enumerate(m_resources.samplers)) { display_resource(sampler, index); }
}
if (auto tn = editor::TreeNode("Textures", flags_v)) {
for (auto const [texture, index] : enumerate(m_resources.textures)) { display(texture, index); }
}
if (auto tn = editor::TreeNode("Materials", flags_v)) {
for (auto const [material, index] : enumerate(m_resources.materials)) { display(*material, index); }
}
if (auto tn = editor::TreeNode("Static Meshes", flags_v)) {
for (auto const [mesh, index] : enumerate(m_resources.static_meshes)) { display_resource(mesh, index); }
}
if (auto tn = editor::TreeNode("Meshes", flags_v)) {
for (auto const [mesh, index] : enumerate(m_resources.meshes)) { display(mesh, index); }
}
}

void ResourceInspector::display(Camera const& camera, std::size_t index, std::string_view prefix) const {
if (auto tn = editor::TreeNode{FixedString<128>{"{}{} ({})", prefix, camera.name, index}.c_str()}) {
auto const visitor = Visitor{
[](Camera::Orthographic const& o) {
ImGui::Text("%s", FixedString{"Near Plane: {}", o.view_plane.near}.c_str());
ImGui::Text("%s", FixedString{"Far Plane: {}", o.view_plane.near}.c_str());
},
[](Camera::Perspective const& p) {
ImGui::Text("%s", FixedString{"FoV: {}", p.field_of_view}.c_str());
ImGui::Text("%s", FixedString{"Near Plane: {}", p.view_plane.near}.c_str());
ImGui::Text("%s", FixedString{"Far Plane: {}", p.view_plane.near}.c_str());
},
};
std::visit(visitor, camera.type);
}
}

void ResourceInspector::display(Texture const& texture, std::size_t index, std::string_view prefix) const {
if (auto tn = editor::TreeNode{FixedString<128>{"{}{} ({})", prefix, texture.name(), index}.c_str()}) {
auto const view = texture.view();
editor::TreeNode::leaf(FixedString{"Extent: {}x{}", view.extent.width, view.extent.height}.c_str());
editor::TreeNode::leaf(FixedString{"Mip levels: {}", texture.mip_levels()}.c_str());
auto const cs = texture.colour_space() == ColourSpace::eLinear ? "linear" : "sRGB";
editor::TreeNode::leaf(FixedString{"Colour Space: {}", cs}.c_str());
}
}

void ResourceInspector::display(Material const& material, std::size_t const index, std::string_view prefix) const {
if (auto tn = editor::TreeNode{FixedString<128>{"{}{} ({})", prefix, material.name, index}.c_str()}) {
if (auto const* lit = dynamic_cast<LitMaterial const*>(&material)) { return display(*lit); }
if (auto const* unlit = dynamic_cast<UnlitMaterial const*>(&material)) { return display(*unlit); }
}
}

void ResourceInspector::display(Mesh const& mesh, std::size_t const index, std::string_view prefix) const {
if (auto tn = editor::TreeNode{FixedString<128>{"{}{} ({})", prefix, mesh.name, index}.c_str()}) {
for (auto const primitive : mesh.primitives) {
display_resource(m_resources.static_meshes[primitive.static_mesh], primitive.static_mesh, "Static Mesh: ");
if (primitive.material) { display(*m_resources.materials[*primitive.material], *primitive.material, "Material: "); }
}
}
}

void ResourceInspector::display(LitMaterial const& lit) const {
ImGui::Text("Albedo: ");
ImGui::SameLine();
ImGui::ColorButton("Albedo", {lit.albedo.x, lit.albedo.y, lit.albedo.z, 1.0f});
ImGui::Text("%s", FixedString{"Metallic: {:.2f}", lit.metallic}.c_str());
ImGui::Text("%s", FixedString{"Roughness: {:.2f}", lit.roughness}.c_str());
if (lit.base_colour) { display(m_resources.textures[*lit.base_colour], *lit.base_colour, "Base Colour: "); }
if (lit.roughness_metallic) { display(m_resources.textures[*lit.roughness_metallic], *lit.roughness_metallic, "Roughness Metallic: "); }
}

void ResourceInspector::display(UnlitMaterial const& unlit) const {
if (unlit.texture) { display(m_resources.textures[*unlit.texture], *unlit.texture, "Texture: "); }
}
} // namespace facade::editor
1 change: 1 addition & 0 deletions lib/scene/include/facade/scene/mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct Mesh {
std::optional<Id<Material>> material{};
};

std::string name{"(unnamed)"};
///
/// \brief List of primitives in this mesh.
///
Expand Down
28 changes: 15 additions & 13 deletions lib/scene/include/facade/scene/scene.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ struct AtomicLoadStatus {
}
};

///
/// \brief Immutable view of the resources stored in the scene.
///
struct SceneResources {
std::span<Camera const> cameras{};
std::span<Sampler const> samplers{};
std::span<std::unique_ptr<Material> const> materials{};
std::span<StaticMesh const> static_meshes{};
std::span<Texture const> textures{};
std::span<Mesh const> meshes{};
};

///
/// \brief Models a 3D scene.
///
Expand All @@ -51,23 +63,13 @@ struct AtomicLoadStatus {
///
class Scene {
public:
using Resources = SceneResources;

///
/// \brief Represents a single GTLF scene.
///
struct Tree {};

///
/// \brief Immutable view of the resources stored in the scene.
///
struct Resources {
std::span<Camera const> cameras{};
std::span<Sampler const> samplers{};
std::span<std::unique_ptr<Material> const> materials{};
std::span<StaticMesh const> static_meshes{};
std::span<Texture const> textures{};
std::span<Mesh const> meshes{};
};

///
/// \brief "Null" Id for a Node: refers to no Node.
///
Expand Down Expand Up @@ -118,7 +120,7 @@ class Scene {
/// \param geometry Geometry to initialize StaticMesh with
/// \returns Id to stored StaticMesh
///
Id<StaticMesh> add(Geometry const& geometry);
Id<StaticMesh> add(Geometry const& geometry, std::string name = "(unnamed)");
///
/// \brief Add a Texture.
/// \param image Image to use for the Texture
Expand Down
2 changes: 1 addition & 1 deletion lib/scene/src/detail/gltf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ struct Mesh {
std::optional<std::size_t> material{};
};

std::string name{};
std::string name{"(unnamed)"};
std::vector<Primitive> primitives{};
};

Expand Down
15 changes: 8 additions & 7 deletions lib/scene/src/scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ std::unique_ptr<Material> to_material(gltf::Material const& material) {
return ret;
}

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

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

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

Id<StaticMesh> Scene::add(Geometry const& geometry) {
Id<StaticMesh> Scene::add(Geometry const& geometry, std::string name) {
auto const id = m_storage.static_meshes.size();
m_storage.static_meshes.emplace_back(m_gfx, geometry);
m_storage.static_meshes.emplace_back(m_gfx, geometry, std::move(name));
return id;
}

Expand Down
4 changes: 3 additions & 1 deletion lib/vk/include/facade/vk/static_mesh.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@ struct Geometry;

class StaticMesh {
public:
StaticMesh(Gfx const& gfx, Geometry const& geometry);
StaticMesh(Gfx const& gfx, Geometry const& geometry, std::string name = "(unnamed)");

std::string_view name() const { return m_name; }
MeshView view() const;
operator MeshView() const { return view(); }

private:
BufferView vbo() const;
BufferView ibo() const;

std::string m_name{};
Defer<UniqueBuffer> m_buffer{};
std::size_t m_vbo_size{};
std::uint32_t m_vertices{};
Expand Down
11 changes: 8 additions & 3 deletions lib/vk/include/facade/vk/texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@

namespace facade {
struct SamplerCreateInfo {
std::string name{"(unnamed)"};
vk::SamplerAddressMode mode_s{vk::SamplerAddressMode::eRepeat};
vk::SamplerAddressMode mode_t{vk::SamplerAddressMode::eRepeat};
vk::Filter min{vk::Filter::eLinear};
vk::Filter mag{vk::Filter::eLinear};
};

struct TextureCreateInfo {
std::string name{"(unnamed)"};
bool mip_mapped{true};
ColourSpace colour_space{ColourSpace::eSrgb};
};
Expand All @@ -22,11 +24,13 @@ class Sampler {
public:
using CreateInfo = SamplerCreateInfo;

explicit Sampler(Gfx const& gfx, CreateInfo const& info = {});
explicit Sampler(Gfx const& gfx, CreateInfo info = {});

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

private:
std::string m_name{};
Defer<vk::UniqueSampler> m_sampler{};
};

Expand All @@ -36,20 +40,21 @@ class Texture {

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

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

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

std::string name{"(Unnamed)"};
vk::Sampler sampler{};

private:
Defer<UniqueImage> m_image{};
Gfx m_gfx{};
ImageCreateInfo m_info{};
vk::ImageLayout m_layout{vk::ImageLayout::eUndefined};
std::string m_name{};
};
} // namespace facade
2 changes: 1 addition & 1 deletion lib/vk/src/static_mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace {
constexpr auto flags_v = vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst;
} // namespace

StaticMesh::StaticMesh(Gfx const& gfx, Geometry const& geometry) : m_buffer{gfx.shared->defer_queue} {
StaticMesh::StaticMesh(Gfx const& gfx, Geometry const& geometry, std::string name) : m_name(std::move(name)), m_buffer{gfx.shared->defer_queue} {
auto const vertices = std::span<Vertex const>{geometry.vertices};
auto const indices = std::span<std::uint32_t const>{geometry.indices};
m_vertices = static_cast<std::uint32_t>(vertices.size());
Expand Down
5 changes: 3 additions & 2 deletions lib/vk/src/texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ bool can_mip(vk::PhysicalDevice const gpu, vk::Format const format) {
}
} // namespace

Sampler::Sampler(Gfx const& gfx, CreateInfo const& info) {
Sampler::Sampler(Gfx const& gfx, CreateInfo info) {
auto sci = vk::SamplerCreateInfo{};
sci.minFilter = info.min;
sci.magFilter = info.mag;
Expand All @@ -101,11 +101,12 @@ Sampler::Sampler(Gfx const& gfx, CreateInfo const& info) {
sci.addressModeW = info.mode_s;
sci.maxLod = VK_LOD_CLAMP_NONE;
m_sampler = {gfx.device.createSamplerUnique(sci), gfx.shared->defer_queue};
m_name = std::move(info.name);
}

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; }

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