From 6a7ebf73a9a3304949ac8dac28976aca69fb2fb0 Mon Sep 17 00:00:00 2001 From: Nanako <469449812@qq.com> Date: Mon, 10 Feb 2025 17:39:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=81=E8=A3=85render=5Fcontext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/src/main.cpp | 4 +- src/core/mirage.cpp | 2 +- src/core/misc/mirage_type.h | 64 ++++++++++++++++ src/core/renderer/render_context.cpp | 65 ++++++++++++++++ src/core/renderer/render_context.h | 33 ++++++++ src/core/window/desktop/desktop_window.cpp | 32 ++++---- src/core/window/window.cpp | 39 +++------- src/core/window/window.h | 87 +++------------------- 8 files changed, 205 insertions(+), 121 deletions(-) create mode 100644 src/core/renderer/render_context.cpp create mode 100644 src/core/renderer/render_context.h diff --git a/example/src/main.cpp b/example/src/main.cpp index de78834..519703d 100644 --- a/example/src/main.cpp +++ b/example/src/main.cpp @@ -2,8 +2,8 @@ int main(int argc, char* argv[]) { mirage::init_info init{}; - init.title = u8"测试"; - init.size = {800, 600}; + init.title = u8"测试"; + init.size = {800, 600}; init.resizable = true; init.centered = true; return run(init); diff --git a/src/core/mirage.cpp b/src/core/mirage.cpp index 9dbffd3..36aaf1a 100644 --- a/src/core/mirage.cpp +++ b/src/core/mirage.cpp @@ -60,7 +60,7 @@ namespace mirage { return false; } - if (!window_ptr->create_swap_chain(in_info)) { + if (!window_ptr->create_context(in_info)) { return false; } spdlog::info("主窗口创建成功"); diff --git a/src/core/misc/mirage_type.h b/src/core/misc/mirage_type.h index bac9ca2..42f84cc 100644 --- a/src/core/misc/mirage_type.h +++ b/src/core/misc/mirage_type.h @@ -1,5 +1,6 @@ #pragma once #include +#include "LLGL/LLGL.h" namespace mirage { using time_type = decltype(std::chrono::high_resolution_clock::now()); @@ -12,4 +13,67 @@ namespace mirage { opengl, metal, }; + + struct window_descriptor { + std::u8string title; + LLGL::Offset2D position; + LLGL::Extent2D size; + bool visible = true; + bool borderless = false; + bool resizable = true; + bool centered = false; + bool accept_drop_files = false; + bool disable_clear_on_resize = false; + bool disable_size_scaling = false; + + operator LLGL::WindowDescriptor() const { + LLGL::WindowDescriptor desc{}; + desc.title = reinterpret_cast(title.c_str()); + desc.position = position; + desc.size = size; + desc.flags = 0; + if (visible) { + desc.flags |= LLGL::WindowFlags::Visible; + } + if (borderless) { + desc.flags |= LLGL::WindowFlags::Borderless; + } + if (resizable) { + desc.flags |= LLGL::WindowFlags::Resizable; + } + if (centered) { + desc.flags |= LLGL::WindowFlags::Centered; + } + if (accept_drop_files) { + desc.flags |= LLGL::WindowFlags::AcceptDropFiles; + } + if (disable_clear_on_resize) { + desc.flags |= LLGL::WindowFlags::DisableClearOnResize; + } + if (disable_size_scaling) { + desc.flags |= LLGL::WindowFlags::DisableSizeScaling; + } + return desc; + } + }; + struct swap_chain_descriptor { + int color_bits = 32; + int depth_bits = 0; + int stencil_bits = 0; + std::uint32_t samples = 1; + std::uint32_t swap_buffers = 2; + bool fullscreen = false; + bool vsync = true; + + operator LLGL::SwapChainDescriptor() const { + LLGL::SwapChainDescriptor desc{}; + desc.colorBits = color_bits; + desc.depthBits = depth_bits; + desc.stencilBits = stencil_bits; + desc.samples = samples; + desc.swapBuffers = swap_buffers; + desc.fullscreen = fullscreen; + return desc; + } + }; } \ No newline at end of file diff --git a/src/core/renderer/render_context.cpp b/src/core/renderer/render_context.cpp new file mode 100644 index 0000000..0af9f90 --- /dev/null +++ b/src/core/renderer/render_context.cpp @@ -0,0 +1,65 @@ +#include "render_context.h" + +#include "mirage.h" + +namespace mirage { + render_context::~render_context() { + if (main_command_buffer) { + get_renderer()->Release(*main_command_buffer); + } + if (vertex_buffer) { + get_renderer()->Release(*vertex_buffer); + } + if (swap_chain) { + get_renderer()->Release(*swap_chain); + } + } + bool render_context::init(const swap_chain_descriptor& in_desc, const std::shared_ptr& in_surface) { + LLGL::SwapChainDescriptor temp = in_desc; + temp.resolution = in_surface->GetContentSize(); + swap_chain = get_renderer()->CreateSwapChain(temp, in_surface); + if (swap_chain == nullptr) { + spdlog::error("无法创建交换链"); + return false; + } + main_command_buffer = get_renderer()->CreateCommandBuffer(LLGL::CommandBufferFlags::ImmediateSubmit); + if (main_command_buffer == nullptr) { + spdlog::error("无法创建命令缓冲区"); + return false; + } + set_vsync(in_desc.vsync); + // LLGL::BufferDescriptor vertex_buffer_descriptor{}; + // vertex_buffer = get_renderer()->CreateBuffer(vertex_buffer_descriptor); + return true; + } + render_context::update_status render_context::update(const duration_type& in_delta_time) { + if (!main_command_buffer || !swap_chain) { + return update_status::fail; + } + if (!swap_chain->IsPresentable()) { + return update_status::wait_for_present; + } + main_command_buffer->Begin(); + { + main_command_buffer->BeginRenderPass(*swap_chain); + main_command_buffer->Clear(LLGL::ClearFlags::Color, {0.1f, 0.1f, 0.2f, 1.0f}); + main_command_buffer->EndRenderPass(); + } + main_command_buffer->End(); + swap_chain->Present(); + return update_status::success; + } + void render_context::resize_swap_chain(const LLGL::Extent2D& in_size, long in_flag) { + if (swap_chain) { + swap_chain->ResizeBuffers(in_size, in_flag); + } + } + + void render_context::set_vsync(bool in_vsync) { + if (swap_chain) { + swap_chain->SetVsyncInterval(in_vsync ? 1 : 0); + vsync = in_vsync; + spdlog::info("垂直同步: {}", vsync); + } + } +} // namespace mirage diff --git a/src/core/renderer/render_context.h b/src/core/renderer/render_context.h new file mode 100644 index 0000000..b8b7d78 --- /dev/null +++ b/src/core/renderer/render_context.h @@ -0,0 +1,33 @@ +#pragma once +#include "LLGL/LLGL.h" +#include "misc/mirage_type.h" + +namespace mirage { + class render_context { + public: + enum class update_status { + success, + wait_for_present, + fail + }; + + ~render_context(); + + bool init(const swap_chain_descriptor& in_desc, const std::shared_ptr& in_surface); + update_status update(const duration_type& in_delta_time); + void resize_swap_chain(const LLGL::Extent2D& in_size, long in_flag); + + void set_vsync(bool in_vsync); + [[nodiscard]] auto is_vsync() const { + return vsync; + } + [[nodiscard]] auto get_swap_chain() const { + return swap_chain; + } + private: + LLGL::SwapChain* swap_chain = nullptr; + LLGL::Buffer* vertex_buffer = nullptr; + LLGL::CommandBuffer* main_command_buffer = nullptr; + bool vsync = true; + }; +} // namespace mirage diff --git a/src/core/window/desktop/desktop_window.cpp b/src/core/window/desktop/desktop_window.cpp index 8ec493d..bc48f13 100644 --- a/src/core/window/desktop/desktop_window.cpp +++ b/src/core/window/desktop/desktop_window.cpp @@ -1,5 +1,6 @@ #include "window/window.h" #include "window/window_manager.h" +#include namespace mirage { class desktop_window_event_listener : public LLGL::Window::EventListener { @@ -53,9 +54,9 @@ namespace mirage { }; - void window::set_title(const std::u8string& title) { + void window::set_title(const std::u8string& in_title) { if (auto window_ptr = static_cast(surface.get())) { - window_ptr->SetTitle((char*)title.c_str()); + window_ptr->SetTitle((char*)in_title.c_str()); } } @@ -66,11 +67,11 @@ namespace mirage { return {}; } - void window::set_fullscreen(bool fullscreen) { + void window::set_fullscreen(bool in_fullscreen) { if (auto window_ptr = static_cast(surface.get())) { - window_ptr->AdaptForVideoMode(nullptr, &fullscreen); + window_ptr->AdaptForVideoMode(nullptr, &in_fullscreen); const auto display = window_ptr->FindResidentDisplay(); - if (display && fullscreen) { + if (display && in_fullscreen) { resize(display->GetDisplayMode().resolution); } } @@ -87,10 +88,10 @@ namespace mirage { return false; } - void window::set_resizable(bool resizable) { + void window::set_resizable(bool in_resizable) { if (auto window_ptr = static_cast(surface.get())) { auto desc = window_ptr->GetDesc(); - desc.flags = resizable ? desc.flags | LLGL::WindowFlags::Resizable : desc.flags & ~LLGL::WindowFlags::Resizable; + desc.flags = in_resizable ? desc.flags | LLGL::WindowFlags::Resizable : desc.flags & ~LLGL::WindowFlags::Resizable; window_ptr->SetDesc(desc); } } @@ -102,10 +103,11 @@ namespace mirage { return false; } - void window::set_centered(bool centered) { + void window::set_centered(bool in_centered) { if (auto window_ptr = static_cast(surface.get())) { auto desc = window_ptr->GetDesc(); - desc.flags = centered ? desc.flags | LLGL::WindowFlags::Centered : desc.flags & ~LLGL::WindowFlags::Centered; + desc.flags = + in_centered ? desc.flags | LLGL::WindowFlags::Centered : desc.flags & ~LLGL::WindowFlags::Centered; window_ptr->SetDesc(desc); } } @@ -147,12 +149,12 @@ namespace mirage { void window::resize(const LLGL::Extent2D& size) { if (get_size() == size) return; - if (swap_chain) { - swap_chain->ResizeBuffers(size, LLGL::ResizeBuffersFlags::AdaptSurface); - return; - } - if (auto window_ptr = static_cast(surface.get())) { - window_ptr->AdaptForVideoMode((LLGL::Extent2D*)&size, nullptr); + if (context) { + context->resize_swap_chain(size, is_fullscreen() ? LLGL::ResizeBuffersFlags::FullscreenMode : LLGL::ResizeBuffersFlags::WindowedMode); + } else if (auto window_ptr = static_cast(surface.get())) { + if (!window_ptr->AdaptForVideoMode((LLGL::Extent2D*) &size, nullptr)) { + spdlog::error("无法调整窗口大小"); + } } } LLGL::Extent2D window::get_size(bool in_client_size) const { diff --git a/src/core/window/window.cpp b/src/core/window/window.cpp index 0727e7a..448f04b 100644 --- a/src/core/window/window.cpp +++ b/src/core/window/window.cpp @@ -20,26 +20,17 @@ namespace mirage { } window::~window() { - if (command_buffer) { - get_renderer()->Release(*command_buffer); - } - if (swap_chain) { - get_renderer()->Release(*swap_chain); - } + delete context; surface.reset(); } - bool window::create_swap_chain(const LLGL::SwapChainDescriptor& desc) { - auto temp = desc; - temp.resolution = get_size(); - swap_chain = get_renderer()->CreateSwapChain(desc, surface); - if (swap_chain == nullptr) { - spdlog::error("无法创建交换链"); - return false; - } - swap_chain->SetVsyncInterval(1); - command_buffer = get_renderer()->CreateCommandBuffer(LLGL::CommandBufferFlags::ImmediateSubmit); - return true; + bool window::create_context(const swap_chain_descriptor& in_desc) { + context = new render_context(); + if (context->init(in_desc, surface)) + return true; + delete context; + context = nullptr; + return false; } #if !MIRAGE_PLATFORM_IOS && !MIRAGE_PLATFORM_MACOS @@ -52,17 +43,9 @@ namespace mirage { } #endif - void window::update(const duration_type& delta_time) { - if (!command_buffer || !swap_chain) { - return; + void window::update(const duration_type& in_delta_time) { + if (context) { + context->update(in_delta_time); } - command_buffer->Begin(); - { - command_buffer->BeginRenderPass(*swap_chain); - command_buffer->Clear(LLGL::ClearFlags::Color, {0.1f, 0.1f, 0.2f, 1.0f}); - command_buffer->EndRenderPass(); - } - command_buffer->End(); - swap_chain->Present(); } } diff --git a/src/core/window/window.h b/src/core/window/window.h index 2c87a94..c6587dd 100644 --- a/src/core/window/window.h +++ b/src/core/window/window.h @@ -1,70 +1,9 @@ #pragma once -#include #include "misc/mirage_type.h" +#include "renderer/render_context.h" +#include namespace mirage { - struct window_descriptor { - std::u8string title; - LLGL::Offset2D position; - LLGL::Extent2D size; - bool visible = true; - bool borderless = false; - bool resizable = true; - bool centered = false; - bool accept_drop_files = false; - bool disable_clear_on_resize = false; - bool disable_size_scaling = false; - - operator LLGL::WindowDescriptor() const { - LLGL::WindowDescriptor desc{}; - desc.title = reinterpret_cast(title.c_str()); - desc.position = position; - desc.size = size; - desc.flags = 0; - if (visible) { - desc.flags |= LLGL::WindowFlags::Visible; - } - if (borderless) { - desc.flags |= LLGL::WindowFlags::Borderless; - } - if (resizable) { - desc.flags |= LLGL::WindowFlags::Resizable; - } - if (centered) { - desc.flags |= LLGL::WindowFlags::Centered; - } - if (accept_drop_files) { - desc.flags |= LLGL::WindowFlags::AcceptDropFiles; - } - if (disable_clear_on_resize) { - desc.flags |= LLGL::WindowFlags::DisableClearOnResize; - } - if (disable_size_scaling) { - desc.flags |= LLGL::WindowFlags::DisableSizeScaling; - } - return desc; - } - }; - struct swap_chain_descriptor { - int color_bits = 32; - int depth_bits = 0; - int stencil_bits = 0; - std::uint32_t samples = 1; - std::uint32_t swap_buffers = 2; - bool fullscreen = false; - - operator LLGL::SwapChainDescriptor() const { - LLGL::SwapChainDescriptor desc{}; - desc.colorBits = color_bits; - desc.depthBits = depth_bits; - desc.stencilBits = stencil_bits; - desc.samples = samples; - desc.swapBuffers = swap_buffers; - desc.fullscreen = fullscreen; - return desc; - } - }; - class window { friend class desktop_window_event_listener; friend class mobile_window_event_listener; @@ -72,19 +11,22 @@ namespace mirage { explicit window(const LLGL::WindowDescriptor& in_desc); virtual ~window(); - bool create_swap_chain(const LLGL::SwapChainDescriptor& desc); + bool create_context(const swap_chain_descriptor& in_desc); + [[nodiscard]] auto get_render_context() const { + return context; + } [[nodiscard]] void* get_native_handle() const; - void update(const duration_type& delta_time); - void set_title(const std::u8string& title); + void update(const duration_type& in_delta_time); + void set_title(const std::u8string& in_title); [[nodiscard]] std::u8string get_title() const; - void set_fullscreen(bool fullscreen); + void set_fullscreen(bool in_fullscreen); [[nodiscard]] bool is_fullscreen() const; - void set_resizable(bool resizable); + void set_resizable(bool in_resizable); [[nodiscard]] bool is_resizable() const; void set_borderless(bool borderless); [[nodiscard]] bool is_borderless() const; - void set_centered(bool centered); + void set_centered(bool in_centered); void show(bool in_show); void move(const LLGL::Offset2D& position); @@ -92,9 +34,6 @@ namespace mirage { void resize(const LLGL::Extent2D& size); [[nodiscard]] LLGL::Extent2D get_size(bool in_client_size = true) const; - [[nodiscard]] LLGL::SwapChain* get_swap_chain() const { - return swap_chain; - } protected: virtual void on_quit(bool& out_veto) {} virtual void on_key_down(LLGL::Key in_key_code) {} @@ -113,8 +52,6 @@ namespace mirage { private: void init_event_listener(); std::shared_ptr surface; - LLGL::SwapChain* swap_chain = nullptr; - LLGL::Buffer* vertex_buffer = nullptr; - LLGL::CommandBuffer* command_buffer = nullptr; + render_context* context = nullptr; }; } // namespace mirage