Refactor shader widget classes and remove deprecated shader_spec_widget
- Replaced instances of shader_spec_widget with procedural_shader_widget in gradient_widget and wave_widget. - Updated gradient_widget and wave_widget to use new effect handling methods. - Removed the deprecated shader_spec_widget.h file and its associated functionality. - Adjusted header template to reflect changes in push constant effect type naming.
This commit is contained in:
@@ -86,8 +86,8 @@ namespace mirage {
|
||||
*/
|
||||
template <typename ShaderSpec>
|
||||
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;
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/widgets/custom_shader/custom_shader_widget_base.h"
|
||||
#include "render/vertex_types.h"
|
||||
#include <type_traits>
|
||||
|
||||
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<shaders::GradientParams> {
|
||||
/// 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<const uint32_t> override {
|
||||
/// return shaders::gradient_frag_spirv;
|
||||
/// }
|
||||
///
|
||||
/// auto get_bindings() const -> std::span<const shader_binding_info> override {
|
||||
/// return shaders::gradient_bindings;
|
||||
/// }
|
||||
///
|
||||
/// auto get_render_mode() const noexcept -> custom_shader_render_mode override {
|
||||
/// return custom_shader_render_mode::procedural;
|
||||
/// }
|
||||
/// };
|
||||
/// ```
|
||||
template <typename ParamsT, typename VertexT = ui_vertex>
|
||||
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>,
|
||||
"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<const void*, size_t> 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<VertexT>& {
|
||||
return vertices_;
|
||||
}
|
||||
|
||||
/// @brief 获取顶点数据(可修改)
|
||||
[[nodiscard]] auto get_vertices() noexcept -> std::vector<VertexT>& {
|
||||
return vertices_;
|
||||
}
|
||||
|
||||
/// @brief 设置顶点数据
|
||||
void set_vertices(std::vector<VertexT> vertices) {
|
||||
vertices_ = std::move(vertices);
|
||||
mark_vertices_dirty();
|
||||
}
|
||||
|
||||
/// @brief 获取索引数据
|
||||
[[nodiscard]] auto get_indices() const noexcept -> const std::vector<uint32_t>& {
|
||||
return indices_;
|
||||
}
|
||||
|
||||
/// @brief 设置索引数据
|
||||
void set_indices(std::vector<uint32_t> indices) {
|
||||
indices_ = std::move(indices);
|
||||
mark_vertices_dirty();
|
||||
}
|
||||
|
||||
/// @brief 获取顶点缓冲配置
|
||||
[[nodiscard]] auto get_vertex_buffer_config() const
|
||||
-> std::optional<custom_vertex_buffer_config> 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<index_buffer_config> 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<vk::VertexInputAttributeDescription> {
|
||||
if constexpr (requires { VertexT::get_attribute_descriptions(); }) {
|
||||
auto attrs = VertexT::get_attribute_descriptions();
|
||||
return std::vector<vk::VertexInputAttributeDescription>(
|
||||
attrs.begin(), attrs.end());
|
||||
}
|
||||
else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
ParamsT params_{};
|
||||
bool params_dirty_ = true;
|
||||
bool vertices_dirty_ = false;
|
||||
|
||||
std::vector<VertexT> vertices_;
|
||||
std::vector<uint32_t> indices_;
|
||||
};
|
||||
} // namespace mirage
|
||||
@@ -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<shaders::blur_shader_spec<>> {
|
||||
class blur_widget : public post_process_shader_widget<shaders::blur_shader_spec<>> {
|
||||
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 更新描述符绑定 - 自定义采样器配置
|
||||
///
|
||||
/// 重写此方法以使用自定义采样器配置。
|
||||
|
||||
@@ -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<shaders::chromatic_aberration_shader_spec<>> {
|
||||
class chromatic_aberration_widget : public post_process_shader_widget<shaders::chromatic_aberration_shader_spec<>> {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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<shaders::color_adjust_shader_spec<>> {
|
||||
class color_adjust_widget : public post_process_shader_widget<shaders::color_adjust_shader_spec<>> {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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<shaders::color_tint_shader_spec<>> {
|
||||
class color_tint_widget : public post_process_shader_widget<shaders::color_tint_shader_spec<>> {
|
||||
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
|
||||
@@ -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<shaders::noise_shader_spec<>> {
|
||||
class noise_widget : public post_process_shader_widget<shaders::noise_shader_spec<>> {
|
||||
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 {
|
||||
|
||||
@@ -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<shaders::vignette_shader_spec<>> {
|
||||
class vignette_widget : public post_process_shader_widget<shaders::vignette_shader_spec<>> {
|
||||
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
|
||||
|
||||
@@ -1,170 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/widgets/custom_shader/custom_shader_widget.h"
|
||||
#include <glm/vec4.hpp>
|
||||
#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_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<shaders::glitch_effect_shader_spec<>> {
|
||||
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_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<glitch_widget::GlitchParams> {
|
||||
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<const uint32_t> override {
|
||||
// TODO: 返回预编译的 glitch_effect.frag.glsl SPIR-V
|
||||
// 从生成的着色器头文件获取:
|
||||
// return shaders::glitch_effect_frag_spirv;
|
||||
return {};
|
||||
}
|
||||
|
||||
/// @brief 获取描述符绑定信息
|
||||
[[nodiscard]] auto get_bindings() const
|
||||
-> std::span<const shader_binding_info> 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<const uint32_t> override {
|
||||
// 返回 nullopt 使用默认顶点着色器
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mirage::ui
|
||||
/// @brief 标记为动画控件(启用自动时间更新)
|
||||
[[nodiscard]] auto is_animated() const noexcept -> bool override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
} // namespace mirage
|
||||
|
||||
@@ -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 <cmath>
|
||||
|
||||
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_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<shaders::gradient_shader_spec<>> {
|
||||
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_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<shaders::gradient_shader_spec<>> {
|
||||
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<float>(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<float>(type);
|
||||
mark_effect_dirty();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// @brief 获取渐变类型
|
||||
[[nodiscard]] auto get_gradient_type() const noexcept -> gradient_type {
|
||||
return static_cast<gradient_type>(
|
||||
static_cast<uint32_t>(push_constant_effect().effect_params.x()));
|
||||
}
|
||||
/// @brief 获取渐变类型
|
||||
[[nodiscard]] auto get_gradient_type() const noexcept -> gradient_type {
|
||||
return static_cast<gradient_type>(
|
||||
static_cast<uint32_t>(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<const void*, size_t> 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
|
||||
|
||||
@@ -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_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<shaders::wave_shader_spec<>> {
|
||||
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_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<shaders::wave_shader_spec<>> {
|
||||
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<const void*, size_t> override {
|
||||
return {&(push_constant_effect().effect_params), sizeof(vec4f_t)};
|
||||
}
|
||||
|
||||
private:
|
||||
vec4f_t color1_{0.0f, 0.5f, 1.0f, 1.0f}; ///< 主色(暂存,需要通过颜色传递机制使用)
|
||||
};
|
||||
|
||||
} // namespace mirage
|
||||
private:
|
||||
vec4f_t color1_{0.0f, 0.5f, 1.0f, 1.0f}; ///< 主色(暂存,需要通过颜色传递机制使用)
|
||||
};
|
||||
} // namespace mirage
|
||||
|
||||
@@ -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<MySpec>
|
||||
* New: procedural_shader_widget<MySpec>
|
||||
* File: ui/widgets/custom_shader/procedural/procedural_shader_widget.h
|
||||
*
|
||||
* 2. PostProcess mode (samples current render target):
|
||||
* Old: shader_spec_widget<MySpec> with post_process mode
|
||||
* New: post_process_shader_widget<MySpec>
|
||||
* File: ui/widgets/custom_shader/post_process/post_process_shader_widget.h
|
||||
*
|
||||
* 3. Mask mode (two-pass rendering):
|
||||
* Old: shader_spec_widget<MySpec> with mask mode
|
||||
* New: mask_shader_widget<MySpec>
|
||||
* File: ui/widgets/custom_shader/mask/mask_shader_widget.h
|
||||
*
|
||||
* 4. Full custom mode (custom vertex shader and geometry):
|
||||
* Old: shader_spec_widget<MySpec, VertexT>
|
||||
* New: full_custom_shader_widget<MySpec, VertexT>
|
||||
* 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 <type_traits>
|
||||
|
||||
namespace mirage {
|
||||
/// @brief shader_spec 概念定义
|
||||
///
|
||||
/// ShaderSpec 必须提供以下静态成员函数:
|
||||
/// - get_vertex_spirv() -> std::span<const uint32_t>
|
||||
/// - get_fragment_spirv() -> std::span<const uint32_t>
|
||||
/// - get_bindings() -> std::span<const shader_binding_info>
|
||||
/// - shader_id : uint32_t
|
||||
/// - params_type : 参数类型
|
||||
template <typename T>
|
||||
concept shader_spec_concept = requires {
|
||||
{ T::get_vertex_spirv() } -> std::convertible_to<std::span<const uint32_t>>;
|
||||
{ T::get_fragment_spirv() } -> std::convertible_to<std::span<const uint32_t>>;
|
||||
{ T::get_bindings() } -> std::convertible_to<std::span<const shader_binding_info>>;
|
||||
{ T::shader_id } -> std::convertible_to<uint32_t>;
|
||||
typename T::params_type;
|
||||
};
|
||||
|
||||
/// @brief 检测 ShaderSpec 是否提供了 push_constant_effect_type
|
||||
///
|
||||
/// 如果 ShaderSpec 提供了 push_constant_effect_type,则可以使用
|
||||
/// shader_spec_widget 的 Push Constants 效果参数功能。
|
||||
template <typename T>
|
||||
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<MySpec>
|
||||
/// New: procedural_shader_widget<MySpec>
|
||||
/// File: ui/widgets/custom_shader/procedural/procedural_shader_widget.h
|
||||
///
|
||||
/// 2. PostProcess mode (samples current render target):
|
||||
/// Old: shader_spec_widget<MySpec> with post_process mode
|
||||
/// New: post_process_shader_widget<MySpec>
|
||||
/// File: ui/widgets/custom_shader/post_process/post_process_shader_widget.h
|
||||
///
|
||||
/// 3. Mask mode (two-pass rendering):
|
||||
/// Old: shader_spec_widget<MySpec> with mask mode
|
||||
/// New: mask_shader_widget<MySpec>
|
||||
/// File: ui/widgets/custom_shader/mask/mask_shader_widget.h
|
||||
///
|
||||
/// 4. Full custom mode (custom vertex shader and geometry):
|
||||
/// Old: shader_spec_widget<MySpec, VertexT>
|
||||
/// New: full_custom_shader_widget<MySpec, VertexT>
|
||||
/// 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<shaders::vignette_shader_spec<>> {
|
||||
/// 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 <typename ShaderSpec, typename VertexT = ui_vertex> requires shader_spec_concept<ShaderSpec>
|
||||
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<ShaderSpec>,
|
||||
typename ShaderSpec::push_constant_effect_type,
|
||||
void
|
||||
>;
|
||||
|
||||
// 静态断言:确保 params_type 满足要求
|
||||
static_assert(std::is_standard_layout_v<params_type>,
|
||||
"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<ShaderSpec>(),
|
||||
"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<ShaderSpec>
|
||||
{
|
||||
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<ShaderSpec>
|
||||
{
|
||||
return push_constant_effect_;
|
||||
}
|
||||
|
||||
/// @brief 标记 Push Constants 效果参数已修改
|
||||
/// @note 仅当 ShaderSpec 提供了 push_constant_effect_type 时可用
|
||||
void mark_push_constant_effect_dirty()
|
||||
requires has_push_constant_effect<ShaderSpec>
|
||||
{
|
||||
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<const uint32_t> override {
|
||||
return ShaderSpec::get_vertex_spirv();
|
||||
}
|
||||
|
||||
/// @brief 获取片段着色器 SPIR-V
|
||||
[[nodiscard]] auto get_fragment_shader_spirv() const
|
||||
-> std::span<const uint32_t> override {
|
||||
return ShaderSpec::get_fragment_spirv();
|
||||
}
|
||||
|
||||
/// @brief 获取描述符绑定信息
|
||||
[[nodiscard]] auto get_bindings() const
|
||||
-> std::span<const shader_binding_info> override {
|
||||
return ShaderSpec::get_bindings();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto get_params_data() const
|
||||
-> std::pair<const void*, size_t> 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<const void*, size_t> override
|
||||
{
|
||||
if constexpr (has_push_constant_effect<ShaderSpec>) {
|
||||
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<ShaderSpec>) {
|
||||
return push_constant_effect_dirty_;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief 清除 Push Constants 效果参数脏标志
|
||||
void clear_push_constant_effect_dirty() override
|
||||
{
|
||||
if constexpr (has_push_constant_effect<ShaderSpec>) {
|
||||
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<ShaderSpec>) {
|
||||
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<ShaderSpec>) {
|
||||
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<ShaderSpec>) {
|
||||
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<ShaderSpec>) {
|
||||
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<VertexT>& {
|
||||
return vertices_;
|
||||
}
|
||||
|
||||
/// @brief 获取顶点数据(可修改)
|
||||
[[nodiscard]] auto get_vertices() noexcept -> std::vector<VertexT>& {
|
||||
return vertices_;
|
||||
}
|
||||
|
||||
/// @brief 设置顶点数据
|
||||
void set_vertices(std::vector<VertexT> vertices) {
|
||||
vertices_ = std::move(vertices);
|
||||
mark_vertices_dirty();
|
||||
}
|
||||
|
||||
/// @brief 获取索引数据
|
||||
[[nodiscard]] auto get_indices() const noexcept -> const std::vector<uint32_t>& {
|
||||
return indices_;
|
||||
}
|
||||
|
||||
/// @brief 设置索引数据
|
||||
void set_indices(std::vector<uint32_t> indices) {
|
||||
indices_ = std::move(indices);
|
||||
mark_vertices_dirty();
|
||||
}
|
||||
|
||||
/// @brief 获取顶点缓冲配置
|
||||
[[nodiscard]] auto get_vertex_buffer_config() const
|
||||
-> std::optional<custom_vertex_buffer_config> 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<index_buffer_config> 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<vk::VertexInputAttributeDescription> {
|
||||
if constexpr (requires { VertexT::get_attribute_descriptions(); }) {
|
||||
auto attrs = VertexT::get_attribute_descriptions();
|
||||
return std::vector<vk::VertexInputAttributeDescription>(
|
||||
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<ShaderSpec>,
|
||||
push_constant_effect_type,
|
||||
std::monostate
|
||||
> push_constant_effect_{};
|
||||
|
||||
bool push_constant_effect_dirty_ = true; ///< 初始为 true 以确保首次渲染
|
||||
|
||||
std::vector<VertexT> vertices_;
|
||||
std::vector<uint32_t> indices_;
|
||||
};
|
||||
} // namespace mirage
|
||||
@@ -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 %}
|
||||
|
||||
Reference in New Issue
Block a user