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