317 lines
8.1 KiB
C
317 lines
8.1 KiB
C
|
|
#pragma once
|
|||
|
|
|
|||
|
|
#include <fostbite2D/core/color.h>
|
|||
|
|
#include <fostbite2D/core/math_types.h>
|
|||
|
|
#include <fostbite2D/core/types.h>
|
|||
|
|
#include <fostbite2D/render/font.h>
|
|||
|
|
#include <fostbite2D/render/opengl/gl_sprite_batch.h>
|
|||
|
|
#include <fostbite2D/render/shader/shader_interface.h>
|
|||
|
|
#include <fostbite2D/render/texture.h>
|
|||
|
|
|
|||
|
|
#include <array>
|
|||
|
|
#include <glad/glad.h>
|
|||
|
|
#include <vector>
|
|||
|
|
|
|||
|
|
struct SDL_Window;
|
|||
|
|
|
|||
|
|
namespace frostbite2D {
|
|||
|
|
|
|||
|
|
// 混合模式枚举
|
|||
|
|
enum class BlendMode { None, Alpha, Additive, Multiply };
|
|||
|
|
|
|||
|
|
// 渲染统计信息
|
|||
|
|
struct RenderStats {
|
|||
|
|
uint32_t drawCalls = 0;
|
|||
|
|
uint32_t triangleCount = 0;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// ============================================================================
|
|||
|
|
// OpenGL 渲染器实现
|
|||
|
|
// ============================================================================
|
|||
|
|
class GLRenderer {
|
|||
|
|
public:
|
|||
|
|
GLRenderer();
|
|||
|
|
~GLRenderer();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 初始化OpenGL渲染器
|
|||
|
|
* @param window SDL窗口指针
|
|||
|
|
* @return 初始化成功返回true,失败返回false
|
|||
|
|
*/
|
|||
|
|
bool init(SDL_Window *window);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 关闭渲染器,释放所有GPU资源
|
|||
|
|
*/
|
|||
|
|
void shutdown();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 开始新帧,清除颜色缓冲区并重置统计信息
|
|||
|
|
* @param clearColor 清屏颜色
|
|||
|
|
*/
|
|||
|
|
void beginFrame(const Color &clearColor);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 结束当前帧,刷新所有待处理的渲染批次
|
|||
|
|
*/
|
|||
|
|
void endFrame();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 设置视口区域
|
|||
|
|
* @param x 视口左下角X坐标
|
|||
|
|
* @param y 视口左下角Y坐标
|
|||
|
|
* @param width 视口宽度
|
|||
|
|
* @param height 视口高度
|
|||
|
|
*/
|
|||
|
|
void setViewport(int x, int y, int width, int height);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 设置垂直同步
|
|||
|
|
* @param enabled true启用垂直同步,false禁用
|
|||
|
|
*/
|
|||
|
|
void setVSync(bool enabled);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 设置混合模式
|
|||
|
|
* @param mode 混合模式枚举值
|
|||
|
|
*/
|
|||
|
|
void setBlendMode(BlendMode mode);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 设置视图投影矩阵
|
|||
|
|
* @param matrix 4x4视图投影矩阵
|
|||
|
|
*/
|
|||
|
|
void setViewProjection(const glm::mat4 &matrix);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 压入变换矩阵到变换栈
|
|||
|
|
* @param transform 变换矩阵
|
|||
|
|
*/
|
|||
|
|
void pushTransform(const glm::mat4 &transform);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 从变换栈弹出顶部变换矩阵
|
|||
|
|
*/
|
|||
|
|
void popTransform();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 获取当前累积的变换矩阵
|
|||
|
|
* @return 当前变换矩阵,如果栈为空则返回单位矩阵
|
|||
|
|
*/
|
|||
|
|
glm::mat4 getCurrentTransform() const;
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 创建纹理对象
|
|||
|
|
* @param width 纹理宽度
|
|||
|
|
* @param height 纹理高度
|
|||
|
|
* @param pixels 像素数据指针
|
|||
|
|
* @param channels 颜色通道数
|
|||
|
|
* @return 创建的纹理智能指针
|
|||
|
|
*/
|
|||
|
|
Ptr<Texture> createTexture(int width, int height, const uint8_t *pixels,
|
|||
|
|
int channels);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 从文件加载纹理
|
|||
|
|
* @param filepath 纹理文件路径
|
|||
|
|
* @return 加载的纹理智能指针
|
|||
|
|
*/
|
|||
|
|
Ptr<Texture> loadTexture(const std::string &filepath);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 开始精灵批处理
|
|||
|
|
*/
|
|||
|
|
void beginSpriteBatch();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 绘制精灵(带完整参数)
|
|||
|
|
* @param texture 纹理引用
|
|||
|
|
* @param destRect 目标矩形(屏幕坐标)
|
|||
|
|
* @param srcRect 源矩形(纹理坐标)
|
|||
|
|
* @param tint 着色颜色
|
|||
|
|
* @param rotation 旋转角度(度)
|
|||
|
|
* @param anchor 锚点位置(0-1范围)
|
|||
|
|
*/
|
|||
|
|
void drawSprite(const Texture &texture, const Rect &destRect,
|
|||
|
|
const Rect &srcRect, const Color &tint, float rotation,
|
|||
|
|
const Vec2 &anchor);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 绘制精灵(简化版本)
|
|||
|
|
* @param texture 纹理引用
|
|||
|
|
* @param position 绘制位置
|
|||
|
|
* @param tint 着色颜色
|
|||
|
|
*/
|
|||
|
|
void drawSprite(const Texture &texture, const Vec2 &position,
|
|||
|
|
const Color &tint);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 结束精灵批处理并提交绘制
|
|||
|
|
*/
|
|||
|
|
void endSpriteBatch();
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 绘制线段
|
|||
|
|
* @param start 起点坐标
|
|||
|
|
* @param end 终点坐标
|
|||
|
|
* @param color 线条颜色
|
|||
|
|
* @param width 线条宽度
|
|||
|
|
*/
|
|||
|
|
void drawLine(const Vec2 &start, const Vec2 &end, const Color &color,
|
|||
|
|
float width);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 绘制矩形边框
|
|||
|
|
* @param rect 矩形区域
|
|||
|
|
* @param color 边框颜色
|
|||
|
|
* @param width 线条宽度
|
|||
|
|
*/
|
|||
|
|
void drawRect(const Rect &rect, const Color &color, float width);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 填充矩形
|
|||
|
|
* @param rect 矩形区域
|
|||
|
|
* @param color 填充颜色
|
|||
|
|
*/
|
|||
|
|
void fillRect(const Rect &rect, const Color &color);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 绘制圆形边框
|
|||
|
|
* @param center 圆心坐标
|
|||
|
|
* @param radius 半径
|
|||
|
|
* @param color 边框颜色
|
|||
|
|
* @param segments 分段数
|
|||
|
|
* @param width 线条宽度
|
|||
|
|
*/
|
|||
|
|
void drawCircle(const Vec2 ¢er, float radius, const Color &color,
|
|||
|
|
int segments, float width);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 填充圆形
|
|||
|
|
* @param center 圆心坐标
|
|||
|
|
* @param radius 半径
|
|||
|
|
* @param color 填充颜色
|
|||
|
|
* @param segments 分段数
|
|||
|
|
*/
|
|||
|
|
void fillCircle(const Vec2 ¢er, float radius, const Color &color,
|
|||
|
|
int segments);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 绘制三角形边框
|
|||
|
|
* @param p1 第一个顶点
|
|||
|
|
* @param p2 第二个顶点
|
|||
|
|
* @param p3 第三个顶点
|
|||
|
|
* @param color 边框颜色
|
|||
|
|
* @param width 线条宽度
|
|||
|
|
*/
|
|||
|
|
void drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
|
|||
|
|
const Color &color, float width);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 填充三角形
|
|||
|
|
* @param p1 第一个顶点
|
|||
|
|
* @param p2 第二个顶点
|
|||
|
|
* @param p3 第三个顶点
|
|||
|
|
* @param color 填充颜色
|
|||
|
|
*/
|
|||
|
|
void fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
|
|||
|
|
const Color &color);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 绘制多边形边框
|
|||
|
|
* @param points 顶点数组
|
|||
|
|
* @param color 边框颜色
|
|||
|
|
* @param width 线条宽度
|
|||
|
|
*/
|
|||
|
|
void drawPolygon(const std::vector<Vec2> &points, const Color &color,
|
|||
|
|
float width);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 填充多边形
|
|||
|
|
* @param points 顶点数组
|
|||
|
|
* @param color 填充颜色
|
|||
|
|
*/
|
|||
|
|
void fillPolygon(const std::vector<Vec2> &points, const Color &color);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 绘制文本
|
|||
|
|
* @param font 字体图集引用
|
|||
|
|
* @param text 文本内容
|
|||
|
|
* @param position 绘制位置
|
|||
|
|
* @param color 文本颜色
|
|||
|
|
*/
|
|||
|
|
void drawText(const FontAtlas &font, const std::string &text,
|
|||
|
|
const Vec2 &position, const Color &color);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 绘制文本(使用浮点坐标)
|
|||
|
|
* @param font 字体图集引用
|
|||
|
|
* @param text 文本内容
|
|||
|
|
* @param x X坐标
|
|||
|
|
* @param y Y坐标
|
|||
|
|
* @param color 文本颜色
|
|||
|
|
*/
|
|||
|
|
void drawText(const FontAtlas &font, const std::string &text, float x,
|
|||
|
|
float y, const Color &color);
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 获取渲染统计信息
|
|||
|
|
* @return 渲染统计信息
|
|||
|
|
*/
|
|||
|
|
RenderStats getStats() const { return stats_; }
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @brief 重置渲染统计信息
|
|||
|
|
*/
|
|||
|
|
void resetStats();
|
|||
|
|
|
|||
|
|
private:
|
|||
|
|
// 形状批处理常量
|
|||
|
|
static constexpr size_t MAX_CIRCLE_SEGMENTS = 128;
|
|||
|
|
static constexpr size_t MAX_SHAPE_VERTICES = 8192; // 最大形状顶点数
|
|||
|
|
static constexpr size_t MAX_LINE_VERTICES = 16384; // 最大线条顶点数
|
|||
|
|
|
|||
|
|
// 形状顶点结构(包含颜色)
|
|||
|
|
struct ShapeVertex {
|
|||
|
|
float x, y;
|
|||
|
|
float r, g, b, a;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
SDL_Window *window_;
|
|||
|
|
GLSpriteBatch spriteBatch_;
|
|||
|
|
Ptr<IShader> shapeShader_;
|
|||
|
|
|
|||
|
|
GLuint shapeVao_;
|
|||
|
|
GLuint shapeVbo_;
|
|||
|
|
GLuint lineVao_; // 线条专用 VAO
|
|||
|
|
GLuint lineVbo_; // 线条专用 VBO
|
|||
|
|
|
|||
|
|
glm::mat4 viewProjection_;
|
|||
|
|
std::vector<glm::mat4> transformStack_;
|
|||
|
|
RenderStats stats_;
|
|||
|
|
bool vsync_;
|
|||
|
|
|
|||
|
|
// 形状批处理缓冲区(预分配,避免每帧内存分配)
|
|||
|
|
std::array<ShapeVertex, MAX_SHAPE_VERTICES> shapeVertexCache_;
|
|||
|
|
size_t shapeVertexCount_ = 0;
|
|||
|
|
GLenum currentShapeMode_ = GL_TRIANGLES;
|
|||
|
|
|
|||
|
|
// 线条批处理缓冲区
|
|||
|
|
std::array<ShapeVertex, MAX_LINE_VERTICES> lineVertexCache_;
|
|||
|
|
size_t lineVertexCount_ = 0;
|
|||
|
|
float currentLineWidth_ = 1.0f;
|
|||
|
|
|
|||
|
|
// OpenGL 状态缓存
|
|||
|
|
BlendMode cachedBlendMode_ = BlendMode::None;
|
|||
|
|
bool blendEnabled_ = false;
|
|||
|
|
|
|||
|
|
void initShapeRendering();
|
|||
|
|
void flushShapeBatch();
|
|||
|
|
void flushLineBatch();
|
|||
|
|
void addShapeVertex(float x, float y, const Color &color);
|
|||
|
|
void addLineVertex(float x, float y, const Color &color);
|
|||
|
|
void submitShapeBatch(GLenum mode);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
} // namespace frostbite2D
|