Frostbite2D/Fostbite2D/include/fostbite2D/render/opengl/gl_renderer.h

317 lines
8.1 KiB
C
Raw Normal View History

2026-02-17 13:28:38 +08:00
#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 truefalse
*/
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 &center, float radius, const Color &color,
int segments, float width);
/**
* @brief
* @param center
* @param radius
* @param color
* @param segments
*/
void fillCircle(const Vec2 &center, 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