Extra2D/Extra2D/include/extra2d/graphics/opengl/gl_renderer.h

185 lines
6.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/graphics/opengl/gl_buffer.h>
#include <extra2d/graphics/opengl/gl_framebuffer.h>
#include <extra2d/graphics/opengl/gl_pipeline.h>
#include <extra2d/graphics/opengl/gl_sprite_batch.h>
#include <extra2d/graphics/shader/shader_interface.h>
#include <array>
#include <glad/glad.h>
#include <vector>
namespace extra2d {
// 前向声明
class GLFWWindow;
class GLContext;
class GLFramebuffer;
// ============================================================================
// OpenGL 渲染器实现
// ============================================================================
class GLRenderer : public RenderBackend {
public:
GLRenderer();
~GLRenderer() override;
// RenderBackend 接口实现
bool init(GLFWWindow *window) override;
void shutdown() override;
void beginFrame(const Color &clearColor) override;
void endFrame() override;
void setViewport(int x, int y, int width, int height) override;
void setVSync(bool enabled) override;
void setBlendMode(BlendMode mode) override;
void setViewProjection(const glm::mat4 &matrix) override;
// 变换矩阵栈
void pushTransform(const glm::mat4 &transform) override;
void popTransform() override;
glm::mat4 getCurrentTransform() const override;
Ptr<Texture> createTexture(int width, int height, const uint8_t *pixels,
int channels) override;
Ptr<Texture> loadTexture(const std::string &filepath) override;
void beginSpriteBatch() override;
void drawSprite(const Texture &texture, const Rect &destRect,
const Rect &srcRect, const Color &tint, float rotation,
const Vec2 &anchor) override;
void drawSprite(const Texture &texture, const Vec2 &position,
const Color &tint) override;
void endSpriteBatch() override;
void flush() override;
void drawLine(const Vec2 &start, const Vec2 &end, const Color &color,
float width) override;
void drawRect(const Rect &rect, const Color &color, float width) override;
void fillRect(const Rect &rect, const Color &color) override;
void drawCircle(const Vec2 &center, float radius, const Color &color,
int segments, float width) override;
void fillCircle(const Vec2 &center, float radius, const Color &color,
int segments) override;
void drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
const Color &color, float width) override;
void fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
const Color &color) override;
void drawPolygon(const std::vector<Vec2> &points, const Color &color,
float width) override;
void fillPolygon(const std::vector<Vec2> &points,
const Color &color) override;
Ptr<FontAtlas> createFontAtlas(const std::string &filepath, int fontSize,
bool useSDF = false) override;
void drawText(const FontAtlas &font, const std::string &text,
const Vec2 &position, const Color &color) override;
void drawText(const FontAtlas &font, const std::string &text, float x,
float y, const Color &color) override;
Stats getStats() const override { return stats_; }
void resetStats() override;
// GLFramebuffer 相关方法
/**
* @brief 创建帧缓冲对象
* @param desc 帧缓冲描述
* @return 创建的帧缓冲智能指针
*/
Ptr<GLFramebuffer> createFramebuffer(const FramebufferDesc &desc);
/**
* @brief 绑定帧缓冲(作为渲染目标)
* @param framebuffer 帧缓冲对象指针,传入 nullptr 则绑定默认帧缓冲
*/
void bindFramebuffer(GLFramebuffer *framebuffer);
/**
* @brief 解绑帧缓冲(恢复到默认帧缓冲)
*/
void unbindFramebuffer();
/**
* @brief 获取默认帧缓冲
* @return 默认帧缓冲智能指针
*/
Ptr<GLFramebuffer> getDefaultFramebuffer() const;
/**
* @brief 清除当前绑定的帧缓冲
* @param color 清除颜色
* @param clearColor 是否清除颜色缓冲
* @param clearDepth 是否清除深度缓冲
* @param clearStencil 是否清除模板缓冲
*/
void clearFramebuffer(const Color &color, bool clearColor = true,
bool clearDepth = true, bool clearStencil = false);
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;
};
GLFWWindow *window_;
GLSpriteBatch spriteBatch_;
Ptr<IShader> shapeShader_;
Ptr<IShader> sdfFontShader_; // SDF字体专用着色器
GLuint shapeVao_; // 形状 VAO手动管理用于顶点属性配置
GLBuffer shapeBuffer_; // 形状 VBO使用 GLBuffer 管理)
GLuint lineVao_; // 线条 VAO手动管理用于顶点属性配置
GLBuffer lineBuffer_; // 线条 VBO使用 GLBuffer 管理)
glm::mat4 viewProjection_;
std::vector<glm::mat4> transformStack_;
Stats 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 管线状态管理
GLPipeline pipeline_;
// 自动批处理状态
bool batchActive_ = false; // 批处理是否激活
bool autoBatchEnabled_ = true; // 是否启用自动批处理
const Texture *currentBatchTexture_ = nullptr; // 当前批处理的纹理
std::vector<SpriteData> pendingSprites_; // 待提交的精灵
static constexpr size_t MAX_BATCH_SPRITES = 1000; // 最大批处理精灵数
// 帧缓冲管理
mutable Ptr<GLFramebuffer> defaultFramebuffer_; // 默认帧缓冲(延迟创建)
GLFramebuffer *currentFramebuffer_ = nullptr; // 当前绑定的帧缓冲
void initShapeRendering();
void ensureBatchActive(); // 确保批处理已激活
void submitPendingSprites(); // 提交待处理的精灵
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 extra2d