From 4ccc968818375b057c93f8c7fc8f2ae355cbe30c Mon Sep 17 00:00:00 2001 From: Nanako <469449812@qq.com> Date: Tue, 5 Nov 2024 23:55:57 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=98=E5=88=B6=E5=9C=86=E8=A7=92=E7=9F=A9?= =?UTF-8?q?=E5=BD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 1 - cmake/compile_shaders.cmake | 13 +++-- example/CMakeLists.txt | 6 --- src/renderer/CMakeLists.txt | 15 ++++++ src/renderer/backend/dx/dx_pipeline.cpp | 35 ++++++------ src/renderer/backend/dx/dx_pipeline.h | 9 ++-- src/renderer/backend/dx/dx_renderer.cpp | 35 +++++++++++- src/renderer/backend/dx/dx_renderer.h | 13 ++++- src/renderer/backend/dx/dx_window.cpp | 32 +++-------- src/renderer/core/pipeline/pipeline.h | 1 + src/renderer/core/renderer/renderer.cpp | 5 ++ src/renderer/core/renderer/renderer.h | 4 +- .../core/renderer/renderer_context.cpp | 12 +++-- src/renderer/core/renderer/renderer_context.h | 22 ++++++-- src/renderer/core/window/window_manager.cpp | 4 +- src/renderer/shader/default_shader.slang | 54 +++++++++---------- 16 files changed, 159 insertions(+), 102 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ea79d4..25efb23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,4 +26,3 @@ set(BUILD_EXAMPLE FALSE CACHE BOOL "Build example") if (BUILD_EXAMPLE) add_subdirectory(example) endif () - diff --git a/cmake/compile_shaders.cmake b/cmake/compile_shaders.cmake index eb86907..9a6e760 100644 --- a/cmake/compile_shaders.cmake +++ b/cmake/compile_shaders.cmake @@ -21,13 +21,18 @@ function(compile_slang_shaders input_file stage entry_point) # 初始化一个列表来存储输出文件 set(output_files) + set(extra_args ${ARGN}) + # 如果是debug模式,添加调试标志 + if(CMAKE_BUILD_TYPE STREQUAL "Debug") + list(APPEND extra_args "-g") + endif() # 为每个后台创建自定义命令 if(GL_BACKEND) set(output_file ${output_dir}/${filename}_${entry_point}.glsl) add_custom_command( OUTPUT ${output_file} - COMMAND slangc -target glsl -entry ${entry_point} -stage ${stage} ${ARGN} -o ${output_file} ${input_file} + COMMAND slangc -target glsl -entry ${entry_point} -stage ${stage} ${extra_args} -o ${output_file} ${input_file} DEPENDS ${input_file} COMMENT "Compiling ${input_file} to GLSL (${stage}, ${entry_point})" ) @@ -38,7 +43,7 @@ function(compile_slang_shaders input_file stage entry_point) set(output_file ${output_dir}/${filename}_${entry_point}.dxbc) add_custom_command( OUTPUT ${output_file} - COMMAND slangc -target dxbc -profile ${profile} -entry ${entry_point} -stage ${stage} ${ARGN} -o ${output_file} ${input_file} + COMMAND slangc -target dxbc -profile ${profile} -entry ${entry_point} -stage ${stage} ${extra_args} -o ${output_file} ${input_file} DEPENDS ${input_file} COMMENT "Compiling ${input_file} to DXBC (${stage}, ${entry_point}) with profile ${profile}" ) @@ -49,7 +54,7 @@ function(compile_slang_shaders input_file stage entry_point) set(output_file ${output_dir}/${filename}_${entry_point}.spirv) add_custom_command( OUTPUT ${output_file} - COMMAND slangc -target spirv -entry ${entry_point} -stage ${stage} ${ARGN} -o ${output_file} ${input_file} + COMMAND slangc -target spirv -entry ${entry_point} -stage ${stage} ${extra_args} -o ${output_file} ${input_file} DEPENDS ${input_file} COMMENT "Compiling ${input_file} to SPIR-V (${stage}, ${entry_point})" ) @@ -60,7 +65,7 @@ function(compile_slang_shaders input_file stage entry_point) set(output_file ${output_dir}/${filename}_${entry_point}.metal) add_custom_command( OUTPUT ${output_file} - COMMAND slangc -target msl -entry ${entry_point} -stage ${stage} ${ARGN} -o ${output_file} ${input_file} + COMMAND slangc -target msl -entry ${entry_point} -stage ${stage} ${extra_args} -o ${output_file} ${input_file} DEPENDS ${input_file} COMMENT "Compiling ${input_file} to Metal Shading Language (${stage}, ${entry_point})" ) diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 9976ced..6ba6266 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -5,9 +5,3 @@ set(SRC_FILES "") retrieve_files(src SRC_FILES) add_executable(${PROJECT_NAME} ${SRC_FILES}) target_link_libraries(${PROJECT_NAME} PRIVATE aorii_renderer) - -# 复制${SHADER_OUTPUT_DIR}文件到${CMAKE_CURRENT_BINARY_DIR}/resource -add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${SHADER_OUTPUT_DIR} $/resource/shaders - COMMENT "Copying shader files to resource directory after build") diff --git a/src/renderer/CMakeLists.txt b/src/renderer/CMakeLists.txt index f9c4f9a..7fc8856 100644 --- a/src/renderer/CMakeLists.txt +++ b/src/renderer/CMakeLists.txt @@ -62,3 +62,18 @@ compile_slang_shaders("${CMAKE_CURRENT_SOURCE_DIR}/shader/default_shader.slang" compile_slang_shaders("${CMAKE_CURRENT_SOURCE_DIR}/shader/default_shader.slang" "pixel" "pixel_main") compile_slang_shaders("${CMAKE_CURRENT_SOURCE_DIR}/shader/default_shader.slang" "pixel" "rounded_rect_pixel_main" -D IS_ROUNDED_RECT) add_compile_shaders_target("compile_aorii_shaders" ${PROJECT_NAME}) + +if (BUILD_EXAMPLE) + # 复制${SHADER_OUTPUT_DIR}文件到${CMAKE_CURRENT_BINARY_DIR}/example/resource/shaders + set(SOURCE_DIR ${SHADER_OUTPUT_DIR}) + set(DEST_DIR ${CMAKE_BINARY_DIR}/example/resource/shaders) + + # 添加自定义命令, 当外部目标compile_aorii_shaders被编译时, 将${SOURCE_DIR}文件复制到${DEST_DIR} + add_custom_command( + TARGET compile_aorii_shaders + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${DEST_DIR} + COMMAND ${CMAKE_COMMAND} -E copy_directory ${SOURCE_DIR} ${DEST_DIR} + COMMENT "Copying shaders to ${DEST_DIR}" + ) +endif () \ No newline at end of file diff --git a/src/renderer/backend/dx/dx_pipeline.cpp b/src/renderer/backend/dx/dx_pipeline.cpp index 64d42b1..372edae 100644 --- a/src/renderer/backend/dx/dx_pipeline.cpp +++ b/src/renderer/backend/dx/dx_pipeline.cpp @@ -6,11 +6,12 @@ #include "dx_renderer.h" #include "core/renderer/renderer.h" +dx_pipeline::dx_pipeline(): vertex_buffer(buffer_type::vertex, 4), triangle_buffer(buffer_type::index, 2), constant_buffer(buffer_type::constant, 1) { +} + dx_pipeline::~dx_pipeline() { if (vertex_shader) { vertex_shader->Release(); } if (pixel_shader) { pixel_shader->Release(); } - delete vertex_buffer; - delete constant_buffer; } void dx_pipeline::use() { @@ -26,9 +27,9 @@ void dx_pipeline::draw() { // 设置顶点缓冲区 constexpr UINT stride = sizeof(aorii_vertex_type); constexpr UINT offset = 0; - auto* v_buffer = static_cast(vertex_buffer->get_native_handle()); - auto* i_buffer = static_cast(triangle_buffer->get_native_handle()); - auto* c_buffer = static_cast(constant_buffer->get_native_handle()); + auto* v_buffer = static_cast(vertex_buffer.get_native_handle()); + auto* i_buffer = static_cast(triangle_buffer.get_native_handle()); + auto* c_buffer = static_cast(constant_buffer.get_native_handle()); d3d_context->IASetVertexBuffers(0, 1, &v_buffer, &stride, &offset); d3d_context->IASetIndexBuffer(i_buffer, DXGI_FORMAT_R32_UINT, 0); d3d_context->VSSetConstantBuffers(0, 1, &c_buffer); @@ -38,7 +39,7 @@ void dx_pipeline::draw() { d3d_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); // 绘制矩形 - d3d_context->Draw(vertex_buffer->get_size(), 0); + d3d_context->Draw(vertex_buffer.get_size(), 0); } void dx_pipeline::load_pixel_shader(const char* shader_name) { @@ -66,30 +67,24 @@ void dx_pipeline::load_vertex_shader() { spdlog::critical("无法创建输入布局: {0}", hr); return; } - vertex_buffer = new dx_buffer(buffer_type::vertex, 4); - triangle_buffer = new dx_buffer(buffer_type::index, 2); -} - -void dx_pipeline::build_constant_buffer() { - constant_buffer = new dx_buffer(buffer_type::constant, 1); } void dx_pipeline::set_triangle(const std::span& in_vertexes, const std::span& in_triangles) { - if (vertex_buffer->get_size() < in_vertexes.size()) { vertex_buffer->resize(in_vertexes.size()); } - aorii_vertex_type* v_buffer = vertex_buffer->lock(); + if (vertex_buffer.get_size() < in_vertexes.size()) { vertex_buffer.resize(static_cast(in_vertexes.size())); } + aorii_vertex_type* v_buffer = vertex_buffer.lock(); std::ranges::copy(in_vertexes, v_buffer); - vertex_buffer->unlock(); + vertex_buffer.unlock(); - if (triangle_buffer->get_size() < in_triangles.size()) { triangle_buffer->resize(in_triangles.size()); } - aorii_triangle_type* i_buffer = triangle_buffer->lock(); + if (triangle_buffer.get_size() < in_triangles.size()) { triangle_buffer.resize(static_cast(in_triangles.size())); } + aorii_triangle_type* i_buffer = triangle_buffer.lock(); std::ranges::copy(in_triangles, i_buffer); - triangle_buffer->unlock(); + triangle_buffer.unlock(); } -aorii_constant_buffer_type* dx_pipeline::lock_constant_buffer() { return constant_buffer->lock(); } +aorii_constant_buffer_type* dx_pipeline::lock_constant_buffer() { return constant_buffer.lock(); } -void dx_pipeline::unlock_constant_buffer() { constant_buffer->unlock(); } +void dx_pipeline::unlock_constant_buffer() { constant_buffer.unlock(); } std::vector dx_pipeline::load_shader(const std::string& shader_name) { auto file_pathname = aorii::get_shader_path(shader_name).generic_string() + ".dxbc"; diff --git a/src/renderer/backend/dx/dx_pipeline.h b/src/renderer/backend/dx/dx_pipeline.h index 2e65a6f..eb46b24 100644 --- a/src/renderer/backend/dx/dx_pipeline.h +++ b/src/renderer/backend/dx/dx_pipeline.h @@ -10,6 +10,7 @@ class dx_pipeline : public pipeline { public: + dx_pipeline(); ~dx_pipeline() override; void use() override; void draw() override; @@ -17,8 +18,6 @@ public: void load_pixel_shader(const char* shader_name); void load_vertex_shader(); - void build_constant_buffer(); - void set_triangle(const std::span& in_vertexes, const std::span& in_triangles) override; aorii_constant_buffer_type* lock_constant_buffer() override; @@ -31,8 +30,8 @@ private: ID3D11InputLayout* input_layout = nullptr; - dx_buffer* vertex_buffer = nullptr; - dx_buffer* triangle_buffer = nullptr; - dx_buffer* constant_buffer = nullptr; + dx_buffer vertex_buffer; + dx_buffer triangle_buffer; + dx_buffer constant_buffer; int vertex_count = 0; }; diff --git a/src/renderer/backend/dx/dx_renderer.cpp b/src/renderer/backend/dx/dx_renderer.cpp index c19c514..5d11ea7 100644 --- a/src/renderer/backend/dx/dx_renderer.cpp +++ b/src/renderer/backend/dx/dx_renderer.cpp @@ -12,10 +12,43 @@ bool dx_renderer::init() { glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); if (!create_device()) return false; + + D3D11_BLEND_DESC blend_desc = {}; + blend_desc.RenderTarget[0].BlendEnable = TRUE; + blend_desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + blend_desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + blend_desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blend_desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blend_desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + blend_desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + blend_desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + auto hr = device->CreateBlendState(&blend_desc, &blend_state); + if (FAILED(hr)) { + spdlog::critical("无法创建混合状态, 错误: {0}", hr); + return false; + } + + default_pipeline = new dx_pipeline(); + rounded_rect_pipeline = new dx_pipeline(); + + default_pipeline->load_pixel_shader(AORII_DEFAULT_PIXEL_SHADER_NAME); + default_pipeline->load_vertex_shader(); + + rounded_rect_pipeline->load_pixel_shader(AORII_DEFAULT_ROUNDED_RECT_PIXEL_SHADER_NAME); + rounded_rect_pipeline->load_vertex_shader(); + return true; } -void dx_renderer::destroy() { glfwTerminate(); } +void dx_renderer::destroy() { + if (blend_state) blend_state->Release(); + delete default_pipeline; + delete rounded_rect_pipeline; + default_pipeline = nullptr; + rounded_rect_pipeline = nullptr; + glfwTerminate(); +} bool dx_renderer::render() { const auto& all_window = aorii::get_all_window(); diff --git a/src/renderer/backend/dx/dx_renderer.h b/src/renderer/backend/dx/dx_renderer.h index 2c289f3..27236b1 100644 --- a/src/renderer/backend/dx/dx_renderer.h +++ b/src/renderer/backend/dx/dx_renderer.h @@ -3,6 +3,7 @@ #include "core/renderer/renderer.h" +class dx_pipeline; class dx_window; class dx_renderer : public renderer { @@ -14,8 +15,12 @@ public: renderer_texture* create_texture(const Eigen::Vector2i& size) override; void destroy_texture(renderer_texture* texture) override; - ID3D11Device* get_d3d_device() const { return device; } - ID3D11DeviceContext* get_d3d_context() const { return context; } + [[nodiscard]] ID3D11Device* get_d3d_device() const { return device; } + [[nodiscard]] ID3D11DeviceContext* get_d3d_context() const { return context; } + + [[nodiscard]] dx_pipeline* get_default_pipeline() const { return default_pipeline; } + [[nodiscard]] dx_pipeline* get_rounded_rect_pipeline() const { return rounded_rect_pipeline; } + [[nodiscard]] ID3D11BlendState* get_blend_state() const { return blend_state; } private: renderer_window* create_window() override; @@ -23,5 +28,9 @@ private: ID3D11Device* device = nullptr; ID3D11DeviceContext* context = nullptr; + ID3D11BlendState* blend_state = nullptr; + + dx_pipeline* default_pipeline = nullptr; + dx_pipeline* rounded_rect_pipeline = nullptr; }; diff --git a/src/renderer/backend/dx/dx_window.cpp b/src/renderer/backend/dx/dx_window.cpp index cc1c5f8..24008ec 100644 --- a/src/renderer/backend/dx/dx_window.cpp +++ b/src/renderer/backend/dx/dx_window.cpp @@ -5,14 +5,11 @@ #include "dx_renderer.h" #include "misc/scope_exit.h" -#include - using namespace aorii; -dx_pipeline default_pipeline; -dx_pipeline rounded_rect_pipeline; bool dx_window::create_surface(GLFWwindow* in_window) { - const auto d3d_device = aorii::get_renderer()->get_d3d_device(); + auto dx = aorii::get_renderer(); + const auto d3d_device = dx->get_d3d_device(); IDXGIDevice* dxgi_device = nullptr; auto hr = d3d_device->QueryInterface(__uuidof(IDXGIDevice), reinterpret_cast(&dxgi_device)); @@ -62,23 +59,14 @@ bool dx_window::create_surface(GLFWwindow* in_window) { return false; } - default_pipeline.build_constant_buffer(); - rounded_rect_pipeline.build_constant_buffer(); - hr = build_render_target_view(); if (FAILED(hr)) { spdlog::critical("无法创建渲染模板视图, 错误: {0}", hr); return false; } - default_pipeline.load_pixel_shader(AORII_DEFAULT_PIXEL_SHADER_NAME); - default_pipeline.load_vertex_shader(); - - rounded_rect_pipeline.load_pixel_shader(AORII_DEFAULT_ROUNDED_RECT_PIXEL_SHADER_NAME); - rounded_rect_pipeline.load_vertex_shader(); - - context.set_default_pipeline(&default_pipeline); - context.set_rounded_rectangular_pipeline(&rounded_rect_pipeline); + context.set_default_pipeline(dx->get_default_pipeline()); + context.set_rounded_rectangular_pipeline(dx->get_rounded_rect_pipeline()); return true; } @@ -90,6 +78,7 @@ void dx_window::begin_frame() { const auto d3d_context = render->get_d3d_context(); d3d_context->OMSetRenderTargets(1, &render_target_view, nullptr); + d3d_context->OMSetBlendState(render->get_blend_state(), nullptr, 0xffffffff); d3d_context->ClearRenderTargetView(render_target_view, clear_color); if constexpr (false) { @@ -136,7 +125,7 @@ void dx_window::begin_frame() { } } - context.draw_rounded_rectangle({ 100, 100 }, { 100, 100 }, { 1, 0, 0, 1 }, 10); + context.draw_rounded_rectangle({ 100, 100 }, { 200, 200 }, { 1, 0, 0, 1 }, 10); context.flush(); swap_chain->Present(1, 0); @@ -195,14 +184,7 @@ HRESULT dx_window::build_render_target_view() { const auto& projection_matrix = get_projection_matrix().transpose(); - // 更新常量缓冲区 - const auto constant_buffer = default_pipeline.lock_constant_buffer(); - constant_buffer->projection_matrix = projection_matrix; - default_pipeline.unlock_constant_buffer(); - - const auto rounded_rect_constant_buffer = rounded_rect_pipeline.lock_constant_buffer(); - rounded_rect_constant_buffer->projection_matrix = projection_matrix; - rounded_rect_pipeline.unlock_constant_buffer(); + context.set_projection_matrix(projection_matrix); return hr; } diff --git a/src/renderer/core/pipeline/pipeline.h b/src/renderer/core/pipeline/pipeline.h index 9931c11..85c7c1f 100644 --- a/src/renderer/core/pipeline/pipeline.h +++ b/src/renderer/core/pipeline/pipeline.h @@ -18,6 +18,7 @@ struct aorii_triangle { }; struct aorii_constant_buffer { Eigen::Matrix4f projection_matrix; + Eigen::Vector2f pos; Eigen::Vector2f size; float radius; }; diff --git a/src/renderer/core/renderer/renderer.cpp b/src/renderer/core/renderer/renderer.cpp index de411bd..e544cc1 100644 --- a/src/renderer/core/renderer/renderer.cpp +++ b/src/renderer/core/renderer/renderer.cpp @@ -10,6 +10,7 @@ std::chrono::duration delta_time = {}; decltype(std::chrono::high_resolution_clock::now()) last_time = {}; +renderer* s_renderer = nullptr; void renderer::tick() { } @@ -18,6 +19,10 @@ void renderer::destroy_window(renderer_window* window) { delete window; } +renderer* aorii::get_renderer_raw() { + return s_renderer; +} + bool aorii::create_renderer(renderer_api api) { if (s_renderer) return true; switch (api) { diff --git a/src/renderer/core/renderer/renderer.h b/src/renderer/core/renderer/renderer.h index 21fe9f0..2fa7928 100644 --- a/src/renderer/core/renderer/renderer.h +++ b/src/renderer/core/renderer/renderer.h @@ -32,11 +32,11 @@ private: }; namespace aorii { - inline renderer* s_renderer; + renderer* get_renderer_raw(); template static T* get_renderer() { - return static_cast(s_renderer); + return static_cast(get_renderer_raw()); } bool create_renderer(renderer_api api); diff --git a/src/renderer/core/renderer/renderer_context.cpp b/src/renderer/core/renderer/renderer_context.cpp index b0413f8..9cad219 100644 --- a/src/renderer/core/renderer/renderer_context.cpp +++ b/src/renderer/core/renderer/renderer_context.cpp @@ -23,13 +23,17 @@ void renderer_context::draw_rectangle(const Eigen::Vector2i& in_pos, const Eigen } void renderer_context::draw_rounded_rectangle(const Eigen::Vector2i& in_pos, const Eigen::Vector2i& in_size, const linear_color& in_color, float in_radius) { - auto constant_buffer = rounded_rectangular_pipeline->lock_constant_buffer(); - constant_buffer->size = in_size.cast(); - constant_buffer->radius = in_radius; - rounded_rectangular_pipeline->unlock_constant_buffer(); + pipeline_context.pos = in_pos.cast(); + pipeline_context.size = in_size.cast(); + pipeline_context.radius = in_radius; switch_pipeline(rounded_rectangular_pipeline); + const auto constant_buffer = rounded_rectangular_pipeline->lock_constant_buffer(); + memcpy(constant_buffer, &pipeline_context, sizeof(aorii_constant_buffer_type)); + rounded_rectangular_pipeline->unlock_constant_buffer(); + + const aorii_vertex_type v1{ { in_pos.x(), in_pos.y() }, in_color }; // 左上角 const aorii_vertex_type v2{ { in_pos.x() + in_size.x(), in_pos.y() }, in_color }; // 右上角 const aorii_vertex_type v3{ { in_pos.x(), in_pos.y() + in_size.y() }, in_color }; // 左下角 diff --git a/src/renderer/core/renderer/renderer_context.h b/src/renderer/core/renderer/renderer_context.h index 2d8a76a..e8adce4 100644 --- a/src/renderer/core/renderer/renderer_context.h +++ b/src/renderer/core/renderer/renderer_context.h @@ -51,12 +51,27 @@ public: } void flush() { if (vertices.empty() || triangles.empty()) return; - if (default_pipeline) { - default_pipeline->set_triangle(vertices, triangles); - default_pipeline->draw(); + if (current_pipeline) { + current_pipeline->set_triangle(vertices, triangles); + current_pipeline->draw(); } clear(); } + void set_projection_matrix(const Eigen::Matrix4f& in_matrix) { + pipeline_context.projection_matrix = in_matrix; + + // 更新默认管线的投影矩阵 + if (default_pipeline) { + auto constant_buffer = default_pipeline->lock_constant_buffer(); + memcpy(constant_buffer, &pipeline_context, sizeof(aorii_constant_buffer_type)); + default_pipeline->unlock_constant_buffer(); + } + + // 圆角矩形管线的投影矩阵不需要更新, 因为它在每次绘制时都会更新 + } + [[nodiscard]] const auto& get_pipeline_context() const { + return pipeline_context; + } protected: void switch_pipeline(pipeline* in_pipeline) { #if DEBUG @@ -72,6 +87,7 @@ protected: private: std::vector vertices; std::vector triangles; + aorii_constant_buffer_type pipeline_context = {}; pipeline* default_pipeline = nullptr; pipeline* rounded_rectangular_pipeline = nullptr; diff --git a/src/renderer/core/window/window_manager.cpp b/src/renderer/core/window/window_manager.cpp index 2eb6166..ee54639 100644 --- a/src/renderer/core/window/window_manager.cpp +++ b/src/renderer/core/window/window_manager.cpp @@ -11,13 +11,13 @@ void on_window_size_change(GLFWwindow* changed_window, int width, int height) { window_manager::~window_manager() { for (const auto window : windows) { - aorii::s_renderer->destroy_window(window); + aorii::get_renderer_raw()->destroy_window(window); } windows.clear(); } renderer_window* window_manager::create_window(const Eigen::Vector2i& in_size, const std::string& in_title) { - const auto window = aorii::s_renderer->create_window(); + const auto window = aorii::get_renderer_raw()->create_window(); if (!window->init(in_size, in_title)) { delete window; spdlog::error("Failed to create window"); diff --git a/src/renderer/shader/default_shader.slang b/src/renderer/shader/default_shader.slang index 09a13c9..a957563 100644 --- a/src/renderer/shader/default_shader.slang +++ b/src/renderer/shader/default_shader.slang @@ -1,36 +1,28 @@ struct ParamBuffer { matrix transform; - float2 size; // 像素单位 - float radius; // 像素单位 + float2 pos; // 屏幕坐标 + float2 size; // 圆角矩形像素单位大小 + float radius; // 圆角像素单位 }; ParameterBlock param_buffer : register(b0); SamplerState texture_sampler : register(s0); struct VSInput { - float2 position : POSITION; - float4 color : COLOR; + float2 position : POSITION; // 窗口坐标 + float4 color : COLOR; // 颜色 }; struct PSInput { - float4 position : SV_POSITION; - float4 color : COLOR; - float2 uv : TEXCOORD0; + float4 position : SV_POSITION; // 裁剪空间坐标 + float4 color : COLOR; // 颜色 }; -// 计算点到矩形边的最小距离 -float rounded_box_SDF(float2 center_position, float2 size, float radius) -{ - float2 q = abs(center_position) - size + radius; - return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius; -} - PSInput vertex_main(VSInput input) { PSInput output; output.position = mul(float4(input.position, 0.0, 1.0), param_buffer.transform); output.color = input.color; - output.uv = (input.position + float2(1.0, 1.0)) * 0.5; // 将 [-1, 1] 映射到 [0, 1] return output; } @@ -38,20 +30,28 @@ PSInput vertex_main(VSInput input) // 圆角矩形像素着色器 float4 rounded_rect_pixel_main(PSInput input) : SV_TARGET { - float2 size = param_buffer.size; + float2 pixel_pos = input.position.xy; + + // 圆角半径 float radius = param_buffer.radius; - // 将UV坐标转换为中心坐标系统 - float2 center_position = (input.uv - 0.5) * size; - - // 计算到圆角矩形边缘的距离 - float distance = rounded_box_SDF(center_position, size * 0.5, radius); - - // 使用平滑步进函数创建抗锯齿边缘 - float alpha = 1.0 - smoothstep(-1.0, 1.0, distance); - - // 返回最终颜色 - return float4(float3(1, 1, 1), input.color.a * alpha); + // 计算矩形的中心位置 + float2 rect_center = param_buffer.pos + param_buffer.size * 0.5; + + // 计算半尺寸,减去圆角半径 + float2 half_size = param_buffer.size * 0.5 - radius; + + // 将坐标系平移到矩形中心 + float2 pos = pixel_pos - rect_center; + + // 计算距离 + float2 d = abs(pos) - half_size; + + // 取最大值与0比较,确保不小于0 + float inside = length(max(d, 0.0)) - radius; + + // inside <= 0.0 说明在圆角矩形内 + return input.color * step(inside, 0.0); } #else float4 pixel_main(PSInput input) : SV_TARGET