From 566aa04cdacebfc95a8d76f51801965e5dadec4d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 3 Feb 2026 23:13:07 +0300 Subject: [PATCH] test rendering ui to texture --- res/scripts/hud.lua | 2 ++ src/graphics/core/Framebuffer.cpp | 4 +++ src/graphics/core/Framebuffer.hpp | 4 ++- src/graphics/ui/elements/Frame.cpp | 42 ++++++++++++++++++++++++++++++ src/graphics/ui/elements/Frame.hpp | 18 +++++++++++++ src/graphics/ui/gui_xml.cpp | 11 ++++++++ 6 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/graphics/ui/elements/Frame.cpp create mode 100644 src/graphics/ui/elements/Frame.hpp diff --git a/res/scripts/hud.lua b/res/scripts/hud.lua index 322f03db5..a0e363b99 100644 --- a/res/scripts/hud.lua +++ b/res/scripts/hud.lua @@ -126,6 +126,8 @@ function on_hud_open() configure_SSAO() hud.default_hand_controller = update_hand + + gui.root.root:add("") end function on_hud_render() diff --git a/src/graphics/core/Framebuffer.cpp b/src/graphics/core/Framebuffer.cpp index bb360b54e..5d6be967d 100644 --- a/src/graphics/core/Framebuffer.cpp +++ b/src/graphics/core/Framebuffer.cpp @@ -89,6 +89,10 @@ Texture* Framebuffer::getTexture() const { return texture.get(); } +std::shared_ptr Framebuffer::getSharedTexture() const { + return texture; +} + uint Framebuffer::getWidth() const { return width; } diff --git a/src/graphics/core/Framebuffer.hpp b/src/graphics/core/Framebuffer.hpp index e48e97df4..4d21449c5 100644 --- a/src/graphics/core/Framebuffer.hpp +++ b/src/graphics/core/Framebuffer.hpp @@ -13,7 +13,7 @@ class Framebuffer : public Bindable { uint width; uint height; uint format; - std::unique_ptr texture; + std::shared_ptr texture; public: Framebuffer(uint fbo, uint depth, std::unique_ptr texture); Framebuffer(uint width, uint height, bool alpha=false); @@ -33,6 +33,8 @@ public: /// @brief Get framebuffer color attachment Texture* getTexture() const; + std::shared_ptr getSharedTexture() const; + /// @brief Get framebuffer width uint getWidth() const; /// @brief Get framebuffer height diff --git a/src/graphics/ui/elements/Frame.cpp b/src/graphics/ui/elements/Frame.cpp new file mode 100644 index 000000000..2a7af926b --- /dev/null +++ b/src/graphics/ui/elements/Frame.cpp @@ -0,0 +1,42 @@ +#include "Frame.hpp" + +#include "assets/Assets.hpp" +#include "graphics/core/Batch2D.hpp" +#include "graphics/core/Framebuffer.hpp" +#include "graphics/core/DrawContext.hpp" +#include "graphics/core/Texture.hpp" +#include "window/Window.hpp" +#include "../GUI.hpp" + +using namespace gui; + +static inline constexpr int MAX_TEXTURE_SIZE = 2048; + +gui::Frame::Frame(GUI& gui) : Container(gui, {}), fbo(nullptr) {} + +gui::Frame::~Frame() = default; + +void gui::Frame::draw(const DrawContext& pctx, const Assets& assets) { + glm::ivec2 size = getSize(); + if (size.x <= 0 || size.y <= 0 || + size.x > MAX_TEXTURE_SIZE || size.y > MAX_TEXTURE_SIZE) { + return; + } + auto& nonConstASsets = const_cast(assets); + if (fbo && (fbo->getWidth() != size.x || fbo->getHeight() != size.y)) { + fbo->resize(size.x, size.y); + nonConstASsets.store(fbo->getSharedTexture(), texture); + } else if (fbo == nullptr) { + fbo = std::make_unique(size.x, size.y, true); + nonConstASsets.store(fbo->getSharedTexture(), texture); + } + + // ui uses flipped camera with matrix based on main viewport + setPos({0, pctx.getViewport().y - size.y}); + + auto ctx = pctx.sub(); + ctx.setFramebuffer(fbo.get()); + display::clear(); + Container::draw(ctx, assets); + ctx.getBatch2D()->flush(); +} diff --git a/src/graphics/ui/elements/Frame.hpp b/src/graphics/ui/elements/Frame.hpp new file mode 100644 index 000000000..1f4a10c86 --- /dev/null +++ b/src/graphics/ui/elements/Frame.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include "Container.hpp" + +class Framebuffer; + +namespace gui { + class Frame final : public Container { + public: + explicit Frame(GUI& gui); + virtual ~Frame(); + + void draw(const DrawContext& pctx, const Assets& assets) override; + private: + std::unique_ptr fbo; + std::string texture = "gui/no_icon"; + }; +} diff --git a/src/graphics/ui/gui_xml.cpp b/src/graphics/ui/gui_xml.cpp index 0020c28d1..f34bd9247 100644 --- a/src/graphics/ui/gui_xml.cpp +++ b/src/graphics/ui/gui_xml.cpp @@ -8,6 +8,7 @@ #include "elements/Button.hpp" #include "elements/Canvas.hpp" #include "elements/CheckBox.hpp" +#include "elements/Frame.hpp" #include "elements/Image.hpp" #include "elements/InlineFrame.hpp" #include "elements/InputBindBox.hpp" @@ -850,6 +851,15 @@ static std::shared_ptr read_page_box( return menu; } +static std::shared_ptr read_frame( + UiXmlReader& reader, const xml::xmlelement& element +) { + auto& gui = reader.getGUI(); + auto frame = std::make_shared(gui); + read_container_impl(reader, element, *frame, true); + return frame; +} + static std::shared_ptr read_iframe( UiXmlReader& reader, const xml::xmlelement& element ) { @@ -867,6 +877,7 @@ UiXmlReader::UiXmlReader(gui::GUI& gui, scriptenv&& env) contextStack.emplace(""); add("image", read_image); add("canvas", read_canvas); + add("frame", read_frame); add("iframe", read_iframe); add("label", read_label); add("panel", read_panel);