diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1a6f20b..2d3e5df 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,7 +1,26 @@ project(mirage_core) set(CMAKE_CXX_STANDARD 26) -find_package(HarfBuzz REQUIRED) +find_package(HarfBuzz) +# 如果HarfBuzz没有找到,则尝试查找harfbuzz +if (NOT HarfBuzz_FOUND) + find_package(harfbuzz REQUIRED) +endif () +# 如果没有harfbuzz则创建别名 +if (NOT TARGET harfbuzz) + # 如果存在HarfBuzz::HarfBuzz则创建别名 + if (TARGET HarfBuzz::HarfBuzz) + add_library(harfbuzz ALIAS HarfBuzz::HarfBuzz) + elseif (TARGET harfbuzz::harfbuzz) + # 否则创建别名 + add_library(harfbuzz ALIAS harfbuzz::harfbuzz) + endif () +endif () +# 检查是否找到HarfBuzz +if (NOT TARGET harfbuzz) + message(FATAL_ERROR "HarfBuzz not found") +endif () + find_package(Eigen3 REQUIRED) find_package(spdlog REQUIRED) find_package(Boost REQUIRED) @@ -12,7 +31,7 @@ set(RENDERER_SOURCES "") retrieve_files(${CMAKE_CURRENT_SOURCE_DIR} RENDERER_SOURCES) add_library(${PROJECT_NAME} STATIC ${RENDERER_SOURCES}) -target_link_libraries(${PROJECT_NAME} PUBLIC Freetype::Freetype harfbuzz::harfbuzz Eigen3::Eigen spdlog::spdlog msdfgen-full Boost::boost Vulkan::Vulkan LLGL) +target_link_libraries(${PROJECT_NAME} PUBLIC Freetype::Freetype harfbuzz Eigen3::Eigen spdlog::spdlog msdfgen-full Boost::boost Vulkan::Vulkan LLGL) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_compile_definitions(${PROJECT_NAME} PRIVATE NOMINMAX) add_os_definitions(${PROJECT_NAME}) diff --git a/src/core/misc/mirage_type.h b/src/core/misc/mirage_type.h index dafd0ec..68fffea 100644 --- a/src/core/misc/mirage_type.h +++ b/src/core/misc/mirage_type.h @@ -78,42 +78,6 @@ namespace mirage { } }; - 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]; diff --git a/src/core/renderer/element_batcher.cpp b/src/core/renderer/element_batcher.cpp new file mode 100644 index 0000000..0116b1b --- /dev/null +++ b/src/core/renderer/element_batcher.cpp @@ -0,0 +1 @@ +#include "element_batcher.h" diff --git a/src/core/renderer/element_batcher.h b/src/core/renderer/element_batcher.h new file mode 100644 index 0000000..56e15c6 --- /dev/null +++ b/src/core/renderer/element_batcher.h @@ -0,0 +1,11 @@ +#pragma once + +namespace mirage { + class element_batcher { + + private: + struct batch_key { + + }; + }; +} diff --git a/src/core/renderer/render_context.h b/src/core/renderer/render_context.h index c158da5..37fa4d5 100644 --- a/src/core/renderer/render_context.h +++ b/src/core/renderer/render_context.h @@ -29,6 +29,10 @@ namespace mirage { [[nodiscard]] size_t get_index_count() const { return index_buffer.get_size() / sizeof(triangle_index_t); } + [[nodiscard]] Eigen::Vector2f get_size() const { + const auto& extent_2d = swap_chain->GetResolution(); + return {extent_2d.width, extent_2d.height}; + } private: void create_vertex_buffer(); void create_index_buffer(); diff --git a/src/core/renderer/render_draw_command.cpp b/src/core/renderer/render_draw_command.cpp deleted file mode 100644 index 4969127..0000000 --- a/src/core/renderer/render_draw_command.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "render_draw_command.h" diff --git a/src/core/renderer/render_draw_command.h b/src/core/renderer/render_draw_command.h deleted file mode 100644 index e80a353..0000000 --- a/src/core/renderer/render_draw_command.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -namespace mirage { - class render_draw_command { - - }; -} diff --git a/src/core/renderer/render_draw_element.cpp b/src/core/renderer/render_draw_element.cpp new file mode 100644 index 0000000..0ea57c2 --- /dev/null +++ b/src/core/renderer/render_draw_element.cpp @@ -0,0 +1 @@ +#include "render_draw_element.h" diff --git a/src/core/renderer/render_draw_element.h b/src/core/renderer/render_draw_element.h new file mode 100644 index 0000000..05b3df4 --- /dev/null +++ b/src/core/renderer/render_draw_element.h @@ -0,0 +1,14 @@ +#pragma once +#include + +namespace mirage { + class render_draw_element { + public: + enum rotation_space { + local, // 相对于元素自身的坐标系 (0, 0)是元素的左上角 + world // 相对于绘制几何体的坐标系 (0, 0)是屏幕的左上角 + }; + + static void make_debug_quad(, uint32_t in_layer, ); + }; +} diff --git a/src/core/renderer/render_element_drawer.cpp b/src/core/renderer/render_element_drawer.cpp new file mode 100644 index 0000000..166d6d8 --- /dev/null +++ b/src/core/renderer/render_element_drawer.cpp @@ -0,0 +1 @@ +#include "render_element_drawer.h" diff --git a/src/core/renderer/render_element_drawer.h b/src/core/renderer/render_element_drawer.h new file mode 100644 index 0000000..efa849b --- /dev/null +++ b/src/core/renderer/render_element_drawer.h @@ -0,0 +1,22 @@ +#pragma once +#include "Eigen/Eigen" + +namespace mirage { + struct rect_round { + float left_top_px; + float right_top_px; + float left_bottom_px; + float right_bottom_px; + }; + enum class draw_effect { + none, + snap_to_pixel, + }; + + class element_drawer { + public: + void draw_rounded_rect(, Eigen::Vector2f in_pos, Eigen::Vector2f in_size, rect_round in_radius, Eigen::Vector4f in_color, draw_effect in_effect); + private: + + }; +} diff --git a/src/core/renderer/render_window_element_list.cpp b/src/core/renderer/render_window_element_list.cpp new file mode 100644 index 0000000..b5cf917 --- /dev/null +++ b/src/core/renderer/render_window_element_list.cpp @@ -0,0 +1 @@ +#include "render_window_element_list.h" diff --git a/src/core/renderer/render_window_element_list.h b/src/core/renderer/render_window_element_list.h new file mode 100644 index 0000000..c1b9eae --- /dev/null +++ b/src/core/renderer/render_window_element_list.h @@ -0,0 +1,8 @@ +#pragma once + +class render_window_element_list { +public: + render_window_element_list(); +private: + +}; diff --git a/src/core/renderer/rendering_common.h b/src/core/renderer/rendering_common.h new file mode 100644 index 0000000..86f77cc --- /dev/null +++ b/src/core/renderer/rendering_common.h @@ -0,0 +1,244 @@ +#pragma once +#include +#include "LLGL/LLGL.h" +#include + +namespace mirage { + using transform_type = Eigen::Projective2d; + using color_type = LLGL::ColorRGBAub; + using linear_color_type = LLGL::ColorRGBAf; + + /** + * 绘制基本类型 + */ + enum class draw_primitive { + none, + line_list, + triangle_list, + }; + + /** + * 着色器类型。注意:在着色器文件中有镜像 + * 如果在此添加类型,必须同时实现对应的着色器类型(tslate_element_ps)。参见slate_shaders.h + */ + enum class shader_type { + /** 默认着色器类型,简单的纹理查找 */ + default_ = 0, + /** 边框着色器 */ + border = 1, + /** 灰度字体着色器,使用仅alpha纹理 */ + grayscale_font = 2, + /** 颜色字体着色器,使用颜色纹理 */ + color_font = 3, + /** 线段着色器,用于绘制抗锯齿线条 */ + line_segment = 4, + /** 完全自定义材质,不假设使用方式 */ + custom = 5, + /** 后处理着色器 */ + post_process = 6, + /** 圆角矩形着色器 */ + rounded_box = 7, + }; + + /** + * 元素渲染时可应用的绘制效果 + * 注意:新增效果应以位掩码形式添加 + * 如果在此添加新类型,必须同时实现对应的着色器类型(TSlateElementPS)。参见SlateShaders.h + */ + enum class draw_effect { + /** 无效果 */ + none = 0, + /** 高级:无混合模式绘制元素 */ + no_blending = 1 << 0, + /** 高级:使用预乘alpha混合。若设置了no_blending则忽略 */ + pre_multiplied_alpha = 1 << 1, + /** 高级:不进行伽马校正 */ + no_gamma = 1 << 2, + /** 高级:将alpha值取反(1 - Alpha) */ + invert_alpha = 1 << 3, + + // ^^ 这些与ESlateBatchDrawFlag匹配 ^^ + + /** 禁用像素对齐 */ + no_pixel_snapping = 1 << 4, + /** 以禁用效果绘制元素 */ + disabled_effect = 1 << 5, + /** 高级:忽略纹理alpha通道 */ + ignore_texture_alpha = 1 << 6, + + /** 高级:反转现有伽马校正 */ + reverse_gamma = 1 << 7 + }; + + enum class line_join_type { + // 使用锐边(斜接)连接线段 + sharp = 0, + // 只需将线段拼接在一起 + simple = 1, + }; + + /** + * 枚举色觉缺陷类型。 + */ + enum class color_vision_deficiency { + normal_vision, // 正常视觉, + deuteranope, // 绿色盲/弱 (男性7%,女性0.4%) + protanope, // 红色盲/弱 (男性2%,女性0.01%) + tritanope, // 蓝色盲/弱 (男性0.0003%) + }; + + enum class mirage_vertex_rounding + { + disabled, + enabled + }; + + struct mirage_pixel_params { + union { + float x; + float r; + }; + union { + float y; + float g; + }; + union { + float z; + float b; + }; + union { + float w; + float a; + }; + mirage_pixel_params(float in_x, float in_y, float in_z, float in_w) : x(in_x), y(in_y), z(in_z), w(in_w) {} + mirage_pixel_params(const LLGL::ColorRGBAf& in) : r(in.r), g(in.g), b(in.b), a(in.a) {} + mirage_pixel_params(const LLGL::Offset2D& in) : x(in.x), y(in.y), z(0), w(0) {} + mirage_pixel_params(const LLGL::Extent2D& in) : x(in.width), y(in.height), z(0), w(0) {} + mirage_pixel_params(const LLGL::Offset3D& in) : x(in.x), y(in.y), z(in.z), w(0) {} + mirage_pixel_params(const LLGL::Extent3D& in) : x(in.width), y(in.height), z(in.depth), w(0) {} + mirage_pixel_params(const Eigen::Vector2f& in) : x(in.x()), y(in.y()), z(0), w(0) {} + mirage_pixel_params(const Eigen::Vector3f& in) : x(in.x()), y(in.y()), z(in.z()), w(0) {} + mirage_pixel_params(const Eigen::Vector4f& in) : x(in.x()), y(in.y()), z(in.z()), w(in.w()) {} + + bool operator==(const mirage_pixel_params& in_other) const { + return x == in_other.x && y == in_other.y && z == in_other.z && w == in_other.w; + } + }; + + struct mirage_shader_params { + mirage_pixel_params pixel_params; + mirage_pixel_params pixel_params2; + mirage_pixel_params pixel_params3; + + bool operator==(const mirage_shader_params& in_other) const { + return pixel_params == in_other.pixel_params && pixel_params2 == in_other.pixel_params2 && pixel_params3 == in_other.pixel_params3; + } + }; + + struct mirage_vertex { + // 纹理坐标 xy zw + float tex_coords[4]; + // 纹理坐标用作自定义纹理的材质的传递 + Eigen::Vector2f material_tex_coords; + // 顶点在窗口中的位置 + Eigen::Vector2f position; + // 顶点颜色 + color_type color; + // 次顶点颜色 一般用于轮廓 + color_type secondary_color; + // 元素的局部大小 + uint16_t pixel_size[2]; + + public: + template + static mirage_vertex make(const transform_type& in_render_transform, const Eigen::Vector2f& in_local_position, const Eigen::Vector2f& in_tex_coord, const Eigen::Vector2f& in_tex_coord2, const color_type& in_color, const color_type& in_secondary_color = {}) { + mirage_vertex vertex{}; + vertex.set_tex_coords(Eigen::Vector4f{in_tex_coord, in_tex_coord2}); + vertex.init_common(in_render_transform, in_local_position, in_color, in_secondary_color); + + return vertex; + } + + template + static mirage_vertex make(const transform_type& in_render_transform, const Eigen::Vector2f& in_local_position, const Eigen::Vector2f& in_tex_coord, const color_type& in_color, const color_type& in_secondary_color = {}) { + mirage_vertex vertex{}; + vertex.set_tex_coords(in_tex_coord); + vertex.init_common(in_render_transform, in_local_position, in_color, in_secondary_color); + + return vertex; + } + + + template + static mirage_vertex make(const transform_type& in_render_transform, const Eigen::Vector2f& in_local_position, const Eigen::Vector4f& in_tex_coord, const color_type& in_color, const color_type& in_secondary_color = {}) { + mirage_vertex vertex{}; + vertex.set_tex_coords(in_tex_coord); + vertex.init_common(in_render_transform, in_local_position, in_color, in_secondary_color); + + return vertex; + } + + template + static mirage_vertex make(const transform_type& in_render_transform, const Eigen::Vector2f& in_local_position, const Eigen::Vector2f& in_local_size, float in_scale, const Eigen::Vector4f& in_tex_coord, const color_type& in_color, const color_type& in_secondary_color = {}) { + mirage_vertex vertex{}; + vertex.set_tex_coords(in_tex_coord); + + vertex.material_tex_coords = in_local_position.array() / in_local_size.array(); + vertex.init_common(in_render_transform, in_local_position, in_color, in_secondary_color); + + const Eigen::Vector2i temp_pixel_size = in_local_size * in_scale; + vertex.pixel_size[0] = static_cast(temp_pixel_size.x()); + vertex.pixel_size[1] = static_cast(temp_pixel_size.y()); + return vertex; + } + + static mirage_vertex make(const transform_type& in_render_transform, const Eigen::Vector2f& in_local_position, const Eigen::Vector2f& in_tex_coord, const Eigen::Vector2f& in_tex_coord2, const color_type& in_color, const color_type& in_secondary_color = {}, mirage_vertex_rounding in_rounding = mirage_vertex_rounding::disabled) { + return in_rounding == mirage_vertex_rounding::enabled + ? make(in_render_transform, in_local_position, in_tex_coord, in_tex_coord2, in_color, in_secondary_color) + : make(in_render_transform, in_local_position, in_tex_coord,in_tex_coord2, in_color, in_secondary_color); + } + static mirage_vertex make(const transform_type& in_render_transform, const Eigen::Vector2f& in_local_position, const Eigen::Vector2f& in_tex_coord, const color_type& in_color, const color_type& in_secondary_color = {}, mirage_vertex_rounding in_rounding = mirage_vertex_rounding::disabled) { + return in_rounding == mirage_vertex_rounding::enabled + ? make(in_render_transform, in_local_position, in_tex_coord, in_color, in_secondary_color) + : make(in_render_transform, in_local_position, in_tex_coord, in_color, in_secondary_color); + } + static mirage_vertex make(const transform_type& in_render_transform, const Eigen::Vector2f& in_local_position, const Eigen::Vector4f& in_tex_coord, const color_type& in_color, const color_type& in_secondary_color = {}, mirage_vertex_rounding in_rounding = mirage_vertex_rounding::disabled) { + return in_rounding == mirage_vertex_rounding::enabled + ? make(in_render_transform, in_local_position, in_tex_coord, in_color, in_secondary_color) + : make(in_render_transform, in_local_position, in_tex_coord, in_color, in_secondary_color); + } + static mirage_vertex make(const transform_type& in_render_transform, const Eigen::Vector2f& in_local_position, const Eigen::Vector2f& in_local_size, float in_scale, const Eigen::Vector4f& in_tex_coord, const color_type& in_color, const color_type& in_secondary_color = {}, + mirage_vertex_rounding in_rounding = mirage_vertex_rounding::disabled) { + return in_rounding == mirage_vertex_rounding::enabled + ? make(in_render_transform, in_local_position, in_local_size, in_scale, in_tex_coord, in_color, in_secondary_color) + : make(in_render_transform, in_local_position, in_local_size, in_scale, in_tex_coord, in_color, in_secondary_color); + } + + void set_tex_coords(const Eigen::Vector4f& in_coords) { + tex_coords[0] = in_coords.x(); + tex_coords[1] = in_coords.y(); + tex_coords[2] = in_coords.z(); + tex_coords[3] = in_coords.w(); + } + void set_tex_coords(const Eigen::Vector2f& in_coords) { + tex_coords[0] = in_coords.x(); + tex_coords[1] = in_coords.y(); + tex_coords[2] = 1.f; + tex_coords[3] = 1.f; + } + + void set_position(const Eigen::Vector2f& in_position) { + position = in_position; + } + private: + template + void init_common(const transform_type& in_render_transform, const Eigen::Vector2f& in_local_position, const color_type& in_color, const color_type& in_secondary_color) { + position = in_render_transform * in_local_position; + if constexpr (Rounding == mirage_vertex_rounding::enabled) { + position = position.array().round().matrix(); + } + color = in_color; + secondary_color = in_secondary_color; + } + }; +} \ No newline at end of file diff --git a/src/core/shaders/aorii_rounded_rect.slang b/src/core/shaders/aorii_rounded_rect.slang index 8f49ebc..575ad55 100644 --- a/src/core/shaders/aorii_rounded_rect.slang +++ b/src/core/shaders/aorii_rounded_rect.slang @@ -3,15 +3,15 @@ cbuffer ParamBuffer : register(b0) { matrix transform; - float2 size; // 矩形大小 像素单位 - float2 pos; // 矩形位置 像素单位 - float4 radius; // 四角圆角像素单位 左上 右上 左下 右下 }; struct PSInput { float4 position : SV_POSITION; // 裁剪空间坐标 float2 uv : TEXCOORD0; // 纹理坐标 float4 color : COLOR; // 颜色 + + float2 size : TEXCOORD1; // 矩形大小 像素单位 + float4 radius : TEXCOORD3; // 四角圆角像素单位 左上 右上 左下 右下 }; [shader("vertex")] @@ -21,10 +21,12 @@ PSInput vertex_main(VSInput input) output.position = mul(float4(input.position, 0.0, 1.0), transform); output.uv = input.uv; output.color = input.color; + output.size = input.param_a.xy; + output.radius = input.param_b; return output; } -float distance_from_rect_uv(float2 p, float corner_radius) { +float distance_from_rect_uv(float2 p, float2 size, float corner_radius) { corner_radius *= 2; float2 corner_radius_uv = corner_radius / size; float2 inner_rect = float2(1) - corner_radius_uv; // 圆心 @@ -41,8 +43,8 @@ float4 pixel_main(PSInput input) : SV_Target // 象限 int2 quadrant = sign(p); int idx = (quadrant.x > 0 ? 1 : 0) + (quadrant.y > 0 ? 2 : 0); - float r = radius[idx]; - float d = distance_from_rect_uv(p, r); + float r = input.radius[idx]; + float d = distance_from_rect_uv(p, input.size, r); float edge_width = fwidth(d); // 根据dd计算抗锯齿