From 777e407d6724c1c75aa27fecf3e76a8f3d817baf Mon Sep 17 00:00:00 2001 From: Caleb Burke Date: Tue, 6 Oct 2026 01:16:28 -0700 Subject: [PATCH] sandbox simplfy --- sandbox/main.cpp | 256 ++++------------------------------------------- 1 file changed, 19 insertions(+), 237 deletions(-) diff --git a/sandbox/main.cpp b/sandbox/main.cpp index 8ab5895..bd62059 100644 --- a/sandbox/main.cpp +++ b/sandbox/main.cpp @@ -1,295 +1,77 @@ #define GLFW_INCLUDE_VULKAN #include -#include -#include -#include -#include -#include -#include #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include #include -#include "renderer/imgui_renderer.hpp" -#include "renderer/model_render_system.hpp" #include "renderer/render_context.hpp" #include "renderer/render_graph.hpp" #include "renderer/scene_renderer.hpp" -#include "resources/mesh.hpp" -#include "resources/render_target.hpp" #include "resources/resource_registry.hpp" -#include "vulkan/buffer.hpp" #include "vulkan/device.hpp" -#include "vulkan/pipelines/graphics_pipeline.hpp" -#include "vulkan/shader.hpp" #include "window.hpp" constexpr uint32_t WIDTH = 1280; constexpr uint32_t HEIGHT = 720; constexpr const char* NAME = "sandbox"; -constexpr sophia::ClearColor CLEAR_COLOR = {0.01f, 0.01f, 0.02f, 1.0f}; - -bool hasFlag(sophia::ClearFlags flags, sophia::ClearFlags flag) { - return (static_cast(flags) & static_cast(flag)) != 0; -} - -int main(int argc, const char** argv) { - std::vector args; - args.assign(argv, argv + argc); - - std::cout << __FILE__ << "::" << __LINE__ << '\n'; - +int main() { sophia::Window window{WIDTH, HEIGHT, NAME}; sophia::Device device{&window}; sophia::RenderContext renderContext{window, device}; - sophia::ResourceRegistry resourceRegistry{ - device, renderContext.getImageFormat()}; // remove? + sophia::ResourceRegistry resourceRegistry{device, + renderContext.getImageFormat()}; - // remove? - std::vector> meshes; - - // remove? - std::vector drawCalls; - - // todo: figure out which to remove - sophia::PanelRegistry panelRegistry; sophia::SceneRegistry sceneRegistry; - sophia::SceneViewRegistry sceneViewRegistry; - sophia::ConsoleCommandRegistry consoleCommandRegistry; - - sophia::DebugUI debugUI{panelRegistry, consoleCommandRegistry}; - debugUI.showFrameStats(true); - - sophia::ModelRenderSystem modelRenderSystem{device, renderContext}; sophia::SceneRenderer sceneRenderer{sceneRegistry, resourceRegistry, device, renderContext.getImageFormat()}; - sophia::ImGuiRenderer imguiRenderer{ - window, device, renderContext.getImageFormat(), - renderContext.getImageCount(), resourceRegistry}; - consoleCommandRegistry.registerCommand( - "reset_layout", "Restore the default panel layout", - [&imguiRenderer](const std::vector&) { - imguiRenderer.resetLayout(); - return std::string{"Layout reset"}; - }); - - auto& meshPool = resourceRegistry.meshPool; - auto& renderTargetPool = resourceRegistry.renderTargetPool; - - imguiRenderer.setDefaultLayout(panelRegistry.getDefaultLayout()); - - // Views already warned about, so each warns once. - std::set viewsWithoutCamera; - std::set viewsOverwritingOthers; - - auto startTime = std::chrono::high_resolution_clock::now(); - auto currentTime = startTime; - sophia::u32 frameIndex = 0; + sophia::SceneView view; + view.scene = sceneRegistry.create(); + view.clearColor = {0.01f, 0.01f, 0.02f, 1.0f}; + view.camera = sceneRegistry.get(view.scene).createCamera(); while (!window.shouldClose()) { glfwPollEvents(); - auto newTime = std::chrono::high_resolution_clock::now(); - double deltaTime = - std::chrono::duration(newTime - currentTime).count(); - currentTime = newTime; - - double elapsedTime = - std::chrono::duration(currentTime - startTime).count(); - - // Resizing waits for the GPU, so it has to happen before any of this - // frame's work (or ImGui's references to the targets) is recorded. - renderTargetPool.applyPendingResizes(); - - vk::Extent2D extent = renderContext.getExtent(); - sophia::FrameInfo frameInfo{frameIndex, elapsedTime, deltaTime, - glm::vec2(static_cast(extent.width), - static_cast(extent.height))}; - - // Canvas draws in window pixels, origin at the center. - // TODO: replace with Debug/Gizmos drawn into scene views through their - // cameras. - glm::mat4 canvasProjection = - glm::ortho(-frameInfo.currentFramebufferExtent.x / 2.f, - frameInfo.currentFramebufferExtent.x / 2.f, - -frameInfo.currentFramebufferExtent.y / 2.f, - frameInfo.currentFramebufferExtent.y / 2.f); - vk::CommandBuffer commandBuffer = renderContext.beginFrame(); if (!commandBuffer) { continue; } - imguiRenderer.beginFrame(); sceneRenderer.beginFrame(renderContext.getFrameIndex()); - panelRegistry.update(frameInfo); - - std::vector instances; - instances.reserve(meshes.size() + drawCalls.size()); - for (const std::unique_ptr& mesh : meshes) { - instances.push_back({mesh.get(), glm::mat4{1.f}}); - } - instances.insert(instances.end(), drawCalls.begin(), drawCalls.end()); - drawCalls.clear(); - sophia::RenderGraph graph{renderContext.getTracyContext()}; - sophia::ImageRef backbuffer = graph.importImage( - renderContext.getCurrentImage(), sophia::Access::Present); - - struct ViewTarget { - sophia::ImageRef color; - sophia::ImageRef depth; - }; - std::map viewTargets; - // Views without a target render straight into the backbuffer. - std::optional swapchainTarget; - for (sophia::SceneViewHandle handle : sceneViewRegistry.GetRenderQueue()) { - const sophia::SceneView& view = sceneViewRegistry.peek(handle); - bool toSwapchain = !view.target.isValid(); - if (!sceneRegistry.isAlive(view.scene) || - !sceneRegistry.get(view.scene).isVisible() || - (!toSwapchain && !renderTargetPool.isAlive(view.target))) { - continue; - } - - ViewTarget target; - vk::Extent2D targetExtent; - // Whether this is the first view this frame to render to its target. - bool firstOnTarget = false; - if (toSwapchain) { - firstOnTarget = !swapchainTarget; - if (!swapchainTarget) { - swapchainTarget = { - backbuffer, - graph.importImage(renderContext.getCurrentDepthImage(), - sophia::Access::DepthWrite)}; - } - target = *swapchainTarget; - targetExtent = renderContext.getExtent(); - } else { - sophia::RenderTarget& renderTarget = renderTargetPool.get(view.target); - auto [it, inserted] = viewTargets.try_emplace(view.target); - firstOnTarget = inserted; - if (inserted) { - it->second = {graph.importImage(renderTarget.getImage(), - sophia::Access::SampledRead), - graph.importImage(renderTarget.getDepthImage(), - sophia::Access::DepthWrite)}; - } - target = it->second; - targetExtent = renderTarget.getExtent(); - } - - if (!firstOnTarget && - hasFlag(view.clearFlags, sophia::ClearFlags::Color) && - viewsOverwritingOthers.insert(handle).second) { - sophia::log::warning( - "scene view clears its target after another view already " - "rendered to it this frame, hiding that view (give it clearFlags " - "without Color, or render it first with a lower priority)"); - } - - const sophia::vec4& color = view.clearColor; - graph.addPass( - "scene view " + std::to_string(handle.index), - [&](sophia::RenderGraph::PassBuilder& pass) { - pass.writeColor(target.color, - hasFlag(view.clearFlags, sophia::ClearFlags::Color) - ? vk::AttachmentLoadOp::eClear - : vk::AttachmentLoadOp::eLoad, - {color.r, color.g, color.b, color.a}); - pass.writeDepth(target.depth, - hasFlag(view.clearFlags, sophia::ClearFlags::Depth) - ? vk::AttachmentLoadOp::eClear - : vk::AttachmentLoadOp::eLoad); - }, - [&sceneRenderer, &sceneRegistry, &sceneViewRegistry, - &viewsWithoutCamera, handle, - targetExtent](vk::CommandBuffer commandBuffer) { - ZoneScopedN("scene view pass"); - const sophia::SceneView& view = sceneViewRegistry.peek(handle); - sophia::Entity camera = - view.camera ? view.camera - : sceneRegistry.get(view.scene).getActiveCamera(); - // No camera to look through: the target is just cleared. - if (!camera) { - if (viewsWithoutCamera.insert(handle).second) { - sophia::log::warning( - "scene view has no camera and its scene has no active " - "camera; it will only be cleared (see " - "Scene::createCamera)"); - } - return; - } - sceneRenderer.render(commandBuffer, view, camera, targetExtent); - }); - } + sophia::ImageRef color = graph.importImage(renderContext.getCurrentImage(), + sophia::Access::Present); + sophia::ImageRef depth = graph.importImage( + renderContext.getCurrentDepthImage(), sophia::Access::DepthWrite); graph.addPass( - "main", + "scene", [&](sophia::RenderGraph::PassBuilder& pass) { - // Keep what scene views drew into the backbuffer. - pass.writeColor(backbuffer, - swapchainTarget ? vk::AttachmentLoadOp::eLoad - : vk::AttachmentLoadOp::eClear, - CLEAR_COLOR); - for (const auto& [handle, target] : viewTargets) { - pass.sample(target.color); - } + const sophia::vec4& c = view.clearColor; + pass.writeColor(color, vk::AttachmentLoadOp::eClear, + {c.r, c.g, c.b, c.a}); + pass.writeDepth(depth, vk::AttachmentLoadOp::eClear); }, [&](vk::CommandBuffer commandBuffer) { - ZoneScopedN("main pass"); - modelRenderSystem.render(commandBuffer, instances, canvasProjection); - - imguiRenderer.endFrame(commandBuffer); + ZoneScopedN("scene pass"); + sceneRenderer.render(commandBuffer, view, view.camera, + renderContext.getExtent()); }); graph.execute(commandBuffer); renderContext.endFrame(); FrameMark; - - frameIndex++; } device.waitIdle(); - auto endTime = std::chrono::high_resolution_clock::now(); - double totalRuntime = - std::chrono::duration(endTime - startTime).count(); - sophia::log::info("Application ran for {:.2f}s", totalRuntime); - return EXIT_SUCCESS; }