diff --git a/lib/editor/include/facade/editor/log.hpp b/lib/editor/include/facade/editor/log.hpp index 4f8f218..740456a 100644 --- a/lib/editor/include/facade/editor/log.hpp +++ b/lib/editor/include/facade/editor/log.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -6,9 +7,7 @@ namespace facade::editor { class Log : public logger::Accessor { public: - void render(); - - bool show{}; + void render(NotClosed window); private: void operator()(std::span entries) final; @@ -16,5 +15,6 @@ class Log : public logger::Accessor { std::vector m_list{}; EnumArray m_level_filter{true, true, true, debug_v}; int m_display_count{50}; + bool m_auto_scroll{true}; }; } // namespace facade::editor diff --git a/lib/editor/src/log.cpp b/lib/editor/src/log.cpp index 29dbebc..e67a745 100644 --- a/lib/editor/src/log.cpp +++ b/lib/editor/src/log.cpp @@ -1,49 +1,57 @@ #include +#include #include #include #include namespace facade::editor { -void Log::render() { - ImGui::SetNextWindowSize({500.0f, 200.0f}, ImGuiCond_Once); - if (auto window = editor::Window{"Log", &show}) { - ImGui::Text("%s", FixedString{"Count: {}", m_display_count}.c_str()); - ImGui::SameLine(); - float spacing = ImGui::GetStyle().ItemInnerSpacing.x; - ImGui::PushButtonRepeat(true); - if (ImGui::ArrowButton("##left", ImGuiDir_Left)) { m_display_count = std::clamp(m_display_count - 10, 0, 1000); } - ImGui::SameLine(0.0f, spacing); - if (ImGui::ArrowButton("##right", ImGuiDir_Right)) { m_display_count = std::clamp(m_display_count + 10, 0, 1000); } - ImGui::PopButtonRepeat(); +void Log::render(NotClosed window) { + ImGui::Text("%s", FixedString{"Count: {}", m_display_count}.c_str()); + ImGui::SameLine(); + float spacing = ImGui::GetStyle().ItemInnerSpacing.x; + ImGui::PushButtonRepeat(true); + auto const max_logs = static_cast(logger::buffer_size().total()); + if (ImGui::ArrowButton("##left", ImGuiDir_Left)) { m_display_count = std::clamp(m_display_count - 10, 0, max_logs); } + ImGui::SameLine(0.0f, spacing); + if (ImGui::ArrowButton("##right", ImGuiDir_Right)) { m_display_count = std::clamp(m_display_count + 10, 0, max_logs); } + ImGui::PopButtonRepeat(); - static constexpr std::string_view levels_v[] = {"Error", "Warn", "Info", "Debug"}; - static constexpr auto max_log_level_v = debug_v ? logger::Level::eDebug : logger::Level::eInfo; - for (logger::Level l = logger::Level::eError; l <= max_log_level_v; l = static_cast(static_cast(l) + 1)) { - ImGui::SameLine(); - ImGui::Checkbox(levels_v[static_cast(l)].data(), &m_level_filter[l]); - } + static constexpr std::string_view levels_v[] = {"Error", "Warn", "Info", "Debug"}; + static constexpr auto max_log_level_v = debug_v ? logger::Level::eDebug : logger::Level::eInfo; + for (logger::Level l = logger::Level::eError; l <= max_log_level_v; l = static_cast(static_cast(l) + 1)) { + ImGui::SameLine(); + ImGui::Checkbox(levels_v[static_cast(l)].data(), &m_level_filter[l]); + } + ImGui::SameLine(); + ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical); + ImGui::SameLine(); + ImGui::Checkbox("Auto-scroll", &m_auto_scroll); - logger::access_buffer(*this); - auto child = editor::Window{window, "scroll", {}, {}, ImGuiWindowFlags_HorizontalScrollbar}; - static constexpr auto im_colour = [](logger::Level const l) { - switch (l) { - case logger::Level::eError: return ImVec4{1.0f, 0.0f, 0.0f, 1.0f}; - case logger::Level::eWarn: return ImVec4{1.0f, 1.0f, 0.0f, 1.0f}; - default: - case logger::Level::eInfo: return ImVec4{1.0f, 1.0f, 1.0f, 1.0f}; - case logger::Level::eDebug: return ImVec4{0.5f, 0.5f, 0.5f, 1.0f}; - } - }; - if (auto style = editor::StyleVar{ImGuiStyleVar_ItemSpacing, glm::vec2{}}) { - for (auto const* entry : m_list) ImGui::TextColored(im_colour(entry->level), "%s", entry->message.c_str()); + ImGui::Separator(); + logger::access_buffer(*this); + auto child = editor::Window{window, "scroll", {}, {}, ImGuiWindowFlags_HorizontalScrollbar}; + static constexpr auto im_colour = [](logger::Level const l) { + switch (l) { + case logger::Level::eError: return ImVec4{1.0f, 0.0f, 0.0f, 1.0f}; + case logger::Level::eWarn: return ImVec4{1.0f, 1.0f, 0.0f, 1.0f}; + default: + case logger::Level::eInfo: return ImVec4{1.0f, 1.0f, 1.0f, 1.0f}; + case logger::Level::eDebug: return ImVec4{0.5f, 0.5f, 0.5f, 1.0f}; } + }; + auto span = std::span{m_list}; + auto const max_size = static_cast(m_display_count); + if (span.size() > max_size) { span = span.subspan(span.size() - max_size); } + if (auto style = editor::StyleVar{ImGuiStyleVar_ItemSpacing, glm::vec2{}}) { + for (auto const* entry : span) ImGui::TextColored(im_colour(entry->level), "%s", entry->message.c_str()); } + + if (m_auto_scroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { ImGui::SetScrollHereY(1.0f); } } void Log::operator()(std::span entries) { m_list.clear(); for (auto const& entry : entries) { - if (m_list.size() >= static_cast(m_display_count)) { break; } if (!m_level_filter[entry.level]) { continue; } m_list.push_back(&entry); } diff --git a/lib/engine/src/engine.cpp b/lib/engine/src/engine.cpp index 9311e99..043ff4c 100644 --- a/lib/engine/src/engine.cpp +++ b/lib/engine/src/engine.cpp @@ -12,31 +12,17 @@ UniqueWin make_window(glm::ivec2 extent, char const* title) { glfwSetWindowSize(ret.get(), extent.x, extent.y); return ret; } - -constexpr auto get_samples(vk::SampleCountFlags supported, std::uint8_t desired) { - if (desired >= 32 && (supported & vk::SampleCountFlagBits::e32)) { return vk::SampleCountFlagBits::e32; } - if (desired >= 16 && (supported & vk::SampleCountFlagBits::e16)) { return vk::SampleCountFlagBits::e16; } - if (desired >= 8 && (supported & vk::SampleCountFlagBits::e8)) { return vk::SampleCountFlagBits::e8; } - if (desired >= 4 && (supported & vk::SampleCountFlagBits::e4)) { return vk::SampleCountFlagBits::e4; } - if (desired >= 2 && (supported & vk::SampleCountFlagBits::e2)) { return vk::SampleCountFlagBits::e2; } - return vk::SampleCountFlagBits::e1; -} - -Renderer::CreateInfo make_renderer_info(Gpu const& gpu, std::uint8_t sample_count) { - return Renderer::CreateInfo{command_buffers_v, get_samples(gpu.properties.limits.framebufferColorSampleCounts, sample_count)}; -} } // namespace struct Engine::Impl { UniqueWin window; Vulkan vulkan; Gfx gfx; - Renderer renderer; Impl(CreateInfo const& info) : window(make_window(info.extent, info.title)), vulkan(GlfwWsi{window}), gfx{vulkan.gfx()}, - renderer(gfx, window, make_renderer_info(vulkan.gpu(), info.msaa_samples)) {} + renderer(gfx, window, Renderer::CreateInfo{command_buffers_v, info.msaa_samples}) {} }; Engine::Engine(Engine&&) noexcept = default; diff --git a/lib/render/include/facade/render/renderer.hpp b/lib/render/include/facade/render/renderer.hpp index 4ed089e..a0409bf 100644 --- a/lib/render/include/facade/render/renderer.hpp +++ b/lib/render/include/facade/render/renderer.hpp @@ -8,6 +8,7 @@ namespace facade { struct FrameStats { + std::string_view gpu_name{}; /// /// \brief Total frames so far /// @@ -28,11 +29,15 @@ struct FrameStats { /// \brief Current present mode /// vk::PresentModeKHR mode{}; + /// + /// \brief Multi-sampled anti-aliasing level + /// + vk::SampleCountFlagBits msaa{}; }; struct RendererCreateInfo { std::size_t command_buffers{1}; - vk::SampleCountFlagBits samples{vk::SampleCountFlagBits::e1}; + std::uint8_t desired_msaa{1}; }; class Renderer { @@ -40,8 +45,7 @@ class Renderer { using CreateInfo = RendererCreateInfo; struct Info { - vk::PresentModeKHR mode{}; - vk::SampleCountFlagBits samples{}; + vk::SampleCountFlags supported_msaa{}; ColourSpace colour_space{}; std::size_t cbs_per_frame{}; }; diff --git a/lib/render/src/renderer.cpp b/lib/render/src/renderer.cpp index 6d08ad6..1a414ca 100644 --- a/lib/render/src/renderer.cpp +++ b/lib/render/src/renderer.cpp @@ -17,6 +17,15 @@ vk::Format depth_format(vk::PhysicalDevice const gpu) { return vk::Format::eD16Unorm; } +constexpr auto get_samples(vk::SampleCountFlags supported, std::uint8_t desired) { + if (desired >= 32 && (supported & vk::SampleCountFlagBits::e32)) { return vk::SampleCountFlagBits::e32; } + if (desired >= 16 && (supported & vk::SampleCountFlagBits::e16)) { return vk::SampleCountFlagBits::e16; } + if (desired >= 8 && (supported & vk::SampleCountFlagBits::e8)) { return vk::SampleCountFlagBits::e8; } + if (desired >= 4 && (supported & vk::SampleCountFlagBits::e4)) { return vk::SampleCountFlagBits::e4; } + if (desired >= 2 && (supported & vk::SampleCountFlagBits::e2)) { return vk::SampleCountFlagBits::e2; } + return vk::SampleCountFlagBits::e1; +} + /// /// \brief Tracks frames per second /// @@ -38,6 +47,8 @@ struct Fps { struct Renderer::Impl { Gfx gfx; + vk::SampleCountFlags supported_msaa{}; + vk::SampleCountFlagBits msaa{}; Glfw::Window window; Swapchain swapchain; @@ -66,18 +77,20 @@ struct Renderer::Impl { struct { FrameStats stats{}; + std::string gpu_name{}; std::uint64_t triangles{}; // reset every frame std::uint32_t draw_calls{}; // reset every frame } stats{}; Impl(Gfx gfx, Glfw::Window window, Renderer::CreateInfo const& info) - : gfx{gfx}, window{window}, swapchain{gfx, GlfwWsi{window}.make_surface(gfx.instance)}, pipes(gfx, info.samples), - render_pass(gfx, info.samples, this->swapchain.info.imageFormat, depth_format(gfx.gpu)), render_frames(make_render_frames(gfx, info.command_buffers)), + : gfx{gfx}, supported_msaa(gfx.gpu.getProperties().limits.framebufferColorSampleCounts), + msaa(get_samples(supported_msaa, info.desired_msaa)), window{window}, swapchain{gfx, GlfwWsi{window}.make_surface(gfx.instance)}, pipes(gfx, msaa), + render_pass(gfx, msaa, this->swapchain.info.imageFormat, depth_format(gfx.gpu)), render_frames(make_render_frames(gfx, info.command_buffers)), dear_imgui(DearImGui::CreateInfo{ gfx, window, render_pass.render_pass(), - info.samples, + msaa, Swapchain::colour_space(swapchain.info.imageFormat), }) {} @@ -92,6 +105,10 @@ struct Renderer::Impl { Renderer::Renderer(Gfx gfx, Glfw::Window window, CreateInfo const& info) : m_impl{std::make_unique(std::move(gfx), window, info)} { m_impl->swapchain.refresh(Swapchain::Spec{window.framebuffer_extent()}); + m_impl->stats.gpu_name = m_impl->gfx.gpu.getProperties().deviceName.data(); + m_impl->stats.stats.gpu_name = m_impl->stats.gpu_name; + m_impl->stats.stats.msaa = m_impl->msaa; + logger::info("[Renderer] buffering (frames): [{}] | MSAA: [{}x] | max threads: [{}] |", buffering_v, to_int(m_impl->msaa), info.command_buffers); } Renderer::Renderer(Renderer&&) noexcept = default; @@ -100,8 +117,7 @@ Renderer::~Renderer() noexcept = default; auto Renderer::info() const -> Info { return { - .mode = m_impl->swapchain.info.presentMode, - .samples = m_impl->render_pass.samples(), + .supported_msaa = m_impl->supported_msaa, .colour_space = m_impl->swapchain.colour_space(), .cbs_per_frame = m_impl->render_frames.get().secondary.size(), }; diff --git a/lib/util/include/facade/util/logger.hpp b/lib/util/include/facade/util/logger.hpp index 0652f7f..2c40887 100644 --- a/lib/util/include/facade/util/logger.hpp +++ b/lib/util/include/facade/util/logger.hpp @@ -16,6 +16,13 @@ struct Entry { Level level{}; }; +struct BufferSize { + std::size_t limit{500}; + std::size_t delta{100}; + + constexpr std::size_t total() const { return limit + delta; } +}; + struct Accessor { virtual void operator()(std::span entries) = 0; }; @@ -23,11 +30,12 @@ struct Accessor { int thread_id(); std::string format(Level level, std::string_view const message); void log_to(Pipe pipe, Entry entry); +BufferSize const& buffer_size(); void access_buffer(Accessor& accessor); class Instance : public Pinned { public: - Instance(std::size_t buffer_limit = 500, std::size_t buffer_extra = 100); + Instance(BufferSize const& buffer_size = {}); ~Instance(); }; diff --git a/lib/util/src/logger.cpp b/lib/util/src/logger.cpp index 08f6cbe..2741d30 100644 --- a/lib/util/src/logger.cpp +++ b/lib/util/src/logger.cpp @@ -84,8 +84,7 @@ class FileLogger : Pinned { struct Storage { struct Buffer { - std::size_t limit{}; - std::size_t extra{}; + logger::BufferSize size{}; std::vector entries{}; }; @@ -118,14 +117,16 @@ void logger::log_to(Pipe pipe, Entry entry) { g_storage.buffer.entries.push_back(std::move(entry)); } +logger::BufferSize const& logger::buffer_size() { return g_storage.buffer.size; } + void logger::access_buffer(Accessor& accessor) { auto lock = std::scoped_lock{g_storage.mutex}; accessor(g_storage.buffer.entries); } -logger::Instance::Instance(std::size_t buffer_limit, std::size_t buffer_extra) { +logger::Instance::Instance(logger::BufferSize const& buffer_size) { auto lock = std::scoped_lock{g_storage.mutex}; - g_storage.buffer = Storage::Buffer{buffer_limit, buffer_extra}; + g_storage.buffer = Storage::Buffer{buffer_size}; g_storage.file_logger.emplace("facade.log"); } diff --git a/lib/vk/include/facade/vk/render_pass.hpp b/lib/vk/include/facade/vk/render_pass.hpp index 5be6941..f0550a6 100644 --- a/lib/vk/include/facade/vk/render_pass.hpp +++ b/lib/vk/include/facade/vk/render_pass.hpp @@ -12,7 +12,6 @@ class RenderPass { void bind(vk::CommandBuffer cb, vk::Pipeline pipeline); void execute(Framebuffer const& framebuffer, vk::ClearColorValue const& clear); - vk::SampleCountFlagBits samples() const { return m_samples; } vk::RenderPass render_pass() const { return *m_render_pass; } private: diff --git a/lib/vk/include/facade/vk/vma.hpp b/lib/vk/include/facade/vk/vma.hpp index 6551b0e..41bd941 100644 --- a/lib/vk/include/facade/vk/vma.hpp +++ b/lib/vk/include/facade/vk/vma.hpp @@ -8,7 +8,7 @@ template using Pair = std::pair; template -concept BufferWrite = !std::is_pointer_v && std::is_trivially_destructible_v; +concept BufferWrite = (!std::is_pointer_v) && std::is_trivially_destructible_v; constexpr vk::Format srgb_formats_v[] = {vk::Format::eR8G8B8A8Srgb, vk::Format::eB8G8R8A8Srgb, vk::Format::eA8B8G8R8SrgbPack32}; constexpr vk::Format linear_formats_v[] = {vk::Format::eR8G8B8A8Unorm, vk::Format::eB8G8R8A8Unorm}; @@ -30,6 +30,19 @@ constexpr std::string_view present_mode_str(vk::PresentModeKHR const mode) { } } +constexpr int to_int(vk::SampleCountFlagBits const samples) { + switch (samples) { + case vk::SampleCountFlagBits::e64: return 64; + case vk::SampleCountFlagBits::e32: return 32; + case vk::SampleCountFlagBits::e16: return 16; + case vk::SampleCountFlagBits::e8: return 8; + case vk::SampleCountFlagBits::e4: return 4; + case vk::SampleCountFlagBits::e2: return 2; + default: + case vk::SampleCountFlagBits::e1: return 1; + } +} + struct BufferView { vk::Buffer buffer{}; vk::DeviceSize size{}; diff --git a/lib/vk/src/render_pass.cpp b/lib/vk/src/render_pass.cpp index 245e2c2..1a7662e 100644 --- a/lib/vk/src/render_pass.cpp +++ b/lib/vk/src/render_pass.cpp @@ -67,11 +67,10 @@ vk::UniqueRenderPass create_render_pass(vk::Device device, vk::SampleCountFlagBi } // namespace RenderPass::RenderPass(Gfx const& gfx, vk::SampleCountFlagBits samples, vk::Format colour, vk::Format depth) - : m_gfx{gfx}, m_render_pass{create_render_pass(gfx.vma.device, samples, colour, depth)} { + : m_gfx{gfx}, m_render_pass{create_render_pass(gfx.vma.device, samples, colour, depth)}, m_samples(samples) { m_colour.image = m_gfx.shared->defer_queue; m_depth.image = m_gfx.shared->defer_queue; m_depth.format = depth; - m_samples = samples; if (m_samples > vk::SampleCountFlagBits::e1) { m_colour.format = colour; } } diff --git a/lib/vk/src/swapchain.cpp b/lib/vk/src/swapchain.cpp index 88e3bb9..f357586 100644 --- a/lib/vk/src/swapchain.cpp +++ b/lib/vk/src/swapchain.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -85,6 +86,7 @@ vk::Result Swapchain::refresh(Spec const& spec) { m_storage.views.insert(m_gfx.vma.make_image_view(image, info.imageFormat)); m_storage.images.insert({image, *m_storage.views.span().back(), info.imageExtent}); } + logger::info("[Swapchain] images: [{}] | colour space: [{}] |", m_storage.images.size(), is_srgb(info.imageFormat) ? "sRGB" : "linear"); return ret; } diff --git a/lib/vk/src/vk.cpp b/lib/vk/src/vk.cpp index e19fc8f..5ed3d42 100644 --- a/lib/vk/src/vk.cpp +++ b/lib/vk/src/vk.cpp @@ -171,12 +171,13 @@ UniqueVma Vulkan::make_vma(vk::Instance instance, vk::PhysicalDevice gpu, vk::De return ret; } -Vulkan ::Vulkan(Wsi const& wsi) noexcept(false) { +Vulkan::Vulkan(Wsi const& wsi) noexcept(false) { instance = Vulkan::Instance::make(wsi.extensions(), Vulkan::eValidation); auto surface = wsi.make_surface(*instance.instance); device = Vulkan::Device::make(instance, *surface); vma = Vulkan::make_vma(*instance.instance, device.gpu.device, *device.device); shared = std::make_unique(*device.device, device.gpu.properties); + logger::info("[Device] GPU: [{}] |", device.gpu.properties.deviceName.data()); } Gfx Vulkan::gfx() const { diff --git a/src/main.cpp b/src/main.cpp index 246be44..4960575 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -120,15 +120,14 @@ struct MainMenu { struct { bool stats{}; bool tree{}; + bool log{}; + bool imgui_demo{}; } windows{}; - editor::Log log{}; struct { - FixedString<128> name{}; - Id id{}; - } inspecting{}; - - editor::Inspectee inspectee{}; + editor::Log log{}; + editor::Inspectee inspectee{}; + } data{}; static constexpr std::string_view vsync_status(vk::PresentModeKHR const mode) { switch (mode) { @@ -160,12 +159,12 @@ struct MainMenu { void inspector(Scene& scene) { bool show = true; ImGui::SetNextWindowSize({400.0f, 400.0f}, ImGuiCond_Once); - if (auto window = editor::Window{inspectee.name.c_str(), &show}) { editor::SceneInspector{window, scene}.inspect(inspectee.id); } - if (!show) { inspectee = {}; } + if (auto window = editor::Window{data.inspectee.name.c_str(), &show}) { editor::SceneInspector{window, scene}.inspect(data.inspectee.id); } + if (!show) { data.inspectee = {}; } } void stats(Engine const& engine, float const dt) { - ImGui::SetNextWindowSize({200.0f, 200.0f}, ImGuiCond_Once); + ImGui::SetNextWindowSize({250.0f, 200.0f}, ImGuiCond_Once); if (auto window = editor::Window{"Frame Stats", &windows.stats}) { auto const& stats = engine.renderer().frame_stats(); ImGui::Text("%s", FixedString{"Counter: {}", stats.frame_counter}.c_str()); @@ -173,6 +172,8 @@ struct MainMenu { ImGui::Text("%s", FixedString{"Draw calls: {}", stats.draw_calls}.c_str()); ImGui::Text("%s", FixedString{"FPS: {}", (stats.fps == 0 ? static_cast(stats.frame_counter) : stats.fps)}.c_str()); ImGui::Text("%s", FixedString{"Frame time: {:.2f}ms", dt * 1000.0f}.c_str()); + ImGui::Text("%s", FixedString{"GPU: {}", stats.gpu_name}.c_str()); + ImGui::Text("%s", FixedString{"MSAA: {}x", to_int(stats.msaa)}.c_str()); if (ImGui::SmallButton("Vsync")) { change_vsync(engine); } ImGui::SameLine(); ImGui::Text("%s", vsync_status(stats.mode).data()); @@ -181,37 +182,12 @@ struct MainMenu { void tree(Scene& scene) { ImGui::SetNextWindowSize({250.0f, 350.0f}, ImGuiCond_Once); - if (auto window = editor::Window{"Scene", &windows.tree}) { editor::SceneTree{scene}.render(window, inspectee); } - } - - static FixedString<128> node_name(Node const& node) { - auto ret = FixedString<128>{node.name}; - if (ret.empty()) { ret = "(Unnamed)"; } - ret += FixedString{" ({})", node.id()}; - return ret; + if (auto window = editor::Window{"Scene", &windows.tree}) { editor::SceneTree{scene}.render(window, data.inspectee); } } - void mark_inspect(Node const& node) { - inspecting.id = node.id(); - inspecting.name = node_name(node); - inspecting.name += FixedString{"###Node"}; - } - - void uninspect() { inspecting = {.name = "[Node]###Node"}; } - - void walk(Node& node) { - auto flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; - if (node.id() == inspecting.id) { flags |= ImGuiTreeNodeFlags_Selected; } - if (node.children().empty()) { flags |= ImGuiTreeNodeFlags_Leaf; } - auto tn = editor::TreeNode{node_name(node).c_str(), flags}; - if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) { - mark_inspect(node); - } else if (ImGui::IsItemClicked(ImGuiMouseButton_Right)) { - uninspect(); - } - if (tn) { - for (auto& child : node.children()) { walk(child); } - } + void log() { + ImGui::SetNextWindowSize({600.0f, 200.0f}, ImGuiCond_Once); + if (auto window = editor::Window{"Log", &windows.log}) { data.log.render(window); } } void display(Engine& engine, Scene& scene, float const dt) { @@ -223,19 +199,30 @@ struct MainMenu { if (auto window = editor::Menu{main, "Window"}) { if (ImGui::MenuItem("Tree")) { windows.tree = true; } if (ImGui::MenuItem("Stats")) { windows.stats = true; } - if (ImGui::MenuItem("Log")) { log.show = true; } + if (ImGui::MenuItem("Log")) { windows.log = true; } + if constexpr (debug_v) { + if (ImGui::MenuItem("ImGui demo")) { windows.imgui_demo = true; } + } ImGui::Separator(); if (ImGui::MenuItem("Close All")) { windows = {}; } } } if (windows.tree) { tree(scene); } - if (inspectee) { inspector(scene); } + if (data.inspectee) { inspector(scene); } if (windows.stats) { stats(engine, dt); } - if (log.show) { log.render(); } + if (windows.log) { log(); } + if (windows.imgui_demo) { ImGui::ShowDemoWindow(&windows.imgui_demo); } } }; +void log_prologue() { + auto const now = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + char buf[32]{}; + std::strftime(buf, sizeof(buf), "%F %Z", std::localtime(&now)); + logger::info("facade v{}.{}.{} | {} |", 0, 0, 0, buf); +} + void run() { auto context = std::optional{}; @@ -264,6 +251,8 @@ void run() { auto init = [&] { context.emplace(); + log_prologue(); + auto lit = shaders::lit(); lit.id = "default"; context->add_shader(lit); @@ -321,8 +310,6 @@ void run() { node->instances[0].rotate(glm::radians(drot_z[0]) * dt, {0.0f, 1.0f, 0.0f}); node->instances[1].rotate(glm::radians(drot_z[1]) * dt, {1.0f, 0.0f, 0.0f}); - ImGui::ShowDemoWindow(); - main_menu.display(context->engine, context->scene, dt); // TEMP CODE }