diff --git a/src/render/push_constant_traits.h b/src/render/push_constant_traits.h index 57cc87f..d6c9b4c 100644 --- a/src/render/push_constant_traits.h +++ b/src/render/push_constant_traits.h @@ -86,8 +86,8 @@ namespace mirage { */ template constexpr bool validate_shader_spec_push_constants() { - if constexpr (requires { typename ShaderSpec::push_constant_effect_type; }) { - using EffectType = typename ShaderSpec::push_constant_effect_type; + if constexpr (requires { typename ShaderSpec::effect_type; }) { + using EffectType = typename ShaderSpec::effect_type; // 验证效果类型的大小 (Layer 3 最大 16 字节) constexpr bool size_valid = sizeof(EffectType) <= PUSH_CONSTANT_EFFECT_MAX_SIZE; return size_valid; diff --git a/src/ui/widgets/custom_shader/custom_shader_widget.h b/src/ui/widgets/custom_shader/custom_shader_widget.h deleted file mode 100644 index 9310d25..0000000 --- a/src/ui/widgets/custom_shader/custom_shader_widget.h +++ /dev/null @@ -1,220 +0,0 @@ -#pragma once - -#include "ui/widgets/custom_shader/custom_shader_widget_base.h" -#include "render/vertex_types.h" -#include - -namespace mirage { - /// @brief 自定义着色器控件模板基类 - /// - /// @tparam ParamsT 着色器参数结构体类型(由着色器工具自动生成) - /// @tparam VertexT 顶点类型(默认使用 ui_vertex) - /// - /// 用户通过继承此类创建自定义着色器控件。ParamsT 类型应由着色器工具 - /// 从 GLSL UBO 定义自动生成,确保 C++ 和着色器之间的类型安全。 - /// - /// 支持三种渲染模式: - /// - **程序化渲染**:使用着色器生成内容(无子控件,无源纹理) - /// - **后处理模式**:对子控件渲染结果或指定纹理应用着色器效果 - /// - **自定义几何模式**:使用自定义顶点着色器和顶点缓冲 - /// - /// @example - /// ```cpp - /// // 使用工具生成的类型 - /// #include "gen/shaders/gradient.h" - /// - /// class gradient_widget : public custom_shader_widget { - /// public: - /// gradient_widget() { - /// params().start_color = {1, 0, 0, 1}; - /// params().end_color = {0, 0, 1, 1}; - /// } - /// - /// auto& colors(const vec4f_t& start, const vec4f_t& end) { - /// params().start_color = start; - /// params().end_color = end; - /// mark_params_dirty(); - /// return *this; - /// } - /// - /// protected: - /// auto get_shader_id() const noexcept -> uint32_t override { - /// return hash_compile_time("gradient_widget"); - /// } - /// - /// auto get_fragment_shader_spirv() const -> std::span override { - /// return shaders::gradient_frag_spirv; - /// } - /// - /// auto get_bindings() const -> std::span override { - /// return shaders::gradient_bindings; - /// } - /// - /// auto get_render_mode() const noexcept -> custom_shader_render_mode override { - /// return custom_shader_render_mode::procedural; - /// } - /// }; - /// ``` - template - class custom_shader_widget : public custom_shader_widget_base { - public: - using params_type = ParamsT; - using vertex_type = VertexT; - - // 静态断言:确保 ParamsT 满足要求 - static_assert(std::is_standard_layout_v, - "ParamsT must be standard layout for GPU compatibility"); - static_assert(alignof(ParamsT) <= 16, - "ParamsT alignment must not exceed 16 bytes"); - - custom_shader_widget() = default; - ~custom_shader_widget() override = default; - - // ======================================================================== - // 参数访问 - // ======================================================================== - - /// @brief 获取参数的可变引用 - /// @note 修改后需要调用 mark_params_dirty() - [[nodiscard]] auto params() noexcept -> ParamsT& { return params_; } - - /// @brief 获取参数的只读引用 - [[nodiscard]] auto params() const noexcept -> const ParamsT& { return params_; } - - /// @brief 标记参数已修改 - void mark_params_dirty() { - params_dirty_ = true; - mark_render_dirty_internal(); - } - - protected: - // ======================================================================== - // 实现基类纯虚函数 - // ======================================================================== - - [[nodiscard]] auto get_params_data() const - -> std::pair override { - return {¶ms_, sizeof(ParamsT)}; - } - - [[nodiscard]] auto is_params_dirty() const noexcept -> bool override { - return params_dirty_; - } - - void clear_params_dirty() override { - params_dirty_ = false; - } - - // ======================================================================== - // 自定义顶点支持 - // ======================================================================== - - /// @brief 标记顶点数据已修改 - void mark_vertices_dirty() { - vertices_dirty_ = true; - mark_render_dirty_internal(); - } - - [[nodiscard]] auto is_vertices_dirty() const noexcept -> bool override { - return vertices_dirty_; - } - - void clear_vertices_dirty() override { - vertices_dirty_ = false; - } - - // ======================================================================== - // 顶点数据管理(仅 custom_geometry 模式使用) - // ======================================================================== - - /// @brief 获取顶点数据 - [[nodiscard]] auto get_vertices() const noexcept -> const std::vector& { - return vertices_; - } - - /// @brief 获取顶点数据(可修改) - [[nodiscard]] auto get_vertices() noexcept -> std::vector& { - return vertices_; - } - - /// @brief 设置顶点数据 - void set_vertices(std::vector vertices) { - vertices_ = std::move(vertices); - mark_vertices_dirty(); - } - - /// @brief 获取索引数据 - [[nodiscard]] auto get_indices() const noexcept -> const std::vector& { - return indices_; - } - - /// @brief 设置索引数据 - void set_indices(std::vector indices) { - indices_ = std::move(indices); - mark_vertices_dirty(); - } - - /// @brief 获取顶点缓冲配置 - [[nodiscard]] auto get_vertex_buffer_config() const - -> std::optional override { - if (vertices_.empty()) { - return std::nullopt; - } - - return custom_vertex_buffer_config{ - .data = vertices_.data(), - .data_size = vertices_.size() * sizeof(VertexT), - .vertex_count = vertices_.size(), - .binding = get_vertex_binding_description(), - .attributes = get_vertex_attribute_descriptions() - }; - } - - /// @brief 获取索引缓冲配置 - [[nodiscard]] auto get_index_buffer_config() const - -> std::optional override { - if (indices_.empty()) { - return std::nullopt; - } - - return index_buffer_config{ - .data = indices_.data(), - .index_count = indices_.size() - }; - } - - /// @brief 获取顶点绑定描述(可重写) - [[nodiscard]] virtual auto get_vertex_binding_description() const - -> vk::VertexInputBindingDescription { - if constexpr (requires { VertexT::get_binding_description(); }) { - return VertexT::get_binding_description(); - } - else { - return vk::VertexInputBindingDescription{ - 0, sizeof(VertexT), vk::VertexInputRate::eVertex - }; - } - } - - /// @brief 获取顶点属性描述(可重写) - [[nodiscard]] virtual auto get_vertex_attribute_descriptions() const - -> std::vector { - if constexpr (requires { VertexT::get_attribute_descriptions(); }) { - auto attrs = VertexT::get_attribute_descriptions(); - return std::vector( - attrs.begin(), attrs.end()); - } - else { - return {}; - } - } - - private: - ParamsT params_{}; - bool params_dirty_ = true; - bool vertices_dirty_ = false; - - std::vector vertices_; - std::vector indices_; - }; -} // namespace mirage diff --git a/src/ui/widgets/custom_shader/effects/blur_widget.h b/src/ui/widgets/custom_shader/effects/blur_widget.h index 8e0b8bf..194d0f1 100644 --- a/src/ui/widgets/custom_shader/effects/blur_widget.h +++ b/src/ui/widgets/custom_shader/effects/blur_widget.h @@ -1,6 +1,6 @@ #pragma once -#include "ui/widgets/custom_shader/shader_spec_widget.h" +#include "ui/widgets/custom_shader/post_process/post_process_shader_widget.h" #include "blur_vert_frag.h" namespace mirage { @@ -25,7 +25,7 @@ namespace mirage { /// blur->set_samples(32); /// blur->set_direction(glm::vec2{1.0f, 0.0f}); // 水平模糊 /// @endcode -class blur_widget : public shader_spec_widget> { +class blur_widget : public post_process_shader_widget> { public: blur_widget() { // Uniform Buffer 参数默认值 @@ -33,8 +33,8 @@ public: params().samples = 16; params().direction = vec2f_t{1.0f, 0.0f}; - // Push Constants 效果参数默认值 - push_constant_effect().intensity = 1.0f; + // 效果参数默认值 + effect().intensity = 1.0f; } ~blur_widget() override = default; @@ -104,35 +104,25 @@ public: } // ======================================================================== - // Push Constants 效果参数接口 + // 效果参数接口 // ======================================================================== /// @brief 设置效果强度 /// @param intensity 强度值 [0.0, 1.0] /// @return *this auto& set_intensity(float intensity) { - push_constant_effect().intensity = std::clamp(intensity, 0.0f, 1.0f); - mark_push_constant_effect_dirty(); + effect().intensity = std::clamp(intensity, 0.0f, 1.0f); + mark_effect_dirty(); return *this; } /// @brief 获取效果强度 /// @return 强度值 [0.0, 1.0] [[nodiscard]] auto get_intensity() const noexcept -> float { - return push_constant_effect().intensity; + return effect().intensity; } - // ======================================================================== - // 基类虚函数实现 - // ======================================================================== - protected: - /// @brief 获取渲染模式 - [[nodiscard]] auto get_render_mode() const noexcept - -> custom_shader_render_mode override { - return custom_shader_render_mode::post_process; - } - /// @brief 更新描述符绑定 - 自定义采样器配置 /// /// 重写此方法以使用自定义采样器配置。 diff --git a/src/ui/widgets/custom_shader/effects/chromatic_aberration_widget.h b/src/ui/widgets/custom_shader/effects/chromatic_aberration_widget.h index e3b07a2..31af2e3 100644 --- a/src/ui/widgets/custom_shader/effects/chromatic_aberration_widget.h +++ b/src/ui/widgets/custom_shader/effects/chromatic_aberration_widget.h @@ -1,6 +1,6 @@ #pragma once -#include "ui/widgets/custom_shader/shader_spec_widget.h" +#include "ui/widgets/custom_shader/post_process/post_process_shader_widget.h" #include "chromatic_aberration_vert_frag.h" namespace mirage { @@ -20,14 +20,14 @@ namespace mirage { /// chromatic_aberration->set_size({200, 100}); /// chromatic_aberration->set_offset(vec2f_t{0.02f, 0.0f}); /// @endcode -class chromatic_aberration_widget : public shader_spec_widget> { +class chromatic_aberration_widget : public post_process_shader_widget> { public: chromatic_aberration_widget() { // Uniform Buffer 参数默认值 params().offset = vec2f_t{0.02f, 0.0f}; - // Push Constants 效果参数默认值 - push_constant_effect().intensity = 1.0f; + // 效果参数默认值 + effect().intensity = 1.0f; } ~chromatic_aberration_widget() override = default; @@ -81,33 +81,22 @@ public: } // ======================================================================== - // Push Constants 效果参数接口 + // 效果参数接口 // ======================================================================== /// @brief 设置效果强度 /// @param intensity 强度值 [0.0, 1.0] /// @return *this auto& set_intensity(float intensity) { - push_constant_effect().intensity = std::clamp(intensity, 0.0f, 1.0f); - mark_push_constant_effect_dirty(); + effect().intensity = std::clamp(intensity, 0.0f, 1.0f); + mark_effect_dirty(); return *this; } /// @brief 获取效果强度 /// @return 强度值 [0.0, 1.0] [[nodiscard]] auto get_intensity() const noexcept -> float { - return push_constant_effect().intensity; - } - - // ======================================================================== - // 基类虚函数实现 - 只需重写渲染模式 - // ======================================================================== - -protected: - /// @brief 获取渲染模式 - [[nodiscard]] auto get_render_mode() const noexcept - -> custom_shader_render_mode override { - return custom_shader_render_mode::post_process; + return effect().intensity; } }; diff --git a/src/ui/widgets/custom_shader/effects/color_adjust_widget.h b/src/ui/widgets/custom_shader/effects/color_adjust_widget.h index 5988768..be3a552 100644 --- a/src/ui/widgets/custom_shader/effects/color_adjust_widget.h +++ b/src/ui/widgets/custom_shader/effects/color_adjust_widget.h @@ -1,6 +1,6 @@ #pragma once -#include "ui/widgets/custom_shader/shader_spec_widget.h" +#include "ui/widgets/custom_shader/post_process/post_process_shader_widget.h" #include "color_adjust_vert_frag.h" namespace mirage { @@ -20,7 +20,7 @@ namespace mirage { /// color_adjust->set_saturation(1.5f); /// color_adjust->set_gamma(0.8f); /// @endcode -class color_adjust_widget : public shader_spec_widget> { +class color_adjust_widget : public post_process_shader_widget> { public: color_adjust_widget() { // Uniform Buffer 参数默认值 @@ -29,8 +29,8 @@ public: params().saturation = 1.0f; params().gamma = 1.0f; - // Push Constants 效果参数默认值 - push_constant_effect().intensity = 1.0f; + // 效果参数默认值 + effect().intensity = 1.0f; } ~color_adjust_widget() override = default; @@ -99,33 +99,22 @@ public: } // ======================================================================== - // Push Constants 效果参数接口 + // 效果参数接口 // ======================================================================== /// @brief 设置效果强度 /// @param intensity 强度值 [0.0, 1.0] /// @return *this auto& set_intensity(float intensity) { - push_constant_effect().intensity = std::clamp(intensity, 0.0f, 1.0f); - mark_push_constant_effect_dirty(); + effect().intensity = std::clamp(intensity, 0.0f, 1.0f); + mark_effect_dirty(); return *this; } /// @brief 获取效果强度 /// @return 强度值 [0.0, 1.0] [[nodiscard]] auto get_intensity() const noexcept -> float { - return push_constant_effect().intensity; - } - - // ======================================================================== - // 基类虚函数实现 - 只需重写渲染模式 - // ======================================================================== - -protected: - /// @brief 获取渲染模式 - [[nodiscard]] auto get_render_mode() const noexcept - -> custom_shader_render_mode override { - return custom_shader_render_mode::post_process; + return effect().intensity; } }; diff --git a/src/ui/widgets/custom_shader/effects/color_tint_widget.h b/src/ui/widgets/custom_shader/effects/color_tint_widget.h index ead3e77..55aff2b 100644 --- a/src/ui/widgets/custom_shader/effects/color_tint_widget.h +++ b/src/ui/widgets/custom_shader/effects/color_tint_widget.h @@ -1,6 +1,6 @@ #pragma once -#include "ui/widgets/custom_shader/shader_spec_widget.h" +#include "ui/widgets/custom_shader/post_process/post_process_shader_widget.h" #include "color_tint_vert_frag.h" namespace mirage { @@ -26,7 +26,7 @@ namespace mirage { /// color_tint->set_tint_color(glm::vec4{1.0f, 0.5f, 0.0f, 0.7f}); // 橙色,强度0.7 /// color_tint->set_blend_mode(2); // Multiply 模式 /// @endcode -class color_tint_widget : public shader_spec_widget> { +class color_tint_widget : public post_process_shader_widget> { public: color_tint_widget() = default; ~color_tint_widget() override = default; @@ -79,17 +79,6 @@ public: [[nodiscard]] auto get_blend_mode() const noexcept -> int32_t { return params().blend_mode; } - - // ======================================================================== - // 基类虚函数实现 - 只需重写渲染模式 - // ======================================================================== - -protected: - /// @brief 获取渲染模式 - [[nodiscard]] auto get_render_mode() const noexcept - -> custom_shader_render_mode override { - return custom_shader_render_mode::post_process; - } }; } // namespace mirage \ No newline at end of file diff --git a/src/ui/widgets/custom_shader/effects/noise_widget.h b/src/ui/widgets/custom_shader/effects/noise_widget.h index 9227afa..dcaff5f 100644 --- a/src/ui/widgets/custom_shader/effects/noise_widget.h +++ b/src/ui/widgets/custom_shader/effects/noise_widget.h @@ -1,6 +1,6 @@ #pragma once -#include "ui/widgets/custom_shader/shader_spec_widget.h" +#include "ui/widgets/custom_shader/post_process/post_process_shader_widget.h" #include "noise_vert_frag.h" namespace mirage { @@ -32,7 +32,7 @@ namespace mirage { /// animated_noise->set_grain_size(2.0f); /// animated_noise->set_animated(true); // 启用动画 /// @endcode -class noise_widget : public shader_spec_widget> { +class noise_widget : public post_process_shader_widget> { public: noise_widget() = default; ~noise_widget() override = default; @@ -80,17 +80,7 @@ public: return *this; } - // ======================================================================== - // 基类虚函数实现 - 只需重写渲染模式 - // ======================================================================== - protected: - /// @brief 获取渲染模式 - [[nodiscard]] auto get_render_mode() const noexcept - -> custom_shader_render_mode override { - return custom_shader_render_mode::post_process; - } - /// @brief 检查是否需要动画更新 /// @return 当 animated 参数为 true 时返回 true [[nodiscard]] auto is_animated() const noexcept -> bool override { diff --git a/src/ui/widgets/custom_shader/effects/vignette_widget.h b/src/ui/widgets/custom_shader/effects/vignette_widget.h index a2e82bc..c7e112c 100644 --- a/src/ui/widgets/custom_shader/effects/vignette_widget.h +++ b/src/ui/widgets/custom_shader/effects/vignette_widget.h @@ -1,6 +1,6 @@ #pragma once -#include "ui/widgets/custom_shader/shader_spec_widget.h" +#include "ui/widgets/custom_shader/post_process/post_process_shader_widget.h" #include "vignette_vert_frag.h" namespace mirage { @@ -23,7 +23,7 @@ namespace mirage { /// vignette->set_softness(0.3f); /// vignette->set_tint_color(glm::vec4{0.0f, 0.0f, 0.0f, 1.0f}); // 黑色暗角 /// @endcode - class vignette_widget : public shader_spec_widget> { + class vignette_widget : public post_process_shader_widget> { public: vignette_widget() = default; ~vignette_widget() override = default; @@ -76,16 +76,5 @@ namespace mirage { [[nodiscard]] auto get_tint_color() const noexcept { return params().tint_color; } - - // ======================================================================== - // 基类虚函数实现 - 只需重写渲染模式 - // ======================================================================== - - protected: - /// @brief 获取渲染模式 - [[nodiscard]] auto get_render_mode() const noexcept - -> custom_shader_render_mode override { - return custom_shader_render_mode::post_process; - } }; } // namespace mirage diff --git a/src/ui/widgets/custom_shader/examples/glitch_widget.h b/src/ui/widgets/custom_shader/examples/glitch_widget.h index e5d6547..3001a42 100644 --- a/src/ui/widgets/custom_shader/examples/glitch_widget.h +++ b/src/ui/widgets/custom_shader/examples/glitch_widget.h @@ -1,170 +1,91 @@ #pragma once -#include "ui/widgets/custom_shader/custom_shader_widget.h" -#include +#include "ui/widgets/custom_shader/post_process/post_process_shader_widget.h" +#include "glitch_effect_vert_frag.h" -namespace mirage::ui { +namespace mirage { + /// @brief 故障效果控件 + /// + /// 使用后处理模式,对子控件或源纹理应用故障效果。 + /// 支持 RGB 分离、扫描线和噪声效果,可用于动画. + /// + /// @par 使用示例 + /// @code + /// // 创建故障效果控件 + /// auto glitch = create_widget(); + /// glitch->set_size({200, 100}); + /// glitch->set_intensity(0.5f); + /// glitch->set_scan_line_frequency(100.0f); + /// glitch->set_noise_amount(0.1f); + /// @endcode + class glitch_widget : public post_process_shader_widget> { + public: + glitch_widget() { + // 设置默认效果参数(Layer 3 Push Constants) + // effect_params.x = intensity, y = scan_line_frequency, z = noise_amount + effect().effect_params.x() = 0.5f; // intensity + effect().effect_params.y() = 100.0f; // scan_line_frequency + effect().effect_params.z() = 0.1f; // noise_amount + } -/// @brief 故障效果控件 -/// -/// 使用后处理模式,对子控件或源纹理应用故障效果。 -/// 支持 RGB 分离、扫描线和噪声效果,可用于动画. -/// -/// @par 使用示例 -/// @code -/// // 创建故障效果控件 -/// auto glitch = create_widget(); -/// glitch->set_size({200, 100}); -/// glitch->set_intensity(0.5f); -/// glitch->set_scan_line_frequency(100.0f); -/// glitch->set_noise_amount(0.1f); -/// @endcode -class glitch_widget : public custom_shader_widget { -public: - /// @brief 故障效果参数结构体 - /// @note 对应 shader 中的 GlitchParams UBO - struct GlitchParams { - float time{0.0f}; ///< 时间(秒) - float intensity{0.5f}; ///< 故障强度 [0, 1] - float scan_line_freq{100.0f}; ///< 扫描线频率 - float noise_amount{0.1f}; ///< 噪声量 - }; + ~glitch_widget() override = default; - glitch_widget() = default; - ~glitch_widget() override = default; + // ======================================================================== + // 公共接口 + // ======================================================================== - // ======================================================================== - // 公共接口 - // ======================================================================== + /// @brief 设置故障强度 + /// @param intensity 强度 [0, 1] + /// @return *this + auto& set_intensity(float intensity) { + effect().effect_params.x() = std::clamp(intensity, 0.0f, 1.0f); + mark_effect_dirty(); + return *this; + } - /// @brief 设置故障强度 - /// @param intensity 强度 [0, 1] - /// @return *this - auto& set_intensity(float intensity) { - params().intensity = glm::clamp(intensity, 0.0f, 1.0f); - mark_params_dirty(); - return *this; - } + /// @brief 获取故障强度 + /// @return 强度 [0, 1] + [[nodiscard]] auto get_intensity() const noexcept -> float { + return effect().effect_params.x(); + } - /// @brief 获取故障强度 - /// @return 强度 [0, 1] - [[nodiscard]] auto get_intensity() const noexcept -> float { - return params().intensity; - } + /// @brief 设置扫描线频率 + /// @param freq 频率 + /// @return *this + auto& set_scan_line_frequency(float freq) { + effect().effect_params.y() = freq; + mark_effect_dirty(); + return *this; + } - /// @brief 设置扫描线频率 - /// @param freq 频率 - /// @return *this - auto& set_scan_line_frequency(float freq) { - params().scan_line_freq = freq; - mark_params_dirty(); - return *this; - } + /// @brief 获取扫描线频率 + /// @return 频率 + [[nodiscard]] auto get_scan_line_frequency() const noexcept -> float { + return effect().effect_params.y(); + } - /// @brief 获取扫描线频率 - /// @return 频率 - [[nodiscard]] auto get_scan_line_frequency() const noexcept -> float { - return params().scan_line_freq; - } + /// @brief 设置噪声量 + /// @param amount 噪声量 + /// @return *this + auto& set_noise_amount(float amount) { + effect().effect_params.z() = amount; + mark_effect_dirty(); + return *this; + } - /// @brief 设置噪声量 - /// @param amount 噪声量 - /// @return *this - auto& set_noise_amount(float amount) { - params().noise_amount = amount; - mark_params_dirty(); - return *this; - } + /// @brief 获取噪声量 + /// @return 噪声量 + [[nodiscard]] auto get_noise_amount() const noexcept -> float { + return effect().effect_params.z(); + } - /// @brief 获取噪声量 - /// @return 噪声量 - [[nodiscard]] auto get_noise_amount() const noexcept -> float { - return params().noise_amount; - } + // ======================================================================== + // 动画控制 + // ======================================================================== - /// @brief 设置时间(用于手动控制动画) - /// @param time 时间(秒) - /// @return *this - auto& set_time(float time) { - params().time = time; - mark_params_dirty(); - return *this; - } - - /// @brief 获取当前时间 - /// @return 时间(秒) - [[nodiscard]] auto get_time() const noexcept -> float { - return params().time; - } - - // ======================================================================== - // 动画控制 - // ======================================================================== - - /// @brief 标记为动画控件(启用自动时间更新) - [[nodiscard]] auto is_animated() const noexcept -> bool override { - return true; - } - - /// @brief 更新时间(每帧调用) - void tick(float dt) override { - params().time += dt; - mark_params_dirty(); - } - - // ======================================================================== - // 基类虚函数实现 - // ======================================================================== - -protected: - /// @brief 获取着色器唯一标识符 - [[nodiscard]] auto get_shader_id() const noexcept -> uint32_t override { - return hash_compile_time("glitch_widget"); - } - - /// @brief 获取片段着色器 SPIR-V - /// @note TODO: 使用着色器工具链预编译的 SPIR-V - [[nodiscard]] auto get_fragment_shader_spirv() const - -> std::span override { - // TODO: 返回预编译的 glitch_effect.frag.glsl SPIR-V - // 从生成的着色器头文件获取: - // return shaders::glitch_effect_frag_spirv; - return {}; - } - - /// @brief 获取描述符绑定信息 - [[nodiscard]] auto get_bindings() const - -> std::span override { - static constexpr shader_binding_info bindings[] = { - { - .binding = 0, - .type = vk::DescriptorType::eUniformBuffer, - .count = 1, - .stage = vk::ShaderStageFlagBits::eFragment - }, - { - .binding = 1, - .type = vk::DescriptorType::eCombinedImageSampler, - .count = 1, - .stage = vk::ShaderStageFlagBits::eFragment - } - }; - return bindings; - } - - /// @brief 获取渲染模式 - [[nodiscard]] auto get_render_mode() const noexcept - -> custom_shader_render_mode override { - return custom_shader_render_mode::post_process; - } - - /// @brief 获取顶点着色器 SPIR-V - /// @note 使用默认的程序化四边形顶点着色器 - [[nodiscard]] auto get_vertex_shader_spirv() const - -> std::span override { - // 返回 nullopt 使用默认顶点着色器 - return {}; - } -}; - -} // namespace mirage::ui \ No newline at end of file + /// @brief 标记为动画控件(启用自动时间更新) + [[nodiscard]] auto is_animated() const noexcept -> bool override { + return true; + } + }; +} // namespace mirage diff --git a/src/ui/widgets/custom_shader/examples/gradient_widget.h b/src/ui/widgets/custom_shader/examples/gradient_widget.h index dc9114f..3a3be0c 100644 --- a/src/ui/widgets/custom_shader/examples/gradient_widget.h +++ b/src/ui/widgets/custom_shader/examples/gradient_widget.h @@ -1,166 +1,146 @@ #pragma once -#include "ui/widgets/custom_shader/shader_spec_widget.h" +#include "ui/widgets/custom_shader/procedural/procedural_shader_widget.h" #include "gradient_vert_frag.h" #include namespace mirage { + /// @brief 渐变类型枚举 + enum class gradient_type : uint32_t { + horizontal = 0, ///< 水平渐变 + vertical = 1, ///< 垂直渐变 + diagonal = 2, ///< 对角线/角度渐变 + radial = 3 ///< 径向渐变 + }; -/// @brief 渐变类型枚举 -enum class gradient_type : uint32_t { - horizontal = 0, ///< 水平渐变 - vertical = 1, ///< 垂直渐变 - diagonal = 2, ///< 对角线/角度渐变 - radial = 3 ///< 径向渐变 -}; + /// @brief 渐变背景控件 + /// + /// 使用程序化渲染模式,通过着色器生成线性渐变背景。 + /// 支持自定义渐变颜色、方向和角度。 + /// + /// 渐变参数通过 Push Constants 传递: + /// - v_color (通过顶点着色器): 起始颜色 + /// - base_color: 结束颜色 + /// - effect_params.x: 渐变类型 (0=horizontal, 1=vertical, 2=diagonal, 3=radial) + /// - effect_params.y: 渐变角度(弧度),用于 diagonal 模式 + /// + /// @par 使用示例 + /// @code + /// // 创建渐变控件 + /// auto gradient = create_widget(); + /// gradient->set_size({200, 100}); + /// gradient->set_colors( + /// vec4f_t{1.0f, 0.0f, 0.0f, 1.0f}, // 红色起始 + /// vec4f_t{0.0f, 0.0f, 1.0f, 1.0f} // 蓝色结束 + /// ); + /// gradient->set_gradient_type(gradient_type::diagonal); + /// gradient->set_angle(45.0f); // 45度角 + /// @endcode + class gradient_widget : public procedural_shader_widget> { + public: + gradient_widget() { + // 设置默认颜色 + set_start_color({1.0f, 0.0f, 0.0f, 1.0f}); // 红色 + set_end_color({0.0f, 0.0f, 1.0f, 1.0f}); // 蓝色 + set_gradient_type(gradient_type::horizontal); + set_angle(0.0f); + } -/// @brief 渐变背景控件 -/// -/// 使用程序化渲染模式,通过着色器生成线性渐变背景。 -/// 支持自定义渐变颜色、方向和角度。 -/// -/// 渐变参数通过 Push Constants 传递: -/// - v_color (通过顶点着色器): 起始颜色 -/// - base_color: 结束颜色 -/// - effect_params.x: 渐变类型 (0=horizontal, 1=vertical, 2=diagonal, 3=radial) -/// - effect_params.y: 渐变角度(弧度),用于 diagonal 模式 -/// -/// @par 使用示例 -/// @code -/// // 创建渐变控件 -/// auto gradient = create_widget(); -/// gradient->set_size({200, 100}); -/// gradient->set_colors( -/// vec4f_t{1.0f, 0.0f, 0.0f, 1.0f}, // 红色起始 -/// vec4f_t{0.0f, 0.0f, 1.0f, 1.0f} // 蓝色结束 -/// ); -/// gradient->set_gradient_type(gradient_type::diagonal); -/// gradient->set_angle(45.0f); // 45度角 -/// @endcode -class gradient_widget : public shader_spec_widget> { -public: - gradient_widget() { - // 设置默认颜色 - set_start_color({1.0f, 0.0f, 0.0f, 1.0f}); // 红色 - set_end_color({0.0f, 0.0f, 1.0f, 1.0f}); // 蓝色 - set_gradient_type(gradient_type::horizontal); - set_angle(0.0f); - } - ~gradient_widget() override = default; + ~gradient_widget() override = default; - // ======================================================================== - // 公共接口 - // ======================================================================== + // ======================================================================== + // 公共接口 + // ======================================================================== - /// @brief 设置渐变颜色 - /// @param start 起始颜色 - /// @param end 结束颜色 - /// @return *this - auto& set_colors(const vec4f_t& start, const vec4f_t& end) { - set_start_color(start); - set_end_color(end); - return *this; - } + /// @brief 设置渐变颜色 + /// @param start 起始颜色 + /// @param end 结束颜色 + /// @return *this + auto& set_colors(const vec4f_t& start, const vec4f_t& end) { + set_start_color(start); + set_end_color(end); + return *this; + } - /// @brief 设置渐变颜色(使用线性 RGB) - /// @param start 起始颜色 [0-255] - /// @param end 结束颜色 [0-255] - /// @return *this - auto& set_colors_linear(const vec4f_t& start, const vec4f_t& end) { - return set_colors(start / 255.0f, end / 255.0f); - } + /// @brief 设置渐变颜色(使用线性 RGB) + /// @param start 起始颜色 [0-255] + /// @param end 结束颜色 [0-255] + /// @return *this + auto& set_colors_linear(const vec4f_t& start, const vec4f_t& end) { + return set_colors(start / 255.0f, end / 255.0f); + } - /// @brief 设置起始颜色 - /// @param color 起始颜色 - /// @return *this - auto& set_start_color(const vec4f_t& color) { - start_color_ = color; - mark_push_constant_effect_dirty(); - return *this; - } + /// @brief 设置起始颜色 + /// @param color 起始颜色 + /// @return *this + auto& set_start_color(const vec4f_t& color) { + start_color_ = color; + mark_effect_dirty(); + return *this; + } - /// @brief 获取起始颜色 - [[nodiscard]] auto get_start_color() const noexcept -> vec4f_t { - return start_color_; - } + /// @brief 获取起始颜色 + [[nodiscard]] auto get_start_color() const noexcept -> vec4f_t { + return start_color_; + } - /// @brief 设置结束颜色 - /// @param color 结束颜色 - /// @return *this - auto& set_end_color(const vec4f_t& color) { - push_constant_effect().base_color = color; - mark_push_constant_effect_dirty(); - return *this; - } + /// @brief 设置结束颜色 + /// @param color 结束颜色 + /// @return *this + auto& set_end_color(const vec4f_t& color) { + effect().base_color = color; + mark_effect_dirty(); + return *this; + } - /// @brief 获取结束颜色 - [[nodiscard]] auto get_end_color() const noexcept -> vec4f_t { - return push_constant_effect().base_color; - } + /// @brief 获取结束颜色 + [[nodiscard]] auto get_end_color() const noexcept -> vec4f_t { + return effect().base_color; + } - /// @brief 设置渐变类型 - /// @param type 渐变类型 - /// @return *this - auto& set_gradient_type(gradient_type type) { - push_constant_effect().effect_params.x() = static_cast(type); - mark_push_constant_effect_dirty(); - return *this; - } + /// @brief 设置渐变类型 + /// @param type 渐变类型 + /// @return *this + auto& set_gradient_type(gradient_type type) { + effect().effect_params.x() = static_cast(type); + mark_effect_dirty(); + return *this; + } - /// @brief 获取渐变类型 - [[nodiscard]] auto get_gradient_type() const noexcept -> gradient_type { - return static_cast( - static_cast(push_constant_effect().effect_params.x())); - } + /// @brief 获取渐变类型 + [[nodiscard]] auto get_gradient_type() const noexcept -> gradient_type { + return static_cast( + static_cast(effect().effect_params.x())); + } - /// @brief 设置渐变角度 - /// @param degrees 角度(度) - /// @return *this - auto& set_angle(float degrees) { - float radians = degrees * 3.14159265358979323846f / 180.0f; - push_constant_effect().effect_params.y() = radians; - mark_push_constant_effect_dirty(); - return *this; - } + /// @brief 设置渐变角度 + /// @param degrees 角度(度) + /// @return *this + auto& set_angle(float degrees) { + float radians = degrees * 3.14159265358979323846f / 180.0f; + effect().effect_params.y() = radians; + mark_effect_dirty(); + return *this; + } - /// @brief 获取渐变角度 - /// @return 角度(度) - [[nodiscard]] auto get_angle() const noexcept -> float { - return push_constant_effect().effect_params.y() * 180.0f / 3.14159265358979323846f; - } + /// @brief 获取渐变角度 + /// @return 角度(度) + [[nodiscard]] auto get_angle() const noexcept -> float { + return effect().effect_params.y() * 180.0f / 3.14159265358979323846f; + } - /// @brief 设置渐变方向(归一化向量,自动计算角度) - /// @param direction 方向向量 - /// @return *this - auto& set_direction(const vec2f_t& direction) { - float angle = std::atan2(direction.y(), direction.x()); - push_constant_effect().effect_params.y() = angle; - set_gradient_type(gradient_type::diagonal); - mark_push_constant_effect_dirty(); - return *this; - } - - // ======================================================================== - // 基类虚函数实现 - // ======================================================================== - -protected: - /// @brief 获取渲染模式 - [[nodiscard]] auto get_render_mode() const noexcept - -> custom_shader_render_mode override { - return custom_shader_render_mode::procedural; - } - - /// @brief 获取 Push Constants 效果参数数据 - /// @note 只返回 effect_params 部分(16字节),对应 Layer 3 - /// Layer 2 的 widget_rect 和 base_color 由渲染器自动填充 - [[nodiscard]] auto get_push_constant_effect_data() const - -> std::pair override { - return {&(push_constant_effect().effect_params), sizeof(vec4f_t)}; - } - -private: - vec4f_t start_color_{1.0f, 0.0f, 0.0f, 1.0f}; ///< 起始颜色(暂存,需要通过颜色传递机制使用) -}; + /// @brief 设置渐变方向(归一化向量,自动计算角度) + /// @param direction 方向向量 + /// @return *this + auto& set_direction(const vec2f_t& direction) { + float angle = std::atan2(direction.y(), direction.x()); + effect().effect_params.y() = angle; + set_gradient_type(gradient_type::diagonal); + mark_effect_dirty(); + return *this; + } + private: + vec4f_t start_color_{1.0f, 0.0f, 0.0f, 1.0f}; ///< 起始颜色(暂存,需要通过颜色传递机制使用) + }; } // namespace mirage diff --git a/src/ui/widgets/custom_shader/examples/wave_widget.h b/src/ui/widgets/custom_shader/examples/wave_widget.h index 5d03b73..1f0c486 100644 --- a/src/ui/widgets/custom_shader/examples/wave_widget.h +++ b/src/ui/widgets/custom_shader/examples/wave_widget.h @@ -1,167 +1,147 @@ #pragma once -#include "ui/widgets/custom_shader/shader_spec_widget.h" +#include "ui/widgets/custom_shader/procedural/procedural_shader_widget.h" #include "wave_vert_frag.h" namespace mirage { + /// @brief 波浪效果控件 + /// + /// 使用程序化渲染模式,通过正弦波生成动态颜色渐变效果。 + /// 支持动画,可用于创建流动的波浪背景。 + /// + /// 波浪参数通过 Push Constants 传递: + /// - v_color (通过顶点着色器): 主色 + /// - base_color: 次色 + /// - effect_params.x: frequency 波浪频率(推荐值: 5.0 - 20.0) + /// - effect_params.y: amplitude 波浪振幅(推荐值: 0.1 - 0.5) + /// - effect_params.z: speed 波浪速度(推荐值: 1.0 - 5.0) + /// - time: 由渲染器自动更新 + /// + /// @par 使用示例 + /// @code + /// // 创建波浪效果控件 + /// auto wave = create_widget(); + /// wave->set_size({200, 100}); + /// wave->set_colors( + /// vec4f_t{0.0f, 0.5f, 1.0f, 1.0f}, // 蓝色主色 + /// vec4f_t{0.0f, 1.0f, 0.8f, 1.0f} // 青色次色 + /// ); + /// wave->set_frequency(10.0f); + /// wave->set_amplitude(0.2f); + /// wave->set_speed(2.0f); + /// @endcode + class wave_widget : public procedural_shader_widget> { + public: + wave_widget() { + // 设置默认颜色 + set_color1({0.0f, 0.5f, 1.0f, 1.0f}); // 蓝色主色 + set_color2({0.0f, 1.0f, 0.8f, 1.0f}); // 青色次色 -/// @brief 波浪效果控件 -/// -/// 使用程序化渲染模式,通过正弦波生成动态颜色渐变效果。 -/// 支持动画,可用于创建流动的波浪背景。 -/// -/// 波浪参数通过 Push Constants 传递: -/// - v_color (通过顶点着色器): 主色 -/// - base_color: 次色 -/// - effect_params.x: frequency 波浪频率(推荐值: 5.0 - 20.0) -/// - effect_params.y: amplitude 波浪振幅(推荐值: 0.1 - 0.5) -/// - effect_params.z: speed 波浪速度(推荐值: 1.0 - 5.0) -/// - time: 由渲染器自动更新 -/// -/// @par 使用示例 -/// @code -/// // 创建波浪效果控件 -/// auto wave = create_widget(); -/// wave->set_size({200, 100}); -/// wave->set_colors( -/// vec4f_t{0.0f, 0.5f, 1.0f, 1.0f}, // 蓝色主色 -/// vec4f_t{0.0f, 1.0f, 0.8f, 1.0f} // 青色次色 -/// ); -/// wave->set_frequency(10.0f); -/// wave->set_amplitude(0.2f); -/// wave->set_speed(2.0f); -/// @endcode -class wave_widget : public shader_spec_widget> { -public: - wave_widget() { - // 设置默认颜色 - set_color1({0.0f, 0.5f, 1.0f, 1.0f}); // 蓝色主色 - set_color2({0.0f, 1.0f, 0.8f, 1.0f}); // 青色次色 - - // 设置默认波浪参数 - set_frequency(10.0f); - set_amplitude(0.2f); - set_speed(2.0f); - } - ~wave_widget() override = default; + // 设置默认波浪参数 + set_frequency(10.0f); + set_amplitude(0.2f); + set_speed(2.0f); + } - // ======================================================================== - // 公共接口 - // ======================================================================== + ~wave_widget() override = default; - /// @brief 设置颜色 - /// @param c1 主色 - /// @param c2 次色 - /// @return *this - auto& set_colors(const vec4f_t& c1, const vec4f_t& c2) { - set_color1(c1); - set_color2(c2); - return *this; - } + // ======================================================================== + // 公共接口 + // ======================================================================== - /// @brief 设置主色 - /// @param color 主色 - /// @return *this - auto& set_color1(const vec4f_t& color) { - color1_ = color; - mark_push_constant_effect_dirty(); - return *this; - } + /// @brief 设置颜色 + /// @param c1 主色 + /// @param c2 次色 + /// @return *this + auto& set_colors(const vec4f_t& c1, const vec4f_t& c2) { + set_color1(c1); + set_color2(c2); + return *this; + } - /// @brief 获取主色 - [[nodiscard]] auto get_color1() const noexcept -> vec4f_t { - return color1_; - } + /// @brief 设置主色 + /// @param color 主色 + /// @return *this + auto& set_color1(const vec4f_t& color) { + color1_ = color; + mark_effect_dirty(); + return *this; + } - /// @brief 设置次色 - /// @param color 次色 - /// @return *this - auto& set_color2(const vec4f_t& color) { - push_constant_effect().base_color = color; - mark_push_constant_effect_dirty(); - return *this; - } + /// @brief 获取主色 + [[nodiscard]] auto get_color1() const noexcept -> vec4f_t { + return color1_; + } - /// @brief 获取次色 - [[nodiscard]] auto get_color2() const noexcept -> vec4f_t { - return push_constant_effect().base_color; - } + /// @brief 设置次色 + /// @param color 次色 + /// @return *this + auto& set_color2(const vec4f_t& color) { + effect().base_color = color; + mark_effect_dirty(); + return *this; + } - /// @brief 设置波浪频率 - /// @param freq 频率(每个单位的波浪数) - /// @return *this - auto& set_frequency(float freq) { - push_constant_effect().effect_params.x() = freq; - mark_push_constant_effect_dirty(); - return *this; - } + /// @brief 获取次色 + [[nodiscard]] auto get_color2() const noexcept -> vec4f_t { + return effect().base_color; + } - /// @brief 获取波浪频率 - /// @return 频率 - [[nodiscard]] auto get_frequency() const noexcept -> float { - return push_constant_effect().effect_params.x(); - } + /// @brief 设置波浪频率 + /// @param freq 频率(每个单位的波浪数) + /// @return *this + auto& set_frequency(float freq) { + effect().effect_params.x() = freq; + mark_effect_dirty(); + return *this; + } - /// @brief 设置波浪振幅 - /// @param amp 振幅(UV 偏移量) - /// @return *this - auto& set_amplitude(float amp) { - push_constant_effect().effect_params.y() = amp; - mark_push_constant_effect_dirty(); - return *this; - } + /// @brief 获取波浪频率 + /// @return 频率 + [[nodiscard]] auto get_frequency() const noexcept -> float { + return effect().effect_params.x(); + } - /// @brief 获取波浪振幅 - /// @return 振幅 - [[nodiscard]] auto get_amplitude() const noexcept -> float { - return push_constant_effect().effect_params.y(); - } + /// @brief 设置波浪振幅 + /// @param amp 振幅(UV 偏移量) + /// @return *this + auto& set_amplitude(float amp) { + effect().effect_params.y() = amp; + mark_effect_dirty(); + return *this; + } - /// @brief 设置波浪速度 - /// @param speed 速度(单位/秒) - /// @return *this - auto& set_speed(float speed) { - push_constant_effect().effect_params.z() = speed; - mark_push_constant_effect_dirty(); - return *this; - } + /// @brief 获取波浪振幅 + /// @return 振幅 + [[nodiscard]] auto get_amplitude() const noexcept -> float { + return effect().effect_params.y(); + } - /// @brief 获取波浪速度 - /// @return 速度 - [[nodiscard]] auto get_speed() const noexcept -> float { - return push_constant_effect().effect_params.z(); - } + /// @brief 设置波浪速度 + /// @param speed 速度(单位/秒) + /// @return *this + auto& set_speed(float speed) { + effect().effect_params.z() = speed; + mark_effect_dirty(); + return *this; + } - // ======================================================================== - // 动画控制 - // ======================================================================== + /// @brief 获取波浪速度 + /// @return 速度 + [[nodiscard]] auto get_speed() const noexcept -> float { + return effect().effect_params.z(); + } - /// @brief 标记为动画控件(启用自动时间更新) - [[nodiscard]] auto is_animated() const noexcept -> bool override { - return true; - } + // ======================================================================== + // 动画控制 + // ======================================================================== - // ======================================================================== - // 基类虚函数实现 - // ======================================================================== + /// @brief 标记为动画控件(启用自动时间更新) + [[nodiscard]] auto is_animated() const noexcept -> bool override { + return true; + } -protected: - /// @brief 获取渲染模式 - [[nodiscard]] auto get_render_mode() const noexcept - -> custom_shader_render_mode override { - return custom_shader_render_mode::procedural; - } - - /// @brief 获取 Push Constants 效果参数数据 - /// @note 只返回 effect_params 部分(16字节),对应 Layer 3 - /// Layer 2 的 widget_rect 和 base_color 由渲染器自动填充 - [[nodiscard]] auto get_push_constant_effect_data() const - -> std::pair override { - return {&(push_constant_effect().effect_params), sizeof(vec4f_t)}; - } - -private: - vec4f_t color1_{0.0f, 0.5f, 1.0f, 1.0f}; ///< 主色(暂存,需要通过颜色传递机制使用) -}; - -} // namespace mirage \ No newline at end of file + private: + vec4f_t color1_{0.0f, 0.5f, 1.0f, 1.0f}; ///< 主色(暂存,需要通过颜色传递机制使用) + }; +} // namespace mirage diff --git a/src/ui/widgets/custom_shader/shader_spec_widget.h b/src/ui/widgets/custom_shader/shader_spec_widget.h deleted file mode 100644 index 5ee6095..0000000 --- a/src/ui/widgets/custom_shader/shader_spec_widget.h +++ /dev/null @@ -1,457 +0,0 @@ -#pragma once - -/** - * @file shader_spec_widget.h - * @deprecated This file contains a deprecated class. Use the specialized widget classes instead. - * - * Migration Guide: - * ================ - * - * 1. Procedural mode (no source texture): - * Old: shader_spec_widget - * New: procedural_shader_widget - * File: ui/widgets/custom_shader/procedural/procedural_shader_widget.h - * - * 2. PostProcess mode (samples current render target): - * Old: shader_spec_widget with post_process mode - * New: post_process_shader_widget - * File: ui/widgets/custom_shader/post_process/post_process_shader_widget.h - * - * 3. Mask mode (two-pass rendering): - * Old: shader_spec_widget with mask mode - * New: mask_shader_widget - * File: ui/widgets/custom_shader/mask/mask_shader_widget.h - * - * 4. Full custom mode (custom vertex shader and geometry): - * Old: shader_spec_widget - * New: full_custom_shader_widget - * File: ui/widgets/custom_shader/full_custom/full_custom_shader_widget.h - * - * API Changes: - * ============ - * - push_constant_effect() -> effect() - * - mark_push_constant_effect_dirty() -> mark_effect_dirty() - * - push_constant_effect_type -> effect_type - */ - -#include "ui/widgets/custom_shader/custom_shader_widget_base.h" -#include "render/vertex_types.h" -#include "render/push_constant_traits.h" -#include - -namespace mirage { - /// @brief shader_spec 概念定义 - /// - /// ShaderSpec 必须提供以下静态成员函数: - /// - get_vertex_spirv() -> std::span - /// - get_fragment_spirv() -> std::span - /// - get_bindings() -> std::span - /// - shader_id : uint32_t - /// - params_type : 参数类型 - template - concept shader_spec_concept = requires { - { T::get_vertex_spirv() } -> std::convertible_to>; - { T::get_fragment_spirv() } -> std::convertible_to>; - { T::get_bindings() } -> std::convertible_to>; - { T::shader_id } -> std::convertible_to; - typename T::params_type; - }; - - /// @brief 检测 ShaderSpec 是否提供了 push_constant_effect_type - /// - /// 如果 ShaderSpec 提供了 push_constant_effect_type,则可以使用 - /// shader_spec_widget 的 Push Constants 效果参数功能。 - template - concept has_push_constant_effect = requires { - typename T::push_constant_effect_type; - }; - - /// @brief 基于 shader_spec 的自定义着色器控件模板类 - /// - /// @tparam ShaderSpec 着色器规格类型(由着色器工具自动生成的 xxx_shader_spec) - /// @tparam VertexT 顶点类型(默认使用 ui_vertex) - /// - /// 此模板类自动从 ShaderSpec 获取着色器 SPIR-V 和绑定信息, - /// 无需手动重写 get_vertex_shader_spirv()、get_fragment_shader_spirv() 和 get_bindings()。 - /// - /// 支持三种渲染模式: - /// - **程序化渲染**:使用着色器生成内容(无子控件,无源纹理) - /// - **后处理模式**:对子控件渲染结果或指定纹理应用着色器效果 - /// - **自定义几何模式**:使用自定义顶点着色器和顶点缓冲 - /// - /// @deprecated This class is deprecated. Use the following replacements: - /// - /// Migration Guide: - /// ================ - /// - /// 1. Procedural mode (no source texture): - /// Old: shader_spec_widget - /// New: procedural_shader_widget - /// File: ui/widgets/custom_shader/procedural/procedural_shader_widget.h - /// - /// 2. PostProcess mode (samples current render target): - /// Old: shader_spec_widget with post_process mode - /// New: post_process_shader_widget - /// File: ui/widgets/custom_shader/post_process/post_process_shader_widget.h - /// - /// 3. Mask mode (two-pass rendering): - /// Old: shader_spec_widget with mask mode - /// New: mask_shader_widget - /// File: ui/widgets/custom_shader/mask/mask_shader_widget.h - /// - /// 4. Full custom mode (custom vertex shader and geometry): - /// Old: shader_spec_widget - /// New: full_custom_shader_widget - /// File: ui/widgets/custom_shader/full_custom/full_custom_shader_widget.h - /// - /// API Changes: - /// ============ - /// - push_constant_effect() -> effect() - /// - mark_push_constant_effect_dirty() -> mark_effect_dirty() - /// - push_constant_effect_type -> effect_type - /// - /// @example - /// ```cpp - /// // 使用工具生成的 shader_spec - /// #include "vignette_vert_frag.h" - /// - /// class vignette_widget : public shader_spec_widget> { - /// public: - /// vignette_widget() { - /// params().radius = 0.5f; - /// params().softness = 0.3f; - /// } - /// - /// auto& set_radius(float r) { - /// params().radius = r; - /// mark_params_dirty(); - /// return *this; - /// } - /// - /// protected: - /// auto get_render_mode() const noexcept -> custom_shader_render_mode override { - /// return custom_shader_render_mode::post_process; - /// } - /// }; - /// ``` - template requires shader_spec_concept - class [[deprecated("Use procedural_shader_widget, post_process_shader_widget, mask_shader_widget, or full_custom_shader_widget instead")]] - shader_spec_widget : public custom_shader_widget_base { - public: - using shader_spec_type = ShaderSpec; - using params_type = ShaderSpec::params_type; - using vertex_type = VertexT; - - /// @brief 条件性定义 push_constant_effect_type - /// @note 如果 ShaderSpec 没有提供 push_constant_effect_type,则使用 void - using push_constant_effect_type = std::conditional_t< - has_push_constant_effect, - typename ShaderSpec::push_constant_effect_type, - void - >; - - // 静态断言:确保 params_type 满足要求 - static_assert(std::is_standard_layout_v, - "params_type must be standard layout for GPU compatibility"); - static_assert(alignof(params_type) <= 16, - "params_type alignment must not exceed 16 bytes"); - - // 静态断言:验证效果 Push Constant 类型(如果存在) - // 验证要求(128 字节分层布局): - // - Layer 3 效果扩展参数(偏移 112-127):最大 16 字节 - static_assert(validate_shader_spec_push_constants(), - "Effect push constants validation failed: " - "size must not exceed 16 bytes (Layer 3: offset 112-127)"); - - shader_spec_widget() = default; - ~shader_spec_widget() override = default; - - // ======================================================================== - // 参数访问 - // ======================================================================== - - /// @brief 获取参数的可变引用 - /// @note 修改后需要调用 mark_params_dirty() - [[nodiscard]] auto params() noexcept -> params_type& { return params_; } - - /// @brief 获取参数的只读引用 - [[nodiscard]] auto params() const noexcept -> const params_type& { return params_; } - - /// @brief 标记参数已修改 - void mark_params_dirty() { - params_dirty_ = true; - mark_render_dirty_internal(); - } - - // ======================================================================== - // Push Constants 效果参数访问(仅当 ShaderSpec 提供了 push_constant_effect_type 时可用) - // ======================================================================== - - /// @brief 获取 Push Constants 效果参数的可变引用 - /// @note 修改后需要调用 mark_push_constant_effect_dirty() - /// @note 仅当 ShaderSpec 提供了 push_constant_effect_type 时可用 - [[nodiscard]] auto push_constant_effect() noexcept - -> push_constant_effect_type& - requires has_push_constant_effect - { - return push_constant_effect_; - } - - /// @brief 获取 Push Constants 效果参数的只读引用 - /// @note 仅当 ShaderSpec 提供了 push_constant_effect_type 时可用 - [[nodiscard]] auto push_constant_effect() const noexcept - -> const push_constant_effect_type& - requires has_push_constant_effect - { - return push_constant_effect_; - } - - /// @brief 标记 Push Constants 效果参数已修改 - /// @note 仅当 ShaderSpec 提供了 push_constant_effect_type 时可用 - void mark_push_constant_effect_dirty() - requires has_push_constant_effect - { - push_constant_effect_dirty_ = true; - mark_render_dirty_internal(); - } - - protected: - // ======================================================================== - // 实现基类纯虚函数 - 由 ShaderSpec 自动提供 - // ======================================================================== - - /// @brief 获取着色器唯一标识符 - [[nodiscard]] auto get_shader_id() const noexcept -> uint32_t override { - return ShaderSpec::shader_id; - } - - /// @brief 获取顶点着色器 SPIR-V - [[nodiscard]] auto get_vertex_shader_spirv() const - -> std::span override { - return ShaderSpec::get_vertex_spirv(); - } - - /// @brief 获取片段着色器 SPIR-V - [[nodiscard]] auto get_fragment_shader_spirv() const - -> std::span override { - return ShaderSpec::get_fragment_spirv(); - } - - /// @brief 获取描述符绑定信息 - [[nodiscard]] auto get_bindings() const - -> std::span override { - return ShaderSpec::get_bindings(); - } - - [[nodiscard]] auto get_params_data() const - -> std::pair override { - return {¶ms_, sizeof(params_type)}; - } - - [[nodiscard]] auto is_params_dirty() const noexcept -> bool override { - return params_dirty_; - } - - void clear_params_dirty() override { - params_dirty_ = false; - } - - // ======================================================================== - // Push Constants 效果参数实现 - // ======================================================================== - - /// @brief 获取 Push Constants 效果参数数据指针和大小 - [[nodiscard]] auto get_push_constant_effect_data() const - -> std::pair override - { - if constexpr (has_push_constant_effect) { - return {&push_constant_effect_, sizeof(push_constant_effect_type)}; - } else { - return {nullptr, 0}; - } - } - - /// @brief 检查 Push Constants 效果参数是否已修改 - [[nodiscard]] auto is_push_constant_effect_dirty() const noexcept - -> bool override - { - if constexpr (has_push_constant_effect) { - return push_constant_effect_dirty_; - } else { - return false; - } - } - - /// @brief 清除 Push Constants 效果参数脏标志 - void clear_push_constant_effect_dirty() override - { - if constexpr (has_push_constant_effect) { - push_constant_effect_dirty_ = false; - } - } - - // ======================================================================== - // 效果区域相关(用于 post_process 模式) - // ======================================================================== - - /// @brief 获取效果区域 rect - [[nodiscard]] auto get_effect_rect() const noexcept -> vec4f_t override - { - if constexpr (has_push_constant_effect) { - return push_constant_effect_.effect_rect; - } - return vec4f_t{0.0f, 0.0f, 0.0f, 0.0f}; - } - - /// @brief 设置效果区域 rect - void set_effect_rect(const vec4f_t& rect) override - { - if constexpr (has_push_constant_effect) { - push_constant_effect_.effect_rect = rect; - push_constant_effect_dirty_ = true; - mark_render_dirty_internal(); - } - } - - /// @brief 获取原始效果区域 rect(用于 UV 计算) - [[nodiscard]] auto get_original_effect_rect() const noexcept -> vec4f_t override - { - if constexpr (has_push_constant_effect) { - return push_constant_effect_.original_effect_rect; - } - return vec4f_t{0.0f, 0.0f, 0.0f, 0.0f}; - } - - /// @brief 设置原始效果区域 rect(用于 UV 计算) - void set_original_effect_rect(const vec4f_t& rect) override - { - if constexpr (has_push_constant_effect) { - push_constant_effect_.original_effect_rect = rect; - push_constant_effect_dirty_ = true; - mark_render_dirty_internal(); - } - } - - // ======================================================================== - // 自定义顶点支持 - // ======================================================================== - - /// @brief 标记顶点数据已修改 - void mark_vertices_dirty() { - vertices_dirty_ = true; - mark_render_dirty_internal(); - } - - [[nodiscard]] auto is_vertices_dirty() const noexcept -> bool override { - return vertices_dirty_; - } - - void clear_vertices_dirty() override { - vertices_dirty_ = false; - } - - // ======================================================================== - // 顶点数据管理(仅 custom_geometry 模式使用) - // ======================================================================== - - /// @brief 获取顶点数据 - [[nodiscard]] auto get_vertices() const noexcept -> const std::vector& { - return vertices_; - } - - /// @brief 获取顶点数据(可修改) - [[nodiscard]] auto get_vertices() noexcept -> std::vector& { - return vertices_; - } - - /// @brief 设置顶点数据 - void set_vertices(std::vector vertices) { - vertices_ = std::move(vertices); - mark_vertices_dirty(); - } - - /// @brief 获取索引数据 - [[nodiscard]] auto get_indices() const noexcept -> const std::vector& { - return indices_; - } - - /// @brief 设置索引数据 - void set_indices(std::vector indices) { - indices_ = std::move(indices); - mark_vertices_dirty(); - } - - /// @brief 获取顶点缓冲配置 - [[nodiscard]] auto get_vertex_buffer_config() const - -> std::optional override { - if (vertices_.empty()) { - return std::nullopt; - } - - return custom_vertex_buffer_config{ - .data = vertices_.data(), - .data_size = vertices_.size() * sizeof(VertexT), - .vertex_count = vertices_.size(), - .binding = get_vertex_binding_description(), - .attributes = get_vertex_attribute_descriptions() - }; - } - - /// @brief 获取索引缓冲配置 - [[nodiscard]] auto get_index_buffer_config() const - -> std::optional override { - if (indices_.empty()) { - return std::nullopt; - } - - return index_buffer_config{ - .data = indices_.data(), - .index_count = indices_.size() - }; - } - - /// @brief 获取顶点绑定描述(可重写) - [[nodiscard]] virtual auto get_vertex_binding_description() const - -> vk::VertexInputBindingDescription { - if constexpr (requires { VertexT::get_binding_description(); }) { - return VertexT::get_binding_description(); - } - else { - return vk::VertexInputBindingDescription{ - 0, sizeof(VertexT), vk::VertexInputRate::eVertex - }; - } - } - - /// @brief 获取顶点属性描述(可重写) - [[nodiscard]] virtual auto get_vertex_attribute_descriptions() const - -> std::vector { - if constexpr (requires { VertexT::get_attribute_descriptions(); }) { - auto attrs = VertexT::get_attribute_descriptions(); - return std::vector( - attrs.begin(), attrs.end()); - } - else { - return {}; - } - } - - private: - params_type params_{}; - bool params_dirty_ = true; - bool vertices_dirty_ = false; - - /// @brief 条件性存储 push_constant_effect_ - /// @note 使用 [[no_unique_address]] 避免 void 类型占用空间 - [[no_unique_address]] std::conditional_t< - has_push_constant_effect, - push_constant_effect_type, - std::monostate - > push_constant_effect_{}; - - bool push_constant_effect_dirty_ = true; ///< 初始为 true 以确保首次渲染 - - std::vector vertices_; - std::vector indices_; - }; -} // namespace mirage diff --git a/tools/templates/base/header.jinja2 b/tools/templates/base/header.jinja2 index a9747b7..ddf759f 100644 --- a/tools/templates/base/header.jinja2 +++ b/tools/templates/base/header.jinja2 @@ -178,7 +178,7 @@ struct {{ shader_spec_name }} { {%- if has_push_constant_effect %} /// @brief Push Constants 效果部分类型 - using push_constant_effect_type = {{ push_constant_effect_type_name }}; + using effect_type = {{ push_constant_effect_type_name }}; {%- endif %} {%- if has_push_constant_base_layout %}