封装render_context

This commit is contained in:
Nanako 2025-02-10 17:39:56 +08:00
parent af808c114e
commit 6a7ebf73a9
8 changed files with 205 additions and 121 deletions

View File

@ -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);

View File

@ -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("主窗口创建成功");

View File

@ -1,5 +1,6 @@
#pragma once
#include <chrono>
#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<const char*>(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;
}
};
}

View File

@ -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<LLGL::Surface>& 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

View File

@ -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<LLGL::Surface>& 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

View File

@ -1,5 +1,6 @@
#include "window/window.h"
#include "window/window_manager.h"
#include <spdlog/spdlog.h>
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<LLGL::Window*>(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<LLGL::Window*>(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<LLGL::Window*>(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<LLGL::Window*>(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<LLGL::Window*>(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<LLGL::Window*>(surface.get())) {
if (!window_ptr->AdaptForVideoMode((LLGL::Extent2D*) &size, nullptr)) {
spdlog::error("无法调整窗口大小");
}
}
}
LLGL::Extent2D window::get_size(bool in_client_size) const {

View File

@ -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();
}
}

View File

@ -1,70 +1,9 @@
#pragma once
#include <LLGL/LLGL.h>
#include "misc/mirage_type.h"
#include "renderer/render_context.h"
#include <LLGL/LLGL.h>
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<const char*>(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<LLGL::Surface> surface;
LLGL::SwapChain* swap_chain = nullptr;
LLGL::Buffer* vertex_buffer = nullptr;
LLGL::CommandBuffer* command_buffer = nullptr;
render_context* context = nullptr;
};
} // namespace mirage