refactor(renderer): 重构着色器系统并优化渲染命令结构

- 将 shader_system.h 重命名为 shader.h 并合并相关实现
- 移除 shader_preset.h 和 shader_preset.cpp 文件
- 优化 render_command.h 中的代码格式和结构
- 清理不必要的头文件包含
This commit is contained in:
ChestnutYueyue 2026-02-26 20:12:12 +08:00
parent 00d709fcc8
commit c84aab70ed
7 changed files with 92 additions and 641 deletions

View File

@ -3,7 +3,6 @@
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <string>
namespace extra2d { namespace extra2d {

View File

@ -26,8 +26,7 @@
#include <renderer/camera.h> #include <renderer/camera.h>
#include <renderer/render_target.h> #include <renderer/render_target.h>
#include <renderer/renderer.h> #include <renderer/renderer.h>
#include <renderer/shader_system.h> #include <renderer/shader.h>
// Scene // Scene
#include <scene/node.h> #include <scene/node.h>

View File

@ -4,11 +4,13 @@
#include <core/rect.h> #include <core/rect.h>
#include <core/types.h> #include <core/types.h>
#include <core/vec2.h> #include <core/vec2.h>
#include <graphics/texture.h>
#include <glm/mat4x4.hpp>
#include <cstdint> #include <cstdint>
#include <glm/mat4x4.hpp>
#include <graphics/texture.h>
#include <string>
#include <variant> #include <variant>
namespace extra2d { namespace extra2d {
// 前向声明 // 前向声明
@ -20,39 +22,39 @@ class FontAtlas;
*/ */
enum class RenderCommandType : uint8_t { enum class RenderCommandType : uint8_t {
None = 0, None = 0,
Sprite, // 精灵绘制 Sprite, // 精灵绘制
Line, // 线条绘制 Line, // 线条绘制
Rect, // 矩形绘制 Rect, // 矩形绘制
FilledRect, // 填充矩形 FilledRect, // 填充矩形
Circle, // 圆形绘制 Circle, // 圆形绘制
FilledCircle, // 填充圆形 FilledCircle, // 填充圆形
Triangle, // 三角形绘制 Triangle, // 三角形绘制
FilledTriangle, // 填充三角形 FilledTriangle, // 填充三角形
Polygon, // 多边形绘制 Polygon, // 多边形绘制
FilledPolygon, // 填充多边形 FilledPolygon, // 填充多边形
Text, // 文本绘制 Text, // 文本绘制
Custom // 自定义绘制 Custom // 自定义绘制
}; };
/** /**
* @brief * @brief
*/ */
struct SpriteCommandData { struct SpriteCommandData {
const Texture* texture; const Texture *texture;
Rect destRect; Rect destRect;
Rect srcRect; Rect srcRect;
Color tint; Color tint;
float rotation; float rotation;
Vec2 anchor; Vec2 anchor;
uint32_t sortKey; // 用于自动排序的键值 uint32_t sortKey; // 用于自动排序的键值
SpriteCommandData() SpriteCommandData()
: texture(nullptr), destRect(), srcRect(), tint(Colors::White), : texture(nullptr), destRect(), srcRect(), tint(Colors::White),
rotation(0.0f), anchor(0.0f, 0.0f), sortKey(0) {} rotation(0.0f), anchor(0.0f, 0.0f), sortKey(0) {}
SpriteCommandData(const Texture* tex, const Rect& dest, const Rect& src, SpriteCommandData(const Texture *tex, const Rect &dest, const Rect &src,
const Color& t, float rot, const Vec2& anc, uint32_t key) const Color &t, float rot, const Vec2 &anc, uint32_t key)
: texture(tex), destRect(dest), srcRect(src), tint(t), : texture(tex), destRect(dest), srcRect(src), tint(t), rotation(rot),
rotation(rot), anchor(anc), sortKey(key) {} anchor(anc), sortKey(key) {}
}; };
/** /**
@ -63,10 +65,10 @@ struct LineCommandData {
Vec2 end; Vec2 end;
Color color; Color color;
float width; float width;
LineCommandData() : start(), end(), color(Colors::White), width(1.0f) {} LineCommandData() : start(), end(), color(Colors::White), width(1.0f) {}
LineCommandData(const Vec2& s, const Vec2& e, const Color& c, float w) LineCommandData(const Vec2 &s, const Vec2 &e, const Color &c, float w)
: start(s), end(e), color(c), width(w) {} : start(s), end(e), color(c), width(w) {}
}; };
/** /**
@ -77,10 +79,11 @@ struct RectCommandData {
Color color; Color color;
float width; float width;
bool filled; bool filled;
RectCommandData() : rect(), color(Colors::White), width(1.0f), filled(false) {} RectCommandData()
RectCommandData(const Rect& r, const Color& c, float w, bool f) : rect(), color(Colors::White), width(1.0f), filled(false) {}
: rect(r), color(c), width(w), filled(f) {} RectCommandData(const Rect &r, const Color &c, float w, bool f)
: rect(r), color(c), width(w), filled(f) {}
}; };
/** /**
@ -93,11 +96,13 @@ struct CircleCommandData {
int segments; int segments;
float width; float width;
bool filled; bool filled;
CircleCommandData() : center(), radius(0.0f), color(Colors::White), CircleCommandData()
segments(32), width(1.0f), filled(false) {} : center(), radius(0.0f), color(Colors::White), segments(32), width(1.0f),
CircleCommandData(const Vec2& c, float r, const Color& col, int seg, float w, bool f) filled(false) {}
: center(c), radius(r), color(col), segments(seg), width(w), filled(f) {} CircleCommandData(const Vec2 &c, float r, const Color &col, int seg, float w,
bool f)
: center(c), radius(r), color(col), segments(seg), width(w), filled(f) {}
}; };
/** /**
@ -108,11 +113,12 @@ struct TriangleCommandData {
Color color; Color color;
float width; float width;
bool filled; bool filled;
TriangleCommandData() : p1(), p2(), p3(), color(Colors::White), TriangleCommandData()
width(1.0f), filled(false) {} : p1(), p2(), p3(), color(Colors::White), width(1.0f), filled(false) {}
TriangleCommandData(const Vec2& a, const Vec2& b, const Vec2& c, const Color& col, float w, bool f) TriangleCommandData(const Vec2 &a, const Vec2 &b, const Vec2 &c,
: p1(a), p2(b), p3(c), color(col), width(w), filled(f) {} const Color &col, float w, bool f)
: p1(a), p2(b), p3(c), color(col), width(w), filled(f) {}
}; };
/** /**
@ -123,21 +129,21 @@ struct PolygonCommandData {
Color color; Color color;
float width; float width;
bool filled; bool filled;
PolygonCommandData() : color(Colors::White), width(1.0f), filled(false) {} PolygonCommandData() : color(Colors::White), width(1.0f), filled(false) {}
PolygonCommandData(std::vector<Vec2> pts, const Color& col, float w, bool f) PolygonCommandData(std::vector<Vec2> pts, const Color &col, float w, bool f)
: points(std::move(pts)), color(col), width(w), filled(f) {} : points(std::move(pts)), color(col), width(w), filled(f) {}
}; };
/** /**
* @brief * @brief
*/ */
struct TextCommandData { struct TextCommandData {
const FontAtlas* font; const FontAtlas *font;
std::string text; std::string text;
Vec2 position; Vec2 position;
Color color; Color color;
TextCommandData() : font(nullptr), text(), position(), color(Colors::White) {} TextCommandData() : font(nullptr), text(), position(), color(Colors::White) {}
}; };
@ -147,33 +153,29 @@ struct TextCommandData {
*/ */
struct RenderCommand { struct RenderCommand {
RenderCommandType type; RenderCommandType type;
uint32_t layer; // 渲染层级,用于排序 uint32_t layer; // 渲染层级,用于排序
uint32_t order; // 提交顺序,保证同层级内稳定排序 uint32_t order; // 提交顺序,保证同层级内稳定排序
glm::mat4 transform; // 变换矩阵 glm::mat4 transform; // 变换矩阵
// 使用 variant 存储具体数据 // 使用 variant 存储具体数据
std::variant< std::variant<SpriteCommandData, LineCommandData, RectCommandData,
SpriteCommandData, CircleCommandData, TriangleCommandData, PolygonCommandData,
LineCommandData, TextCommandData>
RectCommandData, data;
CircleCommandData,
TriangleCommandData, RenderCommand()
PolygonCommandData, : type(RenderCommandType::None), layer(0), order(0), transform(1.0f) {}
TextCommandData
> data;
RenderCommand() : type(RenderCommandType::None), layer(0), order(0),
transform(1.0f) {}
// 便捷构造函数 // 便捷构造函数
static RenderCommand makeSprite(const Texture* tex, const Rect& dest, static RenderCommand makeSprite(const Texture *tex, const Rect &dest,
const Rect& src, const Color& tint, const Rect &src, const Color &tint,
float rot = 0.0f, const Vec2& anc = Vec2(0, 0), float rot = 0.0f,
uint32_t lyr = 0); const Vec2 &anc = Vec2(0, 0),
static RenderCommand makeLine(const Vec2& s, const Vec2& e, const Color& c, uint32_t lyr = 0);
float w = 1.0f, uint32_t lyr = 0); static RenderCommand makeLine(const Vec2 &s, const Vec2 &e, const Color &c,
static RenderCommand makeRect(const Rect& r, const Color& c, float w = 1.0f, uint32_t lyr = 0);
float w = 1.0f, bool fill = false, uint32_t lyr = 0); static RenderCommand makeRect(const Rect &r, const Color &c, float w = 1.0f,
bool fill = false, uint32_t lyr = 0);
}; };
/** /**
@ -184,41 +186,41 @@ class RenderCommandBuffer {
public: public:
static constexpr size_t INITIAL_CAPACITY = 1024; static constexpr size_t INITIAL_CAPACITY = 1024;
static constexpr size_t MAX_CAPACITY = 65536; static constexpr size_t MAX_CAPACITY = 65536;
RenderCommandBuffer(); RenderCommandBuffer();
~RenderCommandBuffer(); ~RenderCommandBuffer();
// 添加渲染命令 // 添加渲染命令
void addCommand(const RenderCommand& cmd); void addCommand(const RenderCommand &cmd);
void addCommand(RenderCommand&& cmd); void addCommand(RenderCommand &&cmd);
// 批量添加(预留空间后使用) // 批量添加(预留空间后使用)
RenderCommand& emplaceCommand(); RenderCommand &emplaceCommand();
// 排序命令(按纹理、层级等) // 排序命令(按纹理、层级等)
void sortCommands(); void sortCommands();
// 清空缓冲区 // 清空缓冲区
void clear(); void clear();
// 获取命令列表 // 获取命令列表
const std::vector<RenderCommand>& getCommands() const { return commands_; } const std::vector<RenderCommand> &getCommands() const { return commands_; }
std::vector<RenderCommand>& getCommands() { return commands_; } std::vector<RenderCommand> &getCommands() { return commands_; }
// 统计 // 统计
size_t size() const { return commands_.size(); } size_t size() const { return commands_.size(); }
bool empty() const { return commands_.empty(); } bool empty() const { return commands_.empty(); }
size_t capacity() const { return commands_.capacity(); } size_t capacity() const { return commands_.capacity(); }
// 预分配空间 // 预分配空间
void reserve(size_t capacity); void reserve(size_t capacity);
private: private:
std::vector<RenderCommand> commands_; std::vector<RenderCommand> commands_;
uint32_t nextOrder_; uint32_t nextOrder_;
// 排序比较函数 // 排序比较函数
static bool compareCommands(const RenderCommand& a, const RenderCommand& b); static bool compareCommands(const RenderCommand &a, const RenderCommand &b);
}; };
} // namespace extra2d } // namespace extra2d

View File

@ -1,319 +0,0 @@
#pragma once
#include <graphics/opengl/gl_shader.h>
#include <core/types.h>
#include <core/color.h>
#include <glm/vec4.hpp>
namespace extra2d {
struct WaterParams {
float waveSpeed = 1.0f;
float waveAmplitude = 0.02f;
float waveFrequency = 4.0f;
};
struct OutlineParams {
Color color = Colors::Black;
float thickness = 2.0f;
};
struct DistortionParams {
float distortionAmount = 0.02f;
float timeScale = 1.0f;
};
struct PixelateParams {
float pixelSize = 8.0f;
};
struct InvertParams {
float strength = 1.0f;
};
struct GrayscaleParams {
float intensity = 1.0f;
};
struct BlurParams {
float radius = 5.0f;
};
namespace ShaderSource {
static const char* StandardVert = R"(
#version 300 es
precision highp float;
layout(location = 0) in vec2 a_position;
layout(location = 1) in vec2 a_texCoord;
layout(location = 2) in vec4 a_color;
uniform mat4 u_viewProjection;
uniform mat4 u_model;
out vec2 v_texCoord;
out vec4 v_color;
void main() {
gl_Position = u_viewProjection * u_model * vec4(a_position, 0.0, 1.0);
v_texCoord = a_texCoord;
v_color = a_color;
}
)";
static const char* StandardFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
in vec4 v_color;
uniform sampler2D u_texture;
uniform float u_opacity;
out vec4 fragColor;
void main() {
vec4 texColor = texture(u_texture, v_texCoord);
fragColor = texColor * v_color;
fragColor.a *= u_opacity;
if (fragColor.a < 0.01) {
discard;
}
}
)";
static const char* WaterFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
in vec4 v_color;
uniform sampler2D u_texture;
uniform float u_waveSpeed;
uniform float u_waveAmplitude;
uniform float u_waveFrequency;
uniform float u_time;
out vec4 fragColor;
void main() {
vec2 uv = v_texCoord;
// 水波纹效果
float wave = sin(uv.y * u_waveFrequency + u_time * u_waveSpeed) * u_waveAmplitude;
uv.x += wave;
vec4 texColor = texture(u_texture, uv);
fragColor = texColor * v_color;
if (fragColor.a < 0.01) {
discard;
}
}
)";
static const char* OutlineFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
in vec4 v_color;
uniform sampler2D u_texture;
uniform vec4 u_outlineColor;
uniform float u_thickness;
uniform vec2 u_textureSize;
out vec4 fragColor;
void main() {
vec4 color = texture(u_texture, v_texCoord);
// 简单的描边检测
float alpha = 0.0;
vec2 offset = u_thickness / u_textureSize;
alpha += texture(u_texture, v_texCoord + vec2(-offset.x, 0.0)).a;
alpha += texture(u_texture, v_texCoord + vec2(offset.x, 0.0)).a;
alpha += texture(u_texture, v_texCoord + vec2(0.0, -offset.y)).a;
alpha += texture(u_texture, v_texCoord + vec2(0.0, offset.y)).a;
if (color.a < 0.1 && alpha > 0.0) {
fragColor = u_outlineColor;
} else {
fragColor = color;
}
if (fragColor.a < 0.01) {
discard;
}
}
)";
static const char* DistortionFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
in vec4 v_color;
uniform sampler2D u_texture;
uniform float u_distortionAmount;
uniform float u_time;
uniform float u_timeScale;
out vec4 fragColor;
void main() {
vec2 uv = v_texCoord;
// 扭曲效果
float t = u_time * u_timeScale;
float dx = sin(uv.y * 10.0 + t) * u_distortionAmount;
float dy = cos(uv.x * 10.0 + t) * u_distortionAmount;
uv += vec2(dx, dy);
vec4 texColor = texture(u_texture, uv);
fragColor = texColor * v_color;
if (fragColor.a < 0.01) {
discard;
}
}
)";
static const char* PixelateFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
in vec4 v_color;
uniform sampler2D u_texture;
uniform float u_pixelSize;
uniform vec2 u_textureSize;
uniform float u_opacity;
out vec4 fragColor;
void main() {
vec2 pixel = u_pixelSize / u_textureSize;
vec2 uv = floor(v_texCoord / pixel) * pixel + pixel * 0.5;
vec4 texColor = texture(u_texture, uv);
fragColor = texColor * v_color;
fragColor.a *= u_opacity;
if (fragColor.a < 0.01) {
discard;
}
}
)";
static const char* InvertFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
in vec4 v_color;
uniform sampler2D u_texture;
uniform float u_strength;
uniform float u_opacity;
out vec4 fragColor;
void main() {
vec4 texColor = texture(u_texture, v_texCoord) * v_color;
vec3 inverted = vec3(1.0) - texColor.rgb;
texColor.rgb = mix(texColor.rgb, inverted, u_strength);
fragColor = texColor;
fragColor.a *= u_opacity;
if (fragColor.a < 0.01) {
discard;
}
}
)";
static const char* GrayscaleFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
in vec4 v_color;
uniform sampler2D u_texture;
uniform float u_intensity;
uniform float u_opacity;
out vec4 fragColor;
void main() {
vec4 texColor = texture(u_texture, v_texCoord) * v_color;
float gray = dot(texColor.rgb, vec3(0.299, 0.587, 0.114));
texColor.rgb = mix(texColor.rgb, vec3(gray), u_intensity);
fragColor = texColor;
fragColor.a *= u_opacity;
if (fragColor.a < 0.01) {
discard;
}
}
)";
static const char* BlurFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
in vec4 v_color;
uniform sampler2D u_texture;
uniform float u_radius;
uniform vec2 u_textureSize;
uniform float u_opacity;
out vec4 fragColor;
void main() {
vec2 texel = u_radius / u_textureSize;
vec4 sum = vec4(0.0);
sum += texture(u_texture, v_texCoord + texel * vec2(-1.0, -1.0));
sum += texture(u_texture, v_texCoord + texel * vec2( 0.0, -1.0));
sum += texture(u_texture, v_texCoord + texel * vec2( 1.0, -1.0));
sum += texture(u_texture, v_texCoord + texel * vec2(-1.0, 0.0));
sum += texture(u_texture, v_texCoord + texel * vec2( 0.0, 0.0));
sum += texture(u_texture, v_texCoord + texel * vec2( 1.0, 0.0));
sum += texture(u_texture, v_texCoord + texel * vec2(-1.0, 1.0));
sum += texture(u_texture, v_texCoord + texel * vec2( 0.0, 1.0));
sum += texture(u_texture, v_texCoord + texel * vec2( 1.0, 1.0));
vec4 texColor = sum / 9.0;
fragColor = texColor * v_color;
fragColor.a *= u_opacity;
if (fragColor.a < 0.01) {
discard;
}
}
)";
} // namespace ShaderSource
class ShaderPreset {
public:
static Ptr<GLShader> Water(const WaterParams& params);
static Ptr<GLShader> Outline(const OutlineParams& params);
static Ptr<GLShader> Distortion(const DistortionParams& params);
static Ptr<GLShader> Pixelate(const PixelateParams& params);
static Ptr<GLShader> Invert(const InvertParams& params);
static Ptr<GLShader> Grayscale(const GrayscaleParams& params);
static Ptr<GLShader> Blur(const BlurParams& params);
static Ptr<GLShader> GrayscaleOutline(const GrayscaleParams& grayParams,
const OutlineParams& outlineParams);
static Ptr<GLShader> PixelateInvert(const PixelateParams& pixParams,
const InvertParams& invParams);
};
} // namespace extra2d

View File

@ -1,231 +0,0 @@
#include <renderer/shader_preset.h>
#include <utils/logger.h>
namespace extra2d {
// ============================================================================
// ShaderPreset实现
// ============================================================================
Ptr<GLShader> ShaderPreset::Water(const WaterParams &params) {
auto shader = std::make_shared<GLShader>();
if (!shader->compileFromSource(ShaderSource::StandardVert,
ShaderSource::WaterFrag)) {
E2D_ERROR("编译水波纹Shader失败");
return nullptr;
}
// 设置默认参数
shader->setFloat("u_waveSpeed", params.waveSpeed);
shader->setFloat("u_waveAmplitude", params.waveAmplitude);
shader->setFloat("u_waveFrequency", params.waveFrequency);
E2D_INFO("创建水波纹Shader预设");
return shader;
}
Ptr<GLShader> ShaderPreset::Outline(const OutlineParams &params) {
auto shader = std::make_shared<GLShader>();
if (!shader->compileFromSource(ShaderSource::StandardVert,
ShaderSource::OutlineFrag)) {
E2D_ERROR("编译描边Shader失败");
return nullptr;
}
// 设置默认参数
shader->setVec4("u_outlineColor", glm::vec4(params.color.r, params.color.g,
params.color.b, params.color.a));
shader->setFloat("u_thickness", params.thickness);
E2D_INFO("创建描边Shader预设");
return shader;
}
Ptr<GLShader> ShaderPreset::Distortion(const DistortionParams &params) {
auto shader = std::make_shared<GLShader>();
if (!shader->compileFromSource(ShaderSource::StandardVert,
ShaderSource::DistortionFrag)) {
E2D_ERROR("编译扭曲Shader失败");
return nullptr;
}
// 设置默认参数
shader->setFloat("u_distortionAmount", params.distortionAmount);
shader->setFloat("u_timeScale", params.timeScale);
E2D_INFO("创建扭曲Shader预设");
return shader;
}
Ptr<GLShader> ShaderPreset::Pixelate(const PixelateParams &params) {
auto shader = std::make_shared<GLShader>();
if (!shader->compileFromSource(ShaderSource::StandardVert,
ShaderSource::PixelateFrag)) {
E2D_ERROR("编译像素化Shader失败");
return nullptr;
}
// 设置默认参数
shader->setFloat("u_pixelSize", params.pixelSize);
E2D_INFO("创建像素化Shader预设");
return shader;
}
Ptr<GLShader> ShaderPreset::Invert(const InvertParams &params) {
auto shader = std::make_shared<GLShader>();
if (!shader->compileFromSource(ShaderSource::StandardVert,
ShaderSource::InvertFrag)) {
E2D_ERROR("编译反相Shader失败");
return nullptr;
}
// 设置默认参数
shader->setFloat("u_strength", params.strength);
E2D_INFO("创建反相Shader预设");
return shader;
}
Ptr<GLShader> ShaderPreset::Grayscale(const GrayscaleParams &params) {
auto shader = std::make_shared<GLShader>();
if (!shader->compileFromSource(ShaderSource::StandardVert,
ShaderSource::GrayscaleFrag)) {
E2D_ERROR("编译灰度Shader失败");
return nullptr;
}
// 设置默认参数
shader->setFloat("u_intensity", params.intensity);
E2D_INFO("创建灰度Shader预设");
return shader;
}
Ptr<GLShader> ShaderPreset::Blur(const BlurParams &params) {
auto shader = std::make_shared<GLShader>();
if (!shader->compileFromSource(ShaderSource::StandardVert,
ShaderSource::BlurFrag)) {
E2D_ERROR("编译模糊Shader失败");
return nullptr;
}
// 设置默认参数
shader->setFloat("u_radius", params.radius);
E2D_INFO("创建模糊Shader预设");
return shader;
}
Ptr<GLShader>
ShaderPreset::GrayscaleOutline(const GrayscaleParams &grayParams,
const OutlineParams &outlineParams) {
// 创建组合效果的片段着色器 (GLES 3.2)
const char *combinedFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
uniform sampler2D u_texture;
uniform float u_grayIntensity;
uniform vec4 u_outlineColor;
uniform float u_thickness;
uniform vec2 u_textureSize;
out vec4 fragColor;
void main() {
vec4 color = texture(u_texture, v_texCoord);
// 灰度效果
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
color.rgb = mix(color.rgb, vec3(gray), u_grayIntensity);
// 描边效果
float alpha = 0.0;
vec2 offset = u_thickness / u_textureSize;
alpha += texture(u_texture, v_texCoord + vec2(-offset.x, 0.0)).a;
alpha += texture(u_texture, v_texCoord + vec2(offset.x, 0.0)).a;
alpha += texture(u_texture, v_texCoord + vec2(0.0, -offset.y)).a;
alpha += texture(u_texture, v_texCoord + vec2(0.0, offset.y)).a;
if (color.a < 0.1 && alpha > 0.0) {
fragColor = u_outlineColor;
} else {
fragColor = color;
}
}
)";
auto shader = std::make_shared<GLShader>();
if (!shader->compileFromSource(ShaderSource::StandardVert, combinedFrag)) {
E2D_ERROR("编译灰度+描边Shader失败");
return nullptr;
}
// 设置默认参数
shader->setFloat("u_grayIntensity", grayParams.intensity);
shader->setVec4("u_outlineColor",
glm::vec4(outlineParams.color.r, outlineParams.color.g,
outlineParams.color.b, outlineParams.color.a));
shader->setFloat("u_thickness", outlineParams.thickness);
E2D_INFO("创建灰度+描边组合Shader预设");
return shader;
}
Ptr<GLShader> ShaderPreset::PixelateInvert(const PixelateParams &pixParams,
const InvertParams &invParams) {
// 创建组合效果的片段着色器 (GLES 3.2)
const char *combinedFrag = R"(
#version 300 es
precision highp float;
in vec2 v_texCoord;
uniform sampler2D u_texture;
uniform float u_pixelSize;
uniform vec2 u_textureSize;
uniform float u_invertStrength;
out vec4 fragColor;
void main() {
// 像素化
vec2 pixel = u_pixelSize / u_textureSize;
vec2 uv = floor(v_texCoord / pixel) * pixel + pixel * 0.5;
vec4 color = texture(u_texture, uv);
// 反相
vec3 inverted = 1.0 - color.rgb;
color.rgb = mix(color.rgb, inverted, u_invertStrength);
fragColor = color;
}
)";
auto shader = std::make_shared<GLShader>();
if (!shader->compileFromSource(ShaderSource::StandardVert, combinedFrag)) {
E2D_ERROR("编译像素化+反相Shader失败");
return nullptr;
}
// 设置默认参数
shader->setFloat("u_pixelSize", pixParams.pixelSize);
shader->setFloat("u_invertStrength", invParams.strength);
E2D_INFO("创建像素化+反相组合Shader预设");
return shader;
}
} // namespace extra2d

View File

@ -1,9 +1,10 @@
#include <core/color.h> #include <core/color.h>
#include <renderer/shader_system.h>
#include <utils/logger.h>
#include <fstream> #include <fstream>
#include <renderer/shader.h>
#include <sstream> #include <sstream>
#include <sys/stat.h> #include <sys/stat.h>
#include <utils/logger.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>