diff --git a/src/core/a.puml b/src/core/a.puml new file mode 100644 index 0000000..d1c054f --- /dev/null +++ b/src/core/a.puml @@ -0,0 +1,30 @@ +@startuml +start +:主线程启动; + +fork + :创建窗口; + :初始化命令缓冲池; +fork again + :启动工作线程; + repeat + :锁定次级CB队列; + if (有可用CB?) then (是) + :取出次级CB; + else (否) + :创建新次级CB; + endif + :录制绘制命令; + :返回就绪队列; + repeat while(有更多任务?) +end fork + +:开始主CB录制; +while (遍历所有窗口?) + :合并次级CB; + :提交到GPU; + :呈现窗口; +endwhile + +stop +@enduml diff --git a/src/core/b.puml b/src/core/b.puml new file mode 100644 index 0000000..df45e3a --- /dev/null +++ b/src/core/b.puml @@ -0,0 +1,57 @@ +@startuml +skinparam classFontSize 13 +skinparam classAttributeIconSize 0 + +class GUIFramework { + + WindowScheduler windowMgr + + CommandBufferPool cmdPool + + WidgetCacheSystem cacheSys + + MainLoop() + + SubmitFrame() +} + +class WindowScheduler { + + vector windows + + CreateWindow() + + CloseWindow() +} + +class WindowContext { + - LLGL::Window* window + - LLGL::CommandBuffer* primaryCB + + vector secondaryCBs + + CachedTextureManager textureCache +} + +class CommandBufferPool { + - queue freeBuffers + - queue readyBuffers + + AsyncRecord(function) + + SyncThreads() +} + +class ElementDrawer { + - LLGL::CommandBuffer* currentCB + + DrawRect() + + DrawText() + + DrawRoundedRect() + + SetTransform() + + PushState() + + PopState() +} + +class WidgetCacheSystem { + - map cacheMap + + GetCachedTexture() + + InvalidateCache() + + UpdateCache() +} + +GUIFramework "1" *-- "1" WindowScheduler +GUIFramework "1" *-- "1" CommandBufferPool +GUIFramework "1" *-- "1" WidgetCacheSystem +WindowScheduler "1" *-- "many" WindowContext +CommandBufferPool "1" *-- "many" LLGL::CommandBuffer +ElementDrawer "1" --* WidgetCacheSystem +ElementDrawer "1" --* LLGL::CommandBuffer +@enduml diff --git a/src/core/c.puml b/src/core/c.puml new file mode 100644 index 0000000..894bfaf --- /dev/null +++ b/src/core/c.puml @@ -0,0 +1,26 @@ +@startuml +actor MainThread +participant WorkerThread +participant GPU + +MainThread -> WorkerThread : 分发录制任务 +activate WorkerThread + +WorkerThread -> WorkerThread : 获取次级CB +WorkerThread -> ElementDrawer : 录制绘制命令 +WorkerThread -> CommandBufferPool : 提交就绪CB +deactivate WorkerThread + +MainThread -> MainThread : 同步所有工作线程 +MainThread -> WindowContext : 开始主CB录制 + +loop 每个窗口 +WindowContext -> CommandBufferPool : 获取就绪CB列表 +CommandBufferPool -> WindowContext : 返回次级CB集合 +WindowContext -> LLGL::CommandBuffer : 执行次级CB +end + +MainThread -> GPU : 提交主CB +GPU -> GPU : 执行绘制命令 +GPU -> Window : 呈现画面 +@enduml diff --git a/src/core/d.puml b/src/core/d.puml new file mode 100644 index 0000000..39f4e51 --- /dev/null +++ b/src/core/d.puml @@ -0,0 +1,16 @@ +@startuml +state CommandBufferState { + [*] --> Idle + Idle --> Recording : Begin() + Recording --> Executable : End() + Executable --> Pending : Submit() + Pending --> Idle : Reset() +} + +state CacheState { + [*] --> Valid + Valid --> Invalid : Widget Changed + Invalid --> Rendering : Start Update + Rendering --> Valid : Complete +} +@enduml diff --git a/src/core/e.puml b/src/core/e.puml new file mode 100644 index 0000000..a3c5c7e --- /dev/null +++ b/src/core/e.puml @@ -0,0 +1,28 @@ +@startuml +skinparam componentStyle rectangle +skinparam nodesep 20 +skinparam ranksep 30 + +package "GUI Framework" { + [Window Manager] as WM + [Command Buffer Pool] as CBP + [Cache System] as CS + [Element Drawer] as ED +} + +package "LLGL Backend" { + [Command Buffer] as CB + [Texture] as Tex + [Render Context] as RC +} + +WM --> CBP : manages +CBP --> CB : creates +ED --> CS : queries +ED --> CB : records +CS --> Tex : caches +[GUI Framework] ..> [LLGL Backend] : depends on + +note right of CB: 管理图形API原生命令缓冲区 +note bottom of Tex: 存储缓存的UI元素渲染结果 +@enduml diff --git a/src/core/mirage.cpp b/src/core/mirage.cpp index 36aaf1a..516a3b6 100644 --- a/src/core/mirage.cpp +++ b/src/core/mirage.cpp @@ -3,10 +3,10 @@ #include "async/thread_pool.h" #include "window/window_manager.h" -mirage::duration_type delta_time = {}; -mirage::time_type begin_time = {}; -mirage::time_type last_time = {}; -LLGL::RenderSystemPtr renderer = nullptr; +mirage::duration_type delta_time = {}; +mirage::time_type begin_time = {}; +mirage::time_type last_time = {}; +LLGL::RenderSystemPtr renderer = nullptr; namespace mirage { void on_llgl_log(LLGL::Log::ReportType type, const char* text, void* user_data) { @@ -51,6 +51,7 @@ namespace mirage { spdlog::info("供应商: {}", renderer_info.vendorName.c_str()); spdlog::info("着色器语言: {}", renderer_info.shadingLanguageName.c_str()); spdlog::info("渲染器加载成功"); + return true; } bool init_window(const init_info& in_info) { @@ -66,6 +67,10 @@ namespace mirage { spdlog::info("主窗口创建成功"); return true; } + void destroy_renderer() { + LLGL::RenderSystem::Unload(std::move(renderer)); + } + bool init(const init_info& in_info) { spdlog::info("初始化 mirage"); @@ -84,7 +89,7 @@ namespace mirage { if (!lazy_singleton::get().destroy()) { spdlog::warn("窗口管理器销毋失败"); } - LLGL::RenderSystem::Unload(std::move(renderer)); + destroy_renderer(); spdlog::info("mirage 销毁"); } @@ -114,6 +119,7 @@ namespace mirage { return renderer_api::vulkan; #endif } + int run(const init_info& in_init_info) { try { if (!init(in_init_info)) { @@ -144,4 +150,7 @@ namespace mirage { LLGL::RenderSystem* get_renderer() { return renderer.get(); } + LLGL::CommandQueue* get_main_command_queue() { + return renderer->GetCommandQueue(); + } } // namespace mirage diff --git a/src/core/mirage.h b/src/core/mirage.h index fdc02ad..0c63422 100644 --- a/src/core/mirage.h +++ b/src/core/mirage.h @@ -20,4 +20,5 @@ namespace mirage { duration_type get_total_time(); LLGL::RenderSystem* get_renderer(); + LLGL::CommandQueue* get_main_command_queue(); } diff --git a/src/core/misc/mirage_type.h b/src/core/misc/mirage_type.h index 42f84cc..dafd0ec 100644 --- a/src/core/misc/mirage_type.h +++ b/src/core/misc/mirage_type.h @@ -1,6 +1,7 @@ #pragma once #include #include "LLGL/LLGL.h" +#include namespace mirage { using time_type = decltype(std::chrono::high_resolution_clock::now()); @@ -76,4 +77,49 @@ namespace mirage { return desc; } }; -} \ No newline at end of file + + struct vertex_param_pack { + union { + float x; + float r; + }; + union { + float y; + float g; + }; + union { + float z; + float b; + }; + union { + float w; + float a; + }; + vertex_param_pack(float in_x, float in_y, float in_z, float in_w) : x(in_x), y(in_y), z(in_z), w(in_w) {} + vertex_param_pack(const LLGL::ColorRGBAf& in) : r(in.r), g(in.g), b(in.b), a(in.a) {} + vertex_param_pack(const LLGL::Offset2D& in) : x(in.x), y(in.y), z(0), w(0) {} + vertex_param_pack(const LLGL::Extent2D& in) : x(in.width), y(in.height), z(0), w(0) {} + vertex_param_pack(const LLGL::Offset3D& in) : x(in.x), y(in.y), z(in.z), w(0) {} + vertex_param_pack(const LLGL::Extent3D& in) : x(in.width), y(in.height), z(in.depth), w(0) {} + vertex_param_pack(const Eigen::Vector2f& in) : x(in.x()), y(in.y()), z(0), w(0) {} + vertex_param_pack(const Eigen::Vector3f& in) : x(in.x()), y(in.y()), z(in.z()), w(0) {} + vertex_param_pack(const Eigen::Vector4f& in) : x(in.x()), y(in.y()), z(in.z()), w(in.w()) {} + }; + + struct vertex_t { + Eigen::Vector3d position; + Eigen::Vector2d uv; + LLGL::ColorRGBAf color; + vertex_param_pack param_a; + vertex_param_pack param_b; + vertex_param_pack param_c; + }; + + struct triangle_index_t { + int32_t vertex_index[3]; + }; + + struct triangle_t { + vertex_t vertex[3]; + }; +} diff --git a/src/core/renderer/render_buffer.cpp b/src/core/renderer/render_buffer.cpp new file mode 100644 index 0000000..e0183cc --- /dev/null +++ b/src/core/renderer/render_buffer.cpp @@ -0,0 +1,135 @@ +#include "render_buffer.h" + +namespace mirage { + render_buffer::~render_buffer() { + if (buffer) { + get_renderer()->Release(*buffer); + } + } + void render_buffer::init(const LLGL::BufferDescriptor& in_desc) { + if (buffer) { + throw std::runtime_error("Buffer already initialized"); + } + + LLGL::BufferDescriptor desc = in_desc; + desc.size = std::max(desc.size, DEFAULT_INITIAL_SIZE); + + buffer = get_renderer()->CreateBuffer(desc); + if (!buffer) { + throw std::runtime_error("Failed to create buffer"); + } + + capacity = desc.size; + access_flags = desc.cpuAccessFlags; + } + void render_buffer::reserve(size_t new_capacity) { + if (new_capacity > capacity) { + resize(new_capacity, true); + } + } + void render_buffer::shrink_to_fit() { + if (capacity > size) { + resize(size, true); + } + } + void render_buffer::resize(size_t in_capacity_size, bool in_keep_data) { + if (in_capacity_size <= capacity) { + return; + } + LLGL::BufferDescriptor desc = buffer->GetDesc(); + desc.size = in_capacity_size; + auto new_buffer = get_renderer()->CreateBuffer(desc); + if (!new_buffer) { + spdlog::error("无法创建缓冲区"); + return; + } + + if (in_keep_data) { + const auto old_data = read(); + get_renderer()->WriteBuffer(*new_buffer, 0, old_data->get_data(), old_data->get_size_bytes()); + } else { + size = 0; + } + + if (buffer) { + get_renderer()->Release(*buffer); + } + buffer = new_buffer; + capacity = in_capacity_size; + } + void render_buffer::clear() { + size = 0; + } + heap_ptr render_buffer::read(size_t in_offset, size_t in_size) const { + if (in_offset + in_size > size) { + spdlog::error("读取缓冲区越界"); + return {}; + } + auto out_heap = std::make_shared(in_size); + get_renderer()->ReadBuffer(*buffer, in_offset, *out_heap, in_size); + return out_heap; + } + heap_ptr render_buffer::read() const { + return read(0, size); + } + void render_buffer::push(const void* data, size_t in_data_size) { + if (size + in_data_size > capacity) { + // 使用更智能的增长策略 + const size_t new_capacity = std::max(static_cast(capacity * GROWTH_FACTOR), size + in_data_size); + resize(new_capacity); + } + + // 批量写入优化 + if (access_flags & LLGL::CPUAccessFlags::Write) { + // 如果支持直接写入,使用映射方式 + if (auto mapped_data = get_renderer()->MapBuffer(*buffer, LLGL::CPUAccess::WriteOnly)) { + std::memcpy(static_cast(mapped_data) + size, data, in_data_size); + get_renderer()->UnmapBuffer(*buffer); + } + } else { + // 否则使用WriteBuffer + get_renderer()->WriteBuffer(*buffer, size, data, in_data_size); + } + size += in_data_size; + } + void render_buffer::update_async(const void* data, size_t offset, size_t size) { + if (offset + size > capacity) { + throw std::out_of_range("Buffer update out of bounds"); + } + + if (offset + size > capacity) { + throw std::out_of_range("Buffer update out of bounds"); + } + + // 使用 RAII 方式获取命令缓冲区 + const scoped_command cmd; + if (!cmd.is_valid()) { + throw std::runtime_error("Failed to acquire command buffer"); + } + + // 复制数据到临时缓冲区(如果需要) + std::vector temp_data(static_cast(data), static_cast(data) + size); + + // 更新缓冲区 + cmd->UpdateBuffer(*buffer, offset, temp_data.data(), size); + + // 提交到命令队列(scoped_command 析构时会自动 End) + get_main_command_queue()->Submit(*cmd); + } + void render_buffer::batch_update_async(const std::vector& updates) { + scoped_command cmd; + if (!cmd.is_valid()) { + throw std::runtime_error("Failed to acquire command buffer"); + } + + for (const auto& update : updates) { + if (update.offset + update.size > capacity) { + spdlog::warn("跳过越界更新"); + continue; + } + cmd->UpdateBuffer(*buffer, update.offset, update.data, update.size); + } + + get_main_command_queue()->Submit(*cmd); + } +} // namespace mirage diff --git a/src/core/renderer/render_buffer.h b/src/core/renderer/render_buffer.h new file mode 100644 index 0000000..9ea0961 --- /dev/null +++ b/src/core/renderer/render_buffer.h @@ -0,0 +1,110 @@ +#pragma once +#include "LLGL/LLGL.h" +#include "mirage.h" +#include "render_command_pool.h" +#include + +namespace mirage { + struct heap { + explicit heap(size_t in_size) : size(in_size) { + data = std::make_unique(in_size); + } + auto get_size() const { + return size; + } + auto get_size_bytes() const { + return size; + } + auto get_data() const { + return data.get(); + } + + operator std::span() const { + return {data.get(), size}; + } + operator std::span() const { + return {data.get(), size}; + } + operator uint8_t*() const { + return data.get(); + } + operator void*() const { + return data.get(); + } + + private: + std::unique_ptr data; + size_t size; + }; + + using heap_ptr = std::shared_ptr; + + class render_buffer { + public: + // 添加预分配大小的常量 + static constexpr size_t DEFAULT_INITIAL_SIZE = 1024; + static constexpr float GROWTH_FACTOR = 2.0f; + + render_buffer() : buffer(nullptr), size(0), capacity(0), access_flags(0) {} + // 禁用拷贝操作 + render_buffer(const render_buffer&) = delete; + render_buffer& operator=(const render_buffer&) = delete; + + ~render_buffer(); + + void init(const LLGL::BufferDescriptor& in_desc); + + // 预留空间 + void reserve(size_t new_capacity); + + // 收缩到适合大小 + void shrink_to_fit(); + void resize(size_t in_capacity_size, bool in_keep_data = true); + void clear(); + + [[nodiscard]] heap_ptr read(size_t in_offset, size_t in_size) const; + [[nodiscard]] heap_ptr read() const; + + void push(const void* data, size_t in_data_size); + template + void push(std::span data) { + push(data.data(), data.size_bytes()); + } + template + void push(const T& data) { + push(&data, sizeof(T)); + } + + // 异步更新缓冲区 + struct update_info { + const void* data; + size_t offset; + size_t size; + }; + void update_async(const void* data, size_t offset, size_t size); + void batch_update_async(const std::vector& updates); + + [[nodiscard]] size_t get_size() const { + return size; + } + [[nodiscard]] size_t get_capacity() const { + return capacity; + } + [[nodiscard]] bool is_empty() const { + return size == 0; + } + + operator LLGL::Buffer*() const { + return buffer; + } + operator bool() const { + return buffer; + } + + private: + LLGL::Buffer* buffer; + size_t size; + size_t capacity; + long access_flags; + }; +} // namespace mirage diff --git a/src/core/renderer/render_command_pool.cpp b/src/core/renderer/render_command_pool.cpp new file mode 100644 index 0000000..f4d24a0 --- /dev/null +++ b/src/core/renderer/render_command_pool.cpp @@ -0,0 +1,60 @@ +#include "render_command_pool.h" + +#include "mirage.h" +#include + +namespace mirage { + + LLGL::CommandBuffer* render_command_pool::acquire() { + std::lock_guard lock(mutex); + + // 检查是否有可用的命令缓冲区 + for (auto& buffer : buffers) { + if (!buffer.in_use) { + buffer.in_use = true; + return buffer.cmd_buffer; + } + } + + // 如果没有可用的,创建新的 + return create_new_buffer(); + } + void render_command_pool::release(const LLGL::CommandBuffer* in_cmd_buffer) { + std::lock_guard lock(mutex); + + for (auto& buffer : buffers) { + if (buffer.cmd_buffer == in_cmd_buffer) { + buffer.in_use = false; + return; + } + } + } + void render_command_pool::cleanup() { + std::lock_guard lock(mutex); + + for (auto& buffer : buffers) { + if (buffer.cmd_buffer) { + get_renderer()->Release(*buffer.cmd_buffer); + } + } + buffers.clear(); + } + LLGL::CommandBuffer* render_command_pool::create_new_buffer() { + if (buffers.size() >= MAX_POOL_SIZE) { + spdlog::warn("Command pool reached maximum size"); + return nullptr; + } + + LLGL::CommandBufferDescriptor desc; + desc.flags = LLGL::CommandBufferFlags::ImmediateSubmit; + + auto* cmd_buffer = get_renderer()->CreateCommandBuffer(desc); + if (!cmd_buffer) { + spdlog::error("Failed to create command buffer"); + return nullptr; + } + + buffers.push_back({cmd_buffer, true}); + return cmd_buffer; + } +} // namespace mirage diff --git a/src/core/renderer/render_command_pool.h b/src/core/renderer/render_command_pool.h new file mode 100644 index 0000000..ee24e21 --- /dev/null +++ b/src/core/renderer/render_command_pool.h @@ -0,0 +1,67 @@ +#pragma once +#include "LLGL/LLGL.h" +#include "misc/lazy_singleton.h" +#include + +namespace mirage { + class render_command_pool { + friend class lazy_singleton_func; + public: + // 获取一个可用的命令缓冲区 + LLGL::CommandBuffer* acquire(); + + // 释放命令缓冲区回池 + void release(const LLGL::CommandBuffer* in_cmd_buffer); + + // 清理所有资源 + void cleanup(); + private: + struct buffer_entry { + LLGL::CommandBuffer* cmd_buffer = nullptr; + bool in_use = false; + }; + + std::vector buffers; + std::mutex mutex; + + static constexpr size_t INITIAL_POOL_SIZE = 4; + static constexpr size_t MAX_POOL_SIZE = 16; + + render_command_pool() { + // 预创建一些命令缓冲区 + for (size_t i = 0; i < INITIAL_POOL_SIZE; ++i) { + create_new_buffer(); + } + } + + ~render_command_pool() { + cleanup(); + } + + LLGL::CommandBuffer* create_new_buffer(); + }; + + // RAII 包装器用于自动管理命令缓冲区的获取和释放 + class scoped_command { + public: + scoped_command() : cmd_buffer(lazy_singleton::get().acquire()) { + if (cmd_buffer) { + cmd_buffer->Begin(); + } + } + + ~scoped_command() { + if (cmd_buffer) { + cmd_buffer->End(); + lazy_singleton::get().release(cmd_buffer); + } + } + + operator LLGL::CommandBuffer*() const { return cmd_buffer; } + LLGL::CommandBuffer* operator->() const { return cmd_buffer; } + + [[nodiscard]] bool is_valid() const { return cmd_buffer != nullptr; } + private: + LLGL::CommandBuffer* cmd_buffer; + }; +} // namespace mirage diff --git a/src/core/renderer/render_context.cpp b/src/core/renderer/render_context.cpp index 0af9f90..7cb067d 100644 --- a/src/core/renderer/render_context.cpp +++ b/src/core/renderer/render_context.cpp @@ -1,17 +1,12 @@ #include "render_context.h" +#include "LLGL/Utils/VertexFormat.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); + if (command_buffer) { + get_renderer()->Release(*command_buffer); } } bool render_context::init(const swap_chain_descriptor& in_desc, const std::shared_ptr& in_surface) { @@ -22,30 +17,30 @@ namespace mirage { spdlog::error("无法创建交换链"); return false; } - main_command_buffer = get_renderer()->CreateCommandBuffer(LLGL::CommandBufferFlags::ImmediateSubmit); - if (main_command_buffer == nullptr) { + command_buffer = get_renderer()->CreateCommandBuffer(LLGL::CommandBufferFlags::ImmediateSubmit); + if (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); + create_vertex_buffer(); + create_index_buffer(); return true; } render_context::update_status render_context::update(const duration_type& in_delta_time) { - if (!main_command_buffer || !swap_chain) { + if (!command_buffer || !swap_chain) { return update_status::fail; } if (!swap_chain->IsPresentable()) { return update_status::wait_for_present; } - main_command_buffer->Begin(); + 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(); + command_buffer->BeginRenderPass(*swap_chain); + command_buffer->Clear(LLGL::ClearFlags::Color, {0.1f, 0.1f, 0.2f, 1.0f}); + command_buffer->EndRenderPass(); } - main_command_buffer->End(); + command_buffer->End(); swap_chain->Present(); return update_status::success; } @@ -62,4 +57,29 @@ namespace mirage { spdlog::info("垂直同步: {}", vsync); } } + + void render_context::create_vertex_buffer() { + // 创建顶点格式布局 + LLGL::VertexFormat vertexFormat; + + // 添加顶点属性 + vertexFormat.AppendAttribute({"position", LLGL::Format::RGB32Float}); // float3 position + vertexFormat.AppendAttribute({"texCoord0", LLGL::Format::RG32Float}); // float2 uv + vertexFormat.AppendAttribute({"color", LLGL::Format::RGBA32Float}); // float4 color + vertexFormat.AppendAttribute({"texCoord1", LLGL::Format::RGBA32Float}); // float4 param_a + vertexFormat.AppendAttribute({"texCoord2", LLGL::Format::RGBA32Float}); // float4 param_b + vertexFormat.AppendAttribute({"texCoord3", LLGL::Format::RGBA32Float}); // float4 param_c + + LLGL::BufferDescriptor vertex_buffer_descriptor{}; + vertex_buffer_descriptor.size = sizeof(vertex_t) * 512; + vertex_buffer_descriptor.bindFlags = LLGL::BindFlags::VertexBuffer; + vertex_buffer_descriptor.vertexAttribs = vertexFormat.attributes; + vertex_buffer.init(vertex_buffer_descriptor); + } + void render_context::create_index_buffer() { + LLGL::BufferDescriptor index_buffer_descriptor{}; + index_buffer_descriptor.size = sizeof(triangle_index_t) * 512; + index_buffer_descriptor.bindFlags = LLGL::BindFlags::IndexBuffer; + index_buffer.init(index_buffer_descriptor); + } } // namespace mirage diff --git a/src/core/renderer/render_context.h b/src/core/renderer/render_context.h index b8b7d78..c158da5 100644 --- a/src/core/renderer/render_context.h +++ b/src/core/renderer/render_context.h @@ -1,15 +1,13 @@ #pragma once #include "LLGL/LLGL.h" #include "misc/mirage_type.h" +#include "render_buffer.h" +#include namespace mirage { class render_context { public: - enum class update_status { - success, - wait_for_present, - fail - }; + enum class update_status { success, wait_for_present, fail }; ~render_context(); @@ -24,10 +22,21 @@ namespace mirage { [[nodiscard]] auto get_swap_chain() const { return swap_chain; } + + [[nodiscard]] size_t get_vertex_count() const { + return vertex_buffer.get_size() / sizeof(vertex_t); + } + [[nodiscard]] size_t get_index_count() const { + return index_buffer.get_size() / sizeof(triangle_index_t); + } private: - LLGL::SwapChain* swap_chain = nullptr; - LLGL::Buffer* vertex_buffer = nullptr; - LLGL::CommandBuffer* main_command_buffer = nullptr; - bool vsync = true; + void create_vertex_buffer(); + void create_index_buffer(); + + render_buffer vertex_buffer; + render_buffer index_buffer; + LLGL::CommandBuffer* command_buffer = nullptr; + LLGL::SwapChain* swap_chain = nullptr; + bool vsync = true; }; } // namespace mirage diff --git a/src/core/renderer/render_draw_command.cpp b/src/core/renderer/render_draw_command.cpp new file mode 100644 index 0000000..4969127 --- /dev/null +++ b/src/core/renderer/render_draw_command.cpp @@ -0,0 +1 @@ +#include "render_draw_command.h" diff --git a/src/core/renderer/render_draw_command.h b/src/core/renderer/render_draw_command.h new file mode 100644 index 0000000..e80a353 --- /dev/null +++ b/src/core/renderer/render_draw_command.h @@ -0,0 +1,7 @@ +#pragma once + +namespace mirage { + class render_draw_command { + + }; +} diff --git a/src/core/shaders/aorii_util.slang b/src/core/shaders/aorii_util.slang index a4fc118..1cfec2a 100644 --- a/src/core/shaders/aorii_util.slang +++ b/src/core/shaders/aorii_util.slang @@ -1,5 +1,5 @@ struct VSInput { - float2 position : POSITION; + float3 position : POSITION; float2 uv : TEXCOORD0; float4 color : COLOR0; float4 param_a : TEXCOORD1;