feat: add canvas rework

This commit is contained in:
2026-11-01 23:16:58 +01:00
parent 6a85d17899
commit d26f61a16f
15 changed files with 393 additions and 12 deletions
+5
View File
@@ -1,6 +1,10 @@
#ifndef DESTRUM_APPLAYER_H
#define DESTRUM_APPLAYER_H
#include <optional>
#include <destrum/Components/UI/CanvasFrame.h>
class Camera;
class GameRenderer;
@@ -25,6 +29,7 @@ public:
[[nodiscard]] virtual Camera* viewCamera() { return nullptr; }
[[nodiscard]] virtual bool hostsViewport() const { return false; }
[[nodiscard]] virtual InputFocus gameInputFocus() const { return {}; }
[[nodiscard]] virtual std::optional<CanvasFrame> canvasFrame() const { return std::nullopt; }
};
#endif // DESTRUM_APPLAYER_H
@@ -1,6 +1,7 @@
#ifndef DESTRUM_CANVAS_H
#define DESTRUM_CANVAS_H
#include <destrum/Components/UI/CanvasFrame.h>
#include <destrum/Components/UI/RectTransform.h>
#include <destrum/ObjectModel/Component.h>
@@ -22,6 +23,7 @@ public:
void Start() override;
void Render(const RenderContext& ctx) override;
void Draw(const glm::vec2& screenSize);
void Draw(const CanvasFrame& frame);
void Reflect(FieldVisitor& v) override;
@@ -0,0 +1,13 @@
#ifndef DESTRUM_CANVASFRAME_H
#define DESTRUM_CANVASFRAME_H
#include <glm/glm.hpp>
// Where canvases lay out, in draw image pixels: a resolution sized screen at min, drawn zoom times larger
struct CanvasFrame {
glm::vec2 min{0.0f};
glm::vec2 resolution{0.0f};
float zoom{1.0f};
};
#endif // DESTRUM_CANVASFRAME_H
@@ -43,6 +43,8 @@ public:
// Where the canvas last drew this object
[[nodiscard]] const UIRect& GetScreenRect() const { return m_ScreenRect; }
[[nodiscard]] const UIRect& GetParentRect() const { return m_ParentRect; }
// Screen pixels per canvas unit at the last draw
[[nodiscard]] float GetScreenScale() const { return m_LastScale; }
void SetScreenRect(const UIRect& rect, const UIRect& parentRect, float scale)
{
m_ScreenRect = rect;
@@ -1,12 +1,17 @@
#ifndef RENDERCONTEXT_H
#define RENDERCONTEXT_H
#include <optional>
#include <destrum/Components/UI/CanvasFrame.h>
#include <destrum/Graphics/Renderer.h>
struct RenderContext {
GameRenderer& renderer;
const Camera& camera;
const GameRenderer::SceneData& sceneData;
// Unset: canvases fill the draw image
std::optional<CanvasFrame> canvasFrame{};
};
#endif //RENDERCONTEXT_H
+1
View File
@@ -378,6 +378,7 @@ void App::renderFrame()
.renderer = renderer,
.camera = camera,
.sceneData = sceneData,
.canvasFrame = layer ? layer->canvasFrame() : std::nullopt,
});
renderer.endDrawing();
renderer.draw(cmd, gfxDevice, camera, sceneData);
+13 -3
View File
@@ -54,19 +54,29 @@ Canvas* Canvas::FindFor(GameObject& object)
void Canvas::Render(const RenderContext& ctx)
{
if (ctx.canvasFrame) {
Draw(*ctx.canvasFrame);
return;
}
const VkExtent3D extent = ctx.renderer.getDrawImage().extent;
Draw(glm::vec2{static_cast<float>(extent.width), static_cast<float>(extent.height)});
}
void Canvas::Draw(const glm::vec2& screenSize)
{
Draw(CanvasFrame{.resolution = screenSize});
}
void Canvas::Draw(const CanvasFrame& frame)
{
ZoneScopedN("Canvas::Draw");
const UIRect screenRect{.min = glm::vec2{0.0f}, .size = screenSize};
const UIRect screenRect{.min = frame.min, .size = frame.resolution * frame.zoom};
const float scale = GetScale(frame.resolution) * frame.zoom;
if (auto* rectTransform = GetGameObject()->GetComponent<RectTransform>()) {
rectTransform->SetScreenRect(screenRect, screenRect, GetScale(screenSize));
rectTransform->SetScreenRect(screenRect, screenRect, scale);
}
DrawObject(*GetGameObject(), screenRect, GetScale(screenSize), true);
DrawObject(*GetGameObject(), screenRect, scale, true);
}
float Canvas::GetScale(const glm::vec2& screenSize) const