Extra2D/include/graphics/opengl/gl_sprite_batch.h

98 lines
2.4 KiB
C
Raw Normal View History

2026-02-11 19:40:26 +08:00
#pragma once
#include <core/color.h>
#include <core/math_types.h>
#include <core/types.h>
#include <graphics/opengl/gl_shader.h>
#include <graphics/texture.h>
2026-02-11 19:40:26 +08:00
#include <glm/mat4x4.hpp>
#include <vector>
#include <array>
2026-02-11 19:40:26 +08:00
#include <glad/glad.h>
namespace extra2d {
// ============================================================================
// OpenGL 精灵批渲染器 - 优化版本
2026-02-11 19:40:26 +08:00
// ============================================================================
class GLSpriteBatch {
public:
static constexpr size_t MAX_SPRITES = 10000;
static constexpr size_t VERTICES_PER_SPRITE = 4;
static constexpr size_t INDICES_PER_SPRITE = 6;
static constexpr size_t MAX_VERTICES = MAX_SPRITES * VERTICES_PER_SPRITE;
static constexpr size_t MAX_INDICES = MAX_SPRITES * INDICES_PER_SPRITE;
2026-02-11 19:40:26 +08:00
struct Vertex {
glm::vec2 position;
glm::vec2 texCoord;
glm::vec4 color;
};
struct SpriteData {
glm::vec2 position;
glm::vec2 size;
glm::vec2 texCoordMin;
glm::vec2 texCoordMax;
glm::vec4 color;
float rotation;
glm::vec2 anchor;
bool isSDF = false;
};
GLSpriteBatch();
~GLSpriteBatch();
bool init();
void shutdown();
void begin(const glm::mat4 &viewProjection);
void draw(const Texture &texture, const SpriteData &data);
void end();
// 批量绘制接口 - 用于自动批处理
void drawBatch(const Texture& texture, const std::vector<SpriteData>& sprites);
// 立即绘制(不缓存)
void drawImmediate(const Texture& texture, const SpriteData& data);
2026-02-11 19:40:26 +08:00
// 统计
uint32_t getDrawCallCount() const { return drawCallCount_; }
uint32_t getSpriteCount() const { return spriteCount_; }
uint32_t getBatchCount() const { return batchCount_; }
// 检查是否需要刷新
bool needsFlush(const Texture& texture, bool isSDF) const;
2026-02-11 19:40:26 +08:00
private:
GLuint vao_;
GLuint vbo_;
GLuint ibo_;
GLShader shader_;
// 使用固定大小数组减少内存分配
std::array<Vertex, MAX_VERTICES> vertexBuffer_;
size_t vertexCount_;
2026-02-11 19:40:26 +08:00
const Texture *currentTexture_;
bool currentIsSDF_;
glm::mat4 viewProjection_;
// 缓存上一帧的 viewProjection避免重复设置
glm::mat4 cachedViewProjection_;
bool viewProjectionDirty_ = true;
2026-02-11 19:40:26 +08:00
uint32_t drawCallCount_;
uint32_t spriteCount_;
uint32_t batchCount_;
2026-02-11 19:40:26 +08:00
void flush();
void setupShader();
// 添加顶点到缓冲区
void addVertices(const SpriteData& data);
2026-02-11 19:40:26 +08:00
};
} // namespace extra2d