refactor(渲染器): 将RenderBackend重命名为Renderer并重构相关代码

重构渲染器接口命名,将RenderBackend统一更名为Renderer,同时更新所有相关文件和文档引用。此变更旨在提供更简洁清晰的接口命名,并保持代码一致性。

- 重命名RenderBackend类为Renderer
- 更新所有相关文件中的类型引用和文档
- 保持原有功能不变,仅进行命名和结构调整
- 修复因重命名导致的编译错误和警告
This commit is contained in:
ChestnutYueyue 2026-02-20 15:04:21 +08:00
parent b34df8bdd1
commit 9e911db53c
40 changed files with 749 additions and 914 deletions

View File

@ -9,7 +9,7 @@
namespace extra2d { namespace extra2d {
class GLFWWindow; class GLFWWindow;
class RenderBackend; class Renderer;
class WindowModule; class WindowModule;
class RenderModule; class RenderModule;
@ -91,7 +91,7 @@ public:
* @brief * @brief
* @return * @return
*/ */
RenderBackend *renderer(); Renderer *renderer();
/** /**
* @brief * @brief

View File

@ -20,10 +20,10 @@
// Graphics // Graphics
#include <extra2d/graphics/camera/camera.h> #include <extra2d/graphics/camera/camera.h>
#include <extra2d/graphics/camera/viewport_adapter.h> #include <extra2d/graphics/camera/viewport_adapter.h>
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/graphics/core/render_module.h> #include <extra2d/graphics/core/render_module.h>
#include <extra2d/graphics/core/render_target.h> #include <extra2d/graphics/core/render_target.h>
#include <extra2d/graphics/memory/vram_manager.h> #include <extra2d/graphics/memory/vram_manager.h>
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/graphics/shader/shader_manager.h> #include <extra2d/graphics/shader/shader_manager.h>
#include <extra2d/graphics/texture/font.h> #include <extra2d/graphics/texture/font.h>
#include <extra2d/graphics/texture/texture.h> #include <extra2d/graphics/texture/texture.h>

View File

@ -1,125 +0,0 @@
#pragma once
#include <extra2d/core/color.h>
#include <extra2d/core/math_types.h>
#include <extra2d/core/types.h>
#include <extra2d/graphics/resources/pipeline.h>
#include <glm/mat4x4.hpp>
namespace extra2d {
// 前向声明
class GLFWWindow;
class Texture;
class FontAtlas;
class Shader;
// BlendMode 定义在 pipeline.h 中
// ============================================================================
// 渲染后端抽象接口
// ============================================================================
class RenderBackend {
public:
virtual ~RenderBackend() = default;
// ------------------------------------------------------------------------
// 生命周期
// ------------------------------------------------------------------------
virtual bool init(GLFWWindow* window) = 0;
virtual void shutdown() = 0;
// ------------------------------------------------------------------------
// 帧管理
// ------------------------------------------------------------------------
virtual void beginFrame(const Color &clearColor) = 0;
virtual void endFrame() = 0;
virtual void setViewport(int x, int y, int width, int height) = 0;
virtual void setVSync(bool enabled) = 0;
// ------------------------------------------------------------------------
// 状态设置
// ------------------------------------------------------------------------
virtual void setBlendMode(BlendMode mode) = 0;
virtual void setViewProjection(const glm::mat4 &matrix) = 0;
// ------------------------------------------------------------------------
// 变换矩阵栈
// ------------------------------------------------------------------------
virtual void pushTransform(const glm::mat4 &transform) = 0;
virtual void popTransform() = 0;
virtual glm::mat4 getCurrentTransform() const = 0;
// ------------------------------------------------------------------------
// 纹理
// ------------------------------------------------------------------------
virtual Ptr<Texture> createTexture(int width, int height,
const uint8_t *pixels, int channels) = 0;
virtual Ptr<Texture> loadTexture(const std::string &filepath) = 0;
// ------------------------------------------------------------------------
// 精灵批渲染
// ------------------------------------------------------------------------
/**
* @brief
* @note drawSprite/drawText
*/
virtual void beginSpriteBatch() = 0;
virtual void drawSprite(const Texture &texture, const Rect &destRect,
const Rect &srcRect, const Color &tint,
float rotation, const Vec2 &anchor) = 0;
virtual void drawSprite(const Texture &texture, const Vec2 &position,
const Color &tint) = 0;
virtual void endSpriteBatch() = 0;
/**
* @brief
* @note
*/
virtual void flush() = 0;
// ------------------------------------------------------------------------
// 形状渲染
// ------------------------------------------------------------------------
virtual void drawLine(const Vec2 &start, const Vec2 &end, const Color &color,
float width = 1.0f) = 0;
virtual void drawRect(const Rect &rect, const Color &color,
float width = 1.0f) = 0;
virtual void fillRect(const Rect &rect, const Color &color) = 0;
virtual void drawCircle(const Vec2 &center, float radius, const Color &color,
int segments = 32, float width = 1.0f) = 0;
virtual void fillCircle(const Vec2 &center, float radius, const Color &color,
int segments = 32) = 0;
virtual void drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
const Color &color, float width = 1.0f) = 0;
virtual void fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
const Color &color) = 0;
virtual void drawPolygon(const std::vector<Vec2> &points, const Color &color,
float width = 1.0f) = 0;
virtual void fillPolygon(const std::vector<Vec2> &points,
const Color &color) = 0;
// ------------------------------------------------------------------------
// 文字渲染
// ------------------------------------------------------------------------
virtual Ptr<FontAtlas> createFontAtlas(const std::string &filepath,
int fontSize, bool useSDF = false) = 0;
virtual void drawText(const FontAtlas &font, const std::string &text,
const Vec2 &position, const Color &color) = 0;
virtual void drawText(const FontAtlas &font, const std::string &text, float x,
float y, const Color &color) = 0;
// ------------------------------------------------------------------------
// 统计信息
// ------------------------------------------------------------------------
struct Stats {
uint32_t drawCalls = 0;
uint32_t triangleCount = 0;
uint32_t textureBinds = 0;
uint32_t shaderBinds = 0;
};
virtual Stats getStats() const = 0;
virtual void resetStats() = 0;
};
} // namespace extra2d

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <extra2d/core/module.h> #include <extra2d/core/module.h>
#include <extra2d/graphics/core/render_backend.h> #include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/platform/window_module.h> #include <extra2d/platform/window_module.h>
#include <functional> #include <functional>
#include <typeindex> #include <typeindex>
@ -17,17 +17,12 @@ struct RenderCfg {
int multisamples; int multisamples;
int priority; int priority;
RenderCfg() RenderCfg() : targetFPS(60), vsync(true), multisamples(0), priority(10) {}
: targetFPS(60)
, vsync(true)
, multisamples(0)
, priority(10)
{}
}; };
/** /**
* @brief * @brief
* OpenGL * OpenGL
*/ */
class RenderModule : public Module { class RenderModule : public Module {
public: public:
@ -65,13 +60,13 @@ public:
/** /**
* @brief * @brief
* @return * @return
*/ */
RenderBackend* renderer() const { return renderer_.get(); } Renderer *renderer() const { return renderer_.get(); }
private: private:
RenderCfg cfg_; RenderCfg cfg_;
UniquePtr<RenderBackend> renderer_; UniquePtr<Renderer> renderer_;
bool initialized_ = false; bool initialized_ = false;
}; };

View File

@ -1,132 +1,111 @@
#pragma once #pragma once
#include <extra2d/graphics/core/render_backend.h> #include <extra2d/core/color.h>
#include <extra2d/core/math_types.h>
#include <extra2d/core/types.h>
#include <extra2d/graphics/opengl/gl_buffer.h> #include <extra2d/graphics/opengl/gl_buffer.h>
#include <extra2d/graphics/opengl/gl_framebuffer.h> #include <extra2d/graphics/opengl/gl_framebuffer.h>
#include <extra2d/graphics/opengl/gl_pipeline.h> #include <extra2d/graphics/opengl/gl_pipeline.h>
#include <extra2d/graphics/opengl/gl_sprite_batch.h> #include <extra2d/graphics/opengl/gl_sprite_batch.h>
#include <extra2d/graphics/resources/pipeline.h>
#include <extra2d/graphics/shader/shader_interface.h> #include <extra2d/graphics/shader/shader_interface.h>
#include <array> #include <array>
#include <glad/glad.h> #include <glad/glad.h>
#include <glm/mat4x4.hpp>
#include <vector> #include <vector>
namespace extra2d { namespace extra2d {
// 前向声明
class GLFWWindow; class GLFWWindow;
class GLContext; class GLContext;
class GLFramebuffer; class GLFramebuffer;
class FontAtlas;
// ============================================================================ /**
// OpenGL 渲染器实现 * @brief
// ============================================================================ */
class GLRenderer : public RenderBackend { struct RenderStats {
uint32_t drawCalls = 0;
uint32_t triangleCount = 0;
uint32_t textureBinds = 0;
uint32_t shaderBinds = 0;
};
/**
* @brief OpenGL
*/
class Renderer {
public: public:
GLRenderer(); Renderer();
~GLRenderer() override; ~Renderer();
// RenderBackend 接口实现 bool init(GLFWWindow *window);
bool init(GLFWWindow *window) override; void shutdown();
void shutdown() override;
void beginFrame(const Color &clearColor) override; void beginFrame(const Color &clearColor);
void endFrame() override; void endFrame();
void setViewport(int x, int y, int width, int height) override; void setViewport(int x, int y, int width, int height);
void setVSync(bool enabled) override; void setVSync(bool enabled);
void setBlendMode(BlendMode mode) override; void setBlendMode(BlendMode mode);
void setViewProjection(const glm::mat4 &matrix) override; void setViewProjection(const glm::mat4 &matrix);
// 变换矩阵栈 void pushTransform(const glm::mat4 &transform);
void pushTransform(const glm::mat4 &transform) override; void popTransform();
void popTransform() override; glm::mat4 getCurrentTransform() const;
glm::mat4 getCurrentTransform() const override;
Ptr<Texture> createTexture(int width, int height, const uint8_t *pixels, Ptr<Texture> createTexture(int width, int height, const uint8_t *pixels,
int channels) override; int channels);
Ptr<Texture> loadTexture(const std::string &filepath) override; Ptr<Texture> loadTexture(const std::string &filepath);
void beginSpriteBatch() override; void beginSpriteBatch();
void drawSprite(const Texture &texture, const Rect &destRect, void drawSprite(const Texture &texture, const Rect &destRect,
const Rect &srcRect, const Color &tint, float rotation, const Rect &srcRect, const Color &tint, float rotation,
const Vec2 &anchor) override; const Vec2 &anchor);
void drawSprite(const Texture &texture, const Vec2 &position, void drawSprite(const Texture &texture, const Vec2 &position,
const Color &tint) override; const Color &tint);
void endSpriteBatch() override; void endSpriteBatch();
void flush() override; void flush();
void drawLine(const Vec2 &start, const Vec2 &end, const Color &color, void drawLine(const Vec2 &start, const Vec2 &end, const Color &color,
float width) override; float width = 1.0f);
void drawRect(const Rect &rect, const Color &color, float width) override; void drawRect(const Rect &rect, const Color &color, float width = 1.0f);
void fillRect(const Rect &rect, const Color &color) override; void fillRect(const Rect &rect, const Color &color);
void drawCircle(const Vec2 &center, float radius, const Color &color, void drawCircle(const Vec2 &center, float radius, const Color &color,
int segments, float width) override; int segments = 32, float width = 1.0f);
void fillCircle(const Vec2 &center, float radius, const Color &color, void fillCircle(const Vec2 &center, float radius, const Color &color,
int segments) override; int segments = 32);
void drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, void drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
const Color &color, float width) override; const Color &color, float width = 1.0f);
void fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, void fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
const Color &color) override; const Color &color);
void drawPolygon(const std::vector<Vec2> &points, const Color &color, void drawPolygon(const std::vector<Vec2> &points, const Color &color,
float width) override; float width = 1.0f);
void fillPolygon(const std::vector<Vec2> &points, void fillPolygon(const std::vector<Vec2> &points, const Color &color);
const Color &color) override;
Ptr<FontAtlas> createFontAtlas(const std::string &filepath, int fontSize, Ptr<FontAtlas> createFontAtlas(const std::string &filepath, int fontSize,
bool useSDF = false) override; bool useSDF = false);
void drawText(const FontAtlas &font, const std::string &text, void drawText(const FontAtlas &font, const std::string &text,
const Vec2 &position, const Color &color) override; const Vec2 &position, const Color &color);
void drawText(const FontAtlas &font, const std::string &text, float x, void drawText(const FontAtlas &font, const std::string &text, float x,
float y, const Color &color) override; float y, const Color &color);
Stats getStats() const override { return stats_; } RenderStats getStats() const { return stats_; }
void resetStats() override; void resetStats();
// GLFramebuffer 相关方法
/**
* @brief
* @param desc
* @return
*/
Ptr<GLFramebuffer> createFramebuffer(const FramebufferDesc &desc); Ptr<GLFramebuffer> createFramebuffer(const FramebufferDesc &desc);
/**
* @brief
* @param framebuffer nullptr
*/
void bindFramebuffer(GLFramebuffer *framebuffer); void bindFramebuffer(GLFramebuffer *framebuffer);
/**
* @brief
*/
void unbindFramebuffer(); void unbindFramebuffer();
/**
* @brief
* @return
*/
Ptr<GLFramebuffer> getDefaultFramebuffer() const; Ptr<GLFramebuffer> getDefaultFramebuffer() const;
/**
* @brief
* @param color
* @param clearColor
* @param clearDepth
* @param clearStencil
*/
void clearFramebuffer(const Color &color, bool clearColor = true, void clearFramebuffer(const Color &color, bool clearColor = true,
bool clearDepth = true, bool clearStencil = false); bool clearDepth = true, bool clearStencil = false);
private: private:
// 形状批处理常量
static constexpr size_t MAX_CIRCLE_SEGMENTS = 128; static constexpr size_t MAX_CIRCLE_SEGMENTS = 128;
static constexpr size_t MAX_SHAPE_VERTICES = 8192; // 最大形状顶点数 static constexpr size_t MAX_SHAPE_VERTICES = 8192;
static constexpr size_t MAX_LINE_VERTICES = 16384; // 最大线条顶点数 static constexpr size_t MAX_LINE_VERTICES = 16384;
// 形状顶点结构(包含颜色)
struct ShapeVertex { struct ShapeVertex {
float x, y; float x, y;
float r, g, b, a; float r, g, b, a;
@ -135,45 +114,40 @@ private:
GLFWWindow *window_; GLFWWindow *window_;
GLSpriteBatch spriteBatch_; GLSpriteBatch spriteBatch_;
Ptr<IShader> shapeShader_; Ptr<IShader> shapeShader_;
Ptr<IShader> sdfFontShader_; // SDF字体专用着色器 Ptr<IShader> sdfFontShader_;
GLuint shapeVao_; // 形状 VAO手动管理用于顶点属性配置 GLuint shapeVao_;
GLBuffer shapeBuffer_; // 形状 VBO使用 GLBuffer 管理) GLBuffer shapeBuffer_;
GLuint lineVao_; // 线条 VAO手动管理用于顶点属性配置 GLuint lineVao_;
GLBuffer lineBuffer_; // 线条 VBO使用 GLBuffer 管理) GLBuffer lineBuffer_;
glm::mat4 viewProjection_; glm::mat4 viewProjection_;
std::vector<glm::mat4> transformStack_; std::vector<glm::mat4> transformStack_;
Stats stats_; RenderStats stats_;
bool vsync_; bool vsync_;
// 形状批处理缓冲区(预分配,避免每帧内存分配)
std::array<ShapeVertex, MAX_SHAPE_VERTICES> shapeVertexCache_; std::array<ShapeVertex, MAX_SHAPE_VERTICES> shapeVertexCache_;
size_t shapeVertexCount_ = 0; size_t shapeVertexCount_ = 0;
GLenum currentShapeMode_ = GL_TRIANGLES; GLenum currentShapeMode_ = GL_TRIANGLES;
// 线条批处理缓冲区
std::array<ShapeVertex, MAX_LINE_VERTICES> lineVertexCache_; std::array<ShapeVertex, MAX_LINE_VERTICES> lineVertexCache_;
size_t lineVertexCount_ = 0; size_t lineVertexCount_ = 0;
float currentLineWidth_ = 1.0f; float currentLineWidth_ = 1.0f;
// OpenGL 管线状态管理
GLPipeline pipeline_; GLPipeline pipeline_;
// 自动批处理状态 bool batchActive_ = false;
bool batchActive_ = false; // 批处理是否激活 bool autoBatchEnabled_ = true;
bool autoBatchEnabled_ = true; // 是否启用自动批处理 const Texture *currentBatchTexture_ = nullptr;
const Texture *currentBatchTexture_ = nullptr; // 当前批处理的纹理 std::vector<SpriteData> pendingSprites_;
std::vector<SpriteData> pendingSprites_; // 待提交的精灵 static constexpr size_t MAX_BATCH_SPRITES = 1000;
static constexpr size_t MAX_BATCH_SPRITES = 1000; // 最大批处理精灵数
// 帧缓冲管理 mutable Ptr<GLFramebuffer> defaultFramebuffer_;
mutable Ptr<GLFramebuffer> defaultFramebuffer_; // 默认帧缓冲(延迟创建) GLFramebuffer *currentFramebuffer_ = nullptr;
GLFramebuffer *currentFramebuffer_ = nullptr; // 当前绑定的帧缓冲
void initShapeRendering(); void initShapeRendering();
void ensureBatchActive(); // 确保批处理已激活 void ensureBatchActive();
void submitPendingSprites(); // 提交待处理的精灵 void submitPendingSprites();
void flushShapeBatch(); void flushShapeBatch();
void flushLineBatch(); void flushLineBatch();
void addShapeVertex(float x, float y, const Color &color); void addShapeVertex(float x, float y, const Color &color);

View File

@ -13,12 +13,10 @@
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
namespace extra2d { namespace extra2d {
// 前向声明
class Scene; class Scene;
class RenderBackend; class Renderer;
// ============================================================================ // ============================================================================
// 纹理加载选项 // 纹理加载选项

View File

@ -4,16 +4,15 @@
#include <extra2d/core/math_types.h> #include <extra2d/core/math_types.h>
#include <extra2d/core/types.h> #include <extra2d/core/types.h>
#include <extra2d/event/event_dispatcher.h> #include <extra2d/event/event_dispatcher.h>
#include <extra2d/graphics/core/render_backend.h> #include <extra2d/graphics/opengl/gl_renderer.h>
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
namespace extra2d { namespace extra2d {
// 前向声明
class Scene; class Scene;
class RenderBackend; class Renderer;
struct RenderCommand; struct RenderCommand;
// ============================================================================ // ============================================================================
@ -137,7 +136,7 @@ public:
virtual void onEnter(); virtual void onEnter();
virtual void onExit(); virtual void onExit();
virtual void onUpdate(float dt); virtual void onUpdate(float dt);
virtual void onRender(RenderBackend &renderer); virtual void onRender(Renderer &renderer);
virtual void onAttachToScene(Scene *scene); virtual void onAttachToScene(Scene *scene);
virtual void onDetachFromScene(); virtual void onDetachFromScene();
@ -155,7 +154,7 @@ public:
// 内部方法 // 内部方法
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void update(float dt); void update(float dt);
void render(RenderBackend &renderer); void render(Renderer &renderer);
void sortChildren(); void sortChildren();
bool isRunning() const { return running_; } bool isRunning() const { return running_; }
@ -167,7 +166,7 @@ public:
protected: protected:
// 子类重写 // 子类重写
virtual void onDraw(RenderBackend &renderer) {} virtual void onDraw(Renderer &renderer) {}
virtual void onUpdateNode(float dt) {} virtual void onUpdateNode(float dt) {}
virtual void generateRenderCommand(std::vector<RenderCommand> &commands, virtual void generateRenderCommand(std::vector<RenderCommand> &commands,
int zOrder) {}; int zOrder) {};

View File

@ -54,8 +54,8 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// 渲染和更新 // 渲染和更新
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void renderScene(RenderBackend &renderer); void renderScene(Renderer &renderer);
virtual void renderContent(RenderBackend &renderer); virtual void renderContent(Renderer &renderer);
void updateScene(float dt); void updateScene(float dt);
void collectRenderCommands(std::vector<RenderCommand> &commands, void collectRenderCommands(std::vector<RenderCommand> &commands,
int parentZOrder = 0) override; int parentZOrder = 0) override;

View File

@ -102,7 +102,7 @@ public:
// 更新和渲染 // 更新和渲染
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void update(float dt); void update(float dt);
void render(RenderBackend &renderer); void render(Renderer &renderer);
void collectRenderCommands(std::vector<RenderCommand> &commands); void collectRenderCommands(std::vector<RenderCommand> &commands);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -143,7 +143,8 @@ private:
* @param inScene * @param inScene
* @return * @return
*/ */
Ptr<TransitionScene> createTransitionScene(TransitionType type, float duration, Ptr<TransitionScene> createTransitionScene(TransitionType type,
float duration,
Ptr<Scene> inScene); Ptr<Scene> inScene);
/** /**

View File

@ -88,7 +88,7 @@ public:
Rect getBounds() const override; Rect getBounds() const override;
protected: protected:
void onDraw(RenderBackend &renderer) override; void onDraw(Renderer &renderer) override;
void generateRenderCommand(std::vector<RenderCommand> &commands, void generateRenderCommand(std::vector<RenderCommand> &commands,
int zOrder) override; int zOrder) override;

View File

@ -40,7 +40,7 @@ public:
Rect getBounds() const override; Rect getBounds() const override;
protected: protected:
void onDraw(RenderBackend &renderer) override; void onDraw(Renderer &renderer) override;
void generateRenderCommand(std::vector<RenderCommand> &commands, void generateRenderCommand(std::vector<RenderCommand> &commands,
int zOrder) override; int zOrder) override;

View File

@ -25,7 +25,7 @@ public:
protected: protected:
void onTransitionStart() override; void onTransitionStart() override;
void renderContent(RenderBackend &renderer) override; void renderContent(Renderer &renderer) override;
void updateTransition(float dt) override; void updateTransition(float dt) override;
private: private:

View File

@ -44,7 +44,7 @@ protected:
* @brief * @brief
* *
*/ */
void renderContent(RenderBackend &renderer) override; void renderContent(Renderer &renderer) override;
private: private:
/** /**

View File

@ -28,7 +28,7 @@ public:
protected: protected:
void onTransitionStart() override; void onTransitionStart() override;
void renderContent(RenderBackend &renderer) override; void renderContent(Renderer &renderer) override;
void updateTransition(float dt) override; void updateTransition(float dt) override;
private: private:

View File

@ -23,7 +23,7 @@ public:
protected: protected:
void onTransitionStart() override; void onTransitionStart() override;
void renderContent(RenderBackend &renderer) override; void renderContent(Renderer &renderer) override;
void updateTransition(float dt) override; void updateTransition(float dt) override;
}; };

View File

@ -63,7 +63,9 @@ public:
/** /**
* @brief * @brief
*/ */
void setFinishCallback(FinishCallback callback) { finishCallback_ = callback; } void setFinishCallback(FinishCallback callback) {
finishCallback_ = callback;
}
/** /**
* @brief * @brief
@ -99,7 +101,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// 渲染 - 在 TransitionScene 上渲染新旧两个子场景 // 渲染 - 在 TransitionScene 上渲染新旧两个子场景
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void renderContent(RenderBackend &renderer) override; void renderContent(Renderer &renderer) override;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// 生命周期 // 生命周期
@ -117,12 +119,12 @@ protected:
/** /**
* @brief * @brief
*/ */
virtual void drawOutScene(RenderBackend &renderer); virtual void drawOutScene(Renderer &renderer);
/** /**
* @brief * @brief
*/ */
virtual void drawInScene(RenderBackend &renderer); virtual void drawInScene(Renderer &renderer);
/** /**
* @brief * @brief

View File

@ -26,7 +26,7 @@ public:
protected: protected:
void onTransitionStart() override; void onTransitionStart() override;
void renderContent(RenderBackend &renderer) override; void renderContent(Renderer &renderer) override;
void updateTransition(float dt) override; void updateTransition(float dt) override;
private: private:

View File

@ -2,6 +2,7 @@
#include <extra2d/core/service_interface.h> #include <extra2d/core/service_interface.h>
#include <extra2d/core/service_locator.h> #include <extra2d/core/service_locator.h>
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/scene/scene_manager.h> #include <extra2d/scene/scene_manager.h>
namespace extra2d { namespace extra2d {
@ -30,11 +31,12 @@ public:
virtual bool isEmpty() const = 0; virtual bool isEmpty() const = 0;
virtual bool hasScene(const std::string &name) const = 0; virtual bool hasScene(const std::string &name) const = 0;
virtual void render(RenderBackend& renderer) = 0; virtual void render(Renderer &renderer) = 0;
virtual void collectRenderCommands(std::vector<RenderCommand> &commands) = 0; virtual void collectRenderCommands(std::vector<RenderCommand> &commands) = 0;
virtual bool isTransitioning() const = 0; virtual bool isTransitioning() const = 0;
virtual void setTransitionCallback(SceneManager::TransitionCallback callback) = 0; virtual void
setTransitionCallback(SceneManager::TransitionCallback callback) = 0;
virtual void end() = 0; virtual void end() = 0;
virtual void purgeCachedScenes() = 0; virtual void purgeCachedScenes() = 0;
@ -72,11 +74,12 @@ public:
bool isEmpty() const override; bool isEmpty() const override;
bool hasScene(const std::string &name) const override; bool hasScene(const std::string &name) const override;
void render(RenderBackend& renderer) override; void render(Renderer &renderer) override;
void collectRenderCommands(std::vector<RenderCommand> &commands) override; void collectRenderCommands(std::vector<RenderCommand> &commands) override;
bool isTransitioning() const override; bool isTransitioning() const override;
void setTransitionCallback(SceneManager::TransitionCallback callback) override; void
setTransitionCallback(SceneManager::TransitionCallback callback) override;
void end() override; void end() override;
void purgeCachedScenes() override; void purgeCachedScenes() override;
@ -92,4 +95,4 @@ private:
E2D_AUTO_REGISTER_SERVICE(ISceneService, SceneService); E2D_AUTO_REGISTER_SERVICE(ISceneService, SceneService);
}; };
} } // namespace extra2d

View File

@ -1,8 +1,8 @@
#include <extra2d/app/application.h> #include <extra2d/app/application.h>
#include <extra2d/core/registry.h> #include <extra2d/core/registry.h>
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/graphics/core/render_module.h> #include <extra2d/graphics/core/render_module.h>
#include <extra2d/graphics/memory/vram_manager.h> #include <extra2d/graphics/memory/vram_manager.h>
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/platform/glfw/glfw_window.h> #include <extra2d/platform/glfw/glfw_window.h>
#include <extra2d/platform/window_module.h> #include <extra2d/platform/window_module.h>
#include <extra2d/services/camera_service.h> #include <extra2d/services/camera_service.h>
@ -11,7 +11,6 @@
#include <extra2d/services/scene_service.h> #include <extra2d/services/scene_service.h>
#include <extra2d/services/timer_service.h> #include <extra2d/services/timer_service.h>
namespace extra2d { namespace extra2d {
static double getTimeSeconds() { static double getTimeSeconds() {
@ -179,9 +178,7 @@ void Application::mainLoop() {
} }
} }
void Application::update() { void Application::update() { ServiceLocator::instance().updateAll(deltaTime_); }
ServiceLocator::instance().updateAll(deltaTime_);
}
void Application::render() { void Application::render() {
auto *renderMod = get<RenderModule>(); auto *renderMod = get<RenderModule>();
@ -218,7 +215,7 @@ GLFWWindow *Application::window() {
return winMod ? winMod->win() : nullptr; return winMod ? winMod->win() : nullptr;
} }
RenderBackend *Application::renderer() { Renderer *Application::renderer() {
auto *renderMod = get<RenderModule>(); auto *renderMod = get<RenderModule>();
return renderMod ? renderMod->renderer() : nullptr; return renderMod ? renderMod->renderer() : nullptr;
} }

View File

@ -38,7 +38,7 @@ bool RenderModule::init() {
} }
E2D_LOG_INFO("正在创建 OpenGL 渲染后端"); E2D_LOG_INFO("正在创建 OpenGL 渲染后端");
renderer_ = makeUnique<GLRenderer>(); renderer_ = makeUnique<Renderer>();
if (!renderer_) { if (!renderer_) {
E2D_LOG_ERROR("创建渲染后端失败"); E2D_LOG_ERROR("创建渲染后端失败");

View File

@ -13,7 +13,6 @@
#include <extra2d/services/logger_service.h> #include <extra2d/services/logger_service.h>
#include <vector> #include <vector>
namespace extra2d { namespace extra2d {
// VBO 初始大小(用于 VRAM 跟踪) // VBO 初始大小(用于 VRAM 跟踪)
@ -22,7 +21,7 @@ static constexpr size_t SHAPE_VBO_SIZE = 1024 * sizeof(float);
/** /**
* @brief OpenGL渲染器成员变量 * @brief OpenGL渲染器成员变量
*/ */
GLRenderer::GLRenderer() Renderer::Renderer()
: window_(nullptr), shapeVao_(0), lineVao_(0), vsync_(true), : window_(nullptr), shapeVao_(0), lineVao_(0), vsync_(true),
shapeVertexCount_(0), currentShapeMode_(GL_TRIANGLES), shapeVertexCount_(0), currentShapeMode_(GL_TRIANGLES),
lineVertexCount_(0), currentLineWidth_(1.0f) { lineVertexCount_(0), currentLineWidth_(1.0f) {
@ -38,14 +37,14 @@ GLRenderer::GLRenderer()
/** /**
* @brief shutdown释放资源 * @brief shutdown释放资源
*/ */
GLRenderer::~GLRenderer() { shutdown(); } Renderer::~Renderer() { shutdown(); }
/** /**
* @brief OpenGL渲染器 * @brief OpenGL渲染器
* @param window * @param window
* @return truefalse * @return truefalse
*/ */
bool GLRenderer::init(GLFWWindow *window) { bool Renderer::init(GLFWWindow *window) {
window_ = window; window_ = window;
// 初始化 OpenGL 上下文Switch 平台已通过 SDL2 + EGL 初始化GLContext // 初始化 OpenGL 上下文Switch 平台已通过 SDL2 + EGL 初始化GLContext
@ -89,7 +88,7 @@ bool GLRenderer::init(GLFWWindow *window) {
/** /**
* @brief GPU资源 * @brief GPU资源
*/ */
void GLRenderer::shutdown() { void Renderer::shutdown() {
// 标记 GPU 上下文为无效 // 标记 GPU 上下文为无效
// 这会在销毁 OpenGL 上下文之前通知所有 GPU 资源 // 这会在销毁 OpenGL 上下文之前通知所有 GPU 资源
GPUContext::get().markInvalid(); GPUContext::get().markInvalid();
@ -118,7 +117,7 @@ void GLRenderer::shutdown() {
* @brief * @brief
* @param clearColor * @param clearColor
*/ */
void GLRenderer::beginFrame(const Color &clearColor) { void Renderer::beginFrame(const Color &clearColor) {
// 应用管线状态 // 应用管线状态
pipeline_.applyAllStates(); pipeline_.applyAllStates();
@ -130,7 +129,7 @@ void GLRenderer::beginFrame(const Color &clearColor) {
/** /**
* @brief * @brief
*/ */
void GLRenderer::endFrame() { void Renderer::endFrame() {
// 刷新所有待处理的精灵批次(自动批处理) // 刷新所有待处理的精灵批次(自动批处理)
if (autoBatchEnabled_ && batchActive_) { if (autoBatchEnabled_ && batchActive_) {
flush(); flush();
@ -148,7 +147,7 @@ void GLRenderer::endFrame() {
* @param width * @param width
* @param height * @param height
*/ */
void GLRenderer::setViewport(int x, int y, int width, int height) { void Renderer::setViewport(int x, int y, int width, int height) {
// 使用 GLPipeline 管理视口状态 // 使用 GLPipeline 管理视口状态
pipeline_.setViewport(x, y, width, height); pipeline_.setViewport(x, y, width, height);
} }
@ -157,7 +156,7 @@ void GLRenderer::setViewport(int x, int y, int width, int height) {
* @brief * @brief
* @param enabled true启用垂直同步false禁用 * @param enabled true启用垂直同步false禁用
*/ */
void GLRenderer::setVSync(bool enabled) { void Renderer::setVSync(bool enabled) {
vsync_ = enabled; vsync_ = enabled;
// 通过窗口接口设置垂直同步 // 通过窗口接口设置垂直同步
if (window_) { if (window_) {
@ -169,7 +168,7 @@ void GLRenderer::setVSync(bool enabled) {
* @brief * @brief
* @param mode * @param mode
*/ */
void GLRenderer::setBlendMode(BlendMode mode) { void Renderer::setBlendMode(BlendMode mode) {
// 使用 GLPipeline 管理混合状态 // 使用 GLPipeline 管理混合状态
pipeline_.setBlendMode(mode); pipeline_.setBlendMode(mode);
} }
@ -178,7 +177,7 @@ void GLRenderer::setBlendMode(BlendMode mode) {
* @brief * @brief
* @param matrix 4x4视图投影矩阵 * @param matrix 4x4视图投影矩阵
*/ */
void GLRenderer::setViewProjection(const glm::mat4 &matrix) { void Renderer::setViewProjection(const glm::mat4 &matrix) {
viewProjection_ = matrix; viewProjection_ = matrix;
} }
@ -186,7 +185,7 @@ void GLRenderer::setViewProjection(const glm::mat4 &matrix) {
* @brief * @brief
* @param transform * @param transform
*/ */
void GLRenderer::pushTransform(const glm::mat4 &transform) { void Renderer::pushTransform(const glm::mat4 &transform) {
if (transformStack_.empty()) { if (transformStack_.empty()) {
transformStack_.push_back(transform); transformStack_.push_back(transform);
} else { } else {
@ -197,7 +196,7 @@ void GLRenderer::pushTransform(const glm::mat4 &transform) {
/** /**
* @brief * @brief
*/ */
void GLRenderer::popTransform() { void Renderer::popTransform() {
if (!transformStack_.empty()) { if (!transformStack_.empty()) {
transformStack_.pop_back(); transformStack_.pop_back();
} }
@ -207,7 +206,7 @@ void GLRenderer::popTransform() {
* @brief * @brief
* @return * @return
*/ */
glm::mat4 GLRenderer::getCurrentTransform() const { glm::mat4 Renderer::getCurrentTransform() const {
if (transformStack_.empty()) { if (transformStack_.empty()) {
return glm::mat4(1.0f); return glm::mat4(1.0f);
} }
@ -222,7 +221,7 @@ glm::mat4 GLRenderer::getCurrentTransform() const {
* @param channels * @param channels
* @return * @return
*/ */
Ptr<Texture> GLRenderer::createTexture(int width, int height, Ptr<Texture> Renderer::createTexture(int width, int height,
const uint8_t *pixels, int channels) { const uint8_t *pixels, int channels) {
return makePtr<GLTexture>(width, height, pixels, channels); return makePtr<GLTexture>(width, height, pixels, channels);
} }
@ -232,14 +231,14 @@ Ptr<Texture> GLRenderer::createTexture(int width, int height,
* @param filepath * @param filepath
* @return * @return
*/ */
Ptr<Texture> GLRenderer::loadTexture(const std::string &filepath) { Ptr<Texture> Renderer::loadTexture(const std::string &filepath) {
return makePtr<GLTexture>(filepath); return makePtr<GLTexture>(filepath);
} }
/** /**
* @brief 使 * @brief 使
*/ */
void GLRenderer::ensureBatchActive() { void Renderer::ensureBatchActive() {
if (!batchActive_) { if (!batchActive_) {
spriteBatch_.begin(viewProjection_); spriteBatch_.begin(viewProjection_);
batchActive_ = true; batchActive_ = true;
@ -251,7 +250,7 @@ void GLRenderer::ensureBatchActive() {
/** /**
* @brief 使 * @brief 使
*/ */
void GLRenderer::submitPendingSprites() { void Renderer::submitPendingSprites() {
if (pendingSprites_.empty()) { if (pendingSprites_.empty()) {
return; return;
} }
@ -266,7 +265,7 @@ void GLRenderer::submitPendingSprites() {
* @brief * @brief
* @note drawSprite/drawText * @note drawSprite/drawText
*/ */
void GLRenderer::beginSpriteBatch() { void Renderer::beginSpriteBatch() {
// 如果自动批处理已激活,先提交 // 如果自动批处理已激活,先提交
if (autoBatchEnabled_ && batchActive_) { if (autoBatchEnabled_ && batchActive_) {
flush(); flush();
@ -286,7 +285,7 @@ void GLRenderer::beginSpriteBatch() {
* @param rotation * @param rotation
* @param anchor 0-1 * @param anchor 0-1
*/ */
void GLRenderer::drawSprite(const Texture &texture, const Rect &destRect, void Renderer::drawSprite(const Texture &texture, const Rect &destRect,
const Rect &srcRect, const Color &tint, const Rect &srcRect, const Color &tint,
float rotation, const Vec2 &anchor) { float rotation, const Vec2 &anchor) {
// 自动批处理模式 // 自动批处理模式
@ -356,7 +355,7 @@ void GLRenderer::drawSprite(const Texture &texture, const Rect &destRect,
* @param position * @param position
* @param tint * @param tint
*/ */
void GLRenderer::drawSprite(const Texture &texture, const Vec2 &position, void Renderer::drawSprite(const Texture &texture, const Vec2 &position,
const Color &tint) { const Color &tint) {
Rect destRect(position.x, position.y, static_cast<float>(texture.getWidth()), Rect destRect(position.x, position.y, static_cast<float>(texture.getWidth()),
static_cast<float>(texture.getHeight())); static_cast<float>(texture.getHeight()));
@ -369,7 +368,7 @@ void GLRenderer::drawSprite(const Texture &texture, const Vec2 &position,
* @brief * @brief
* @note * @note
*/ */
void GLRenderer::endSpriteBatch() { void Renderer::endSpriteBatch() {
if (autoBatchEnabled_) { if (autoBatchEnabled_) {
// 自动模式下,只是标记批处理结束 // 自动模式下,只是标记批处理结束
flush(); flush();
@ -386,7 +385,7 @@ void GLRenderer::endSpriteBatch() {
* @brief * @brief
* @note * @note
*/ */
void GLRenderer::flush() { void Renderer::flush() {
if (autoBatchEnabled_ && batchActive_) { if (autoBatchEnabled_ && batchActive_) {
submitPendingSprites(); submitPendingSprites();
spriteBatch_.end(); spriteBatch_.end();
@ -403,8 +402,8 @@ void GLRenderer::flush() {
* @param color 线 * @param color 线
* @param width 线 * @param width 线
*/ */
void GLRenderer::drawLine(const Vec2 &start, const Vec2 &end, void Renderer::drawLine(const Vec2 &start, const Vec2 &end, const Color &color,
const Color &color, float width) { float width) {
// 如果线宽改变,需要先刷新线条批次 // 如果线宽改变,需要先刷新线条批次
if (width != currentLineWidth_) { if (width != currentLineWidth_) {
flushLineBatch(); flushLineBatch();
@ -416,7 +415,7 @@ void GLRenderer::drawLine(const Vec2 &start, const Vec2 &end,
addLineVertex(end.x, end.y, color); addLineVertex(end.x, end.y, color);
} }
void GLRenderer::drawRect(const Rect &rect, const Color &color, float width) { void Renderer::drawRect(const Rect &rect, const Color &color, float width) {
// 如果线宽改变,需要先刷新线条批次 // 如果线宽改变,需要先刷新线条批次
if (width != currentLineWidth_) { if (width != currentLineWidth_) {
flushLineBatch(); flushLineBatch();
@ -448,7 +447,7 @@ void GLRenderer::drawRect(const Rect &rect, const Color &color, float width) {
* @param rect * @param rect
* @param color * @param color
*/ */
void GLRenderer::fillRect(const Rect &rect, const Color &color) { void Renderer::fillRect(const Rect &rect, const Color &color) {
// 提交当前批次(如果模式不同) // 提交当前批次(如果模式不同)
submitShapeBatch(GL_TRIANGLES); submitShapeBatch(GL_TRIANGLES);
@ -477,8 +476,8 @@ void GLRenderer::fillRect(const Rect &rect, const Color &color) {
* @param segments * @param segments
* @param width 线 * @param width 线
*/ */
void GLRenderer::drawCircle(const Vec2 &center, float radius, void Renderer::drawCircle(const Vec2 &center, float radius, const Color &color,
const Color &color, int segments, float width) { int segments, float width) {
// 限制段数不超过缓存大小 // 限制段数不超过缓存大小
if (segments > static_cast<int>(MAX_CIRCLE_SEGMENTS)) { if (segments > static_cast<int>(MAX_CIRCLE_SEGMENTS)) {
segments = static_cast<int>(MAX_CIRCLE_SEGMENTS); segments = static_cast<int>(MAX_CIRCLE_SEGMENTS);
@ -511,8 +510,8 @@ void GLRenderer::drawCircle(const Vec2 &center, float radius,
* @param color * @param color
* @param segments * @param segments
*/ */
void GLRenderer::fillCircle(const Vec2 &center, float radius, void Renderer::fillCircle(const Vec2 &center, float radius, const Color &color,
const Color &color, int segments) { int segments) {
// 限制段数不超过缓存大小 // 限制段数不超过缓存大小
if (segments > static_cast<int>(MAX_CIRCLE_SEGMENTS)) { if (segments > static_cast<int>(MAX_CIRCLE_SEGMENTS)) {
segments = static_cast<int>(MAX_CIRCLE_SEGMENTS); segments = static_cast<int>(MAX_CIRCLE_SEGMENTS);
@ -546,7 +545,7 @@ void GLRenderer::fillCircle(const Vec2 &center, float radius,
* @param color * @param color
* @param width 线 * @param width 线
*/ */
void GLRenderer::drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, void Renderer::drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
const Color &color, float width) { const Color &color, float width) {
drawLine(p1, p2, color, width); drawLine(p1, p2, color, width);
drawLine(p2, p3, color, width); drawLine(p2, p3, color, width);
@ -560,7 +559,7 @@ void GLRenderer::drawTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
* @param p3 * @param p3
* @param color * @param color
*/ */
void GLRenderer::fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3, void Renderer::fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
const Color &color) { const Color &color) {
submitShapeBatch(GL_TRIANGLES); submitShapeBatch(GL_TRIANGLES);
@ -575,8 +574,8 @@ void GLRenderer::fillTriangle(const Vec2 &p1, const Vec2 &p2, const Vec2 &p3,
* @param color * @param color
* @param width 线 * @param width 线
*/ */
void GLRenderer::drawPolygon(const std::vector<Vec2> &points, void Renderer::drawPolygon(const std::vector<Vec2> &points, const Color &color,
const Color &color, float width) { float width) {
if (points.size() < 2) if (points.size() < 2)
return; return;
@ -600,7 +599,7 @@ void GLRenderer::drawPolygon(const std::vector<Vec2> &points,
* @param points * @param points
* @param color * @param color
*/ */
void GLRenderer::fillPolygon(const std::vector<Vec2> &points, void Renderer::fillPolygon(const std::vector<Vec2> &points,
const Color &color) { const Color &color) {
if (points.size() < 3) if (points.size() < 3)
return; return;
@ -623,7 +622,7 @@ void GLRenderer::fillPolygon(const std::vector<Vec2> &points,
* @param useSDF 使SDF渲染 * @param useSDF 使SDF渲染
* @return * @return
*/ */
Ptr<FontAtlas> GLRenderer::createFontAtlas(const std::string &filepath, Ptr<FontAtlas> Renderer::createFontAtlas(const std::string &filepath,
int fontSize, bool useSDF) { int fontSize, bool useSDF) {
return makePtr<GLFontAtlas>(filepath, fontSize, useSDF); return makePtr<GLFontAtlas>(filepath, fontSize, useSDF);
} }
@ -635,7 +634,7 @@ Ptr<FontAtlas> GLRenderer::createFontAtlas(const std::string &filepath,
* @param position * @param position
* @param color * @param color
*/ */
void GLRenderer::drawText(const FontAtlas &font, const std::string &text, void Renderer::drawText(const FontAtlas &font, const std::string &text,
const Vec2 &position, const Color &color) { const Vec2 &position, const Color &color) {
drawText(font, text, position.x, position.y, color); drawText(font, text, position.x, position.y, color);
} }
@ -648,8 +647,8 @@ void GLRenderer::drawText(const FontAtlas &font, const std::string &text,
* @param y Y坐标 * @param y Y坐标
* @param color * @param color
*/ */
void GLRenderer::drawText(const FontAtlas &font, const std::string &text, void Renderer::drawText(const FontAtlas &font, const std::string &text, float x,
float x, float y, const Color &color) { float y, const Color &color) {
float cursorX = x; float cursorX = x;
float cursorY = y; float cursorY = y;
float baselineY = cursorY + font.getAscent(); float baselineY = cursorY + font.getAscent();
@ -789,12 +788,12 @@ void GLRenderer::drawText(const FontAtlas &font, const std::string &text,
/** /**
* @brief * @brief
*/ */
void GLRenderer::resetStats() { stats_ = Stats{}; } void Renderer::resetStats() { stats_ = RenderStats{}; }
/** /**
* @brief OpenGL资源VAOVBO * @brief OpenGL资源VAOVBO
*/ */
void GLRenderer::initShapeRendering() { void Renderer::initShapeRendering() {
// 从ShaderManager获取形状着色器 // 从ShaderManager获取形状着色器
shapeShader_ = ShaderManager::getInstance().getBuiltin("shape"); shapeShader_ = ShaderManager::getInstance().getBuiltin("shape");
if (!shapeShader_) { if (!shapeShader_) {
@ -871,7 +870,7 @@ void GLRenderer::initShapeRendering() {
* @param y Y坐标 * @param y Y坐标
* @param color * @param color
*/ */
void GLRenderer::addShapeVertex(float x, float y, const Color &color) { void Renderer::addShapeVertex(float x, float y, const Color &color) {
if (shapeVertexCount_ >= MAX_SHAPE_VERTICES) { if (shapeVertexCount_ >= MAX_SHAPE_VERTICES) {
flushShapeBatch(); flushShapeBatch();
} }
@ -896,7 +895,7 @@ void GLRenderer::addShapeVertex(float x, float y, const Color &color) {
* @param y Y坐标 * @param y Y坐标
* @param color * @param color
*/ */
void GLRenderer::addLineVertex(float x, float y, const Color &color) { void Renderer::addLineVertex(float x, float y, const Color &color) {
if (lineVertexCount_ >= MAX_LINE_VERTICES) { if (lineVertexCount_ >= MAX_LINE_VERTICES) {
flushLineBatch(); flushLineBatch();
} }
@ -919,7 +918,7 @@ void GLRenderer::addLineVertex(float x, float y, const Color &color) {
* @brief * @brief
* @param mode OpenGL绘制模式 * @param mode OpenGL绘制模式
*/ */
void GLRenderer::submitShapeBatch(GLenum mode) { void Renderer::submitShapeBatch(GLenum mode) {
if (shapeVertexCount_ == 0) if (shapeVertexCount_ == 0)
return; return;
@ -933,7 +932,7 @@ void GLRenderer::submitShapeBatch(GLenum mode) {
/** /**
* @brief OpenGL绘制调用 * @brief OpenGL绘制调用
*/ */
void GLRenderer::flushShapeBatch() { void Renderer::flushShapeBatch() {
if (shapeVertexCount_ == 0) if (shapeVertexCount_ == 0)
return; return;
@ -966,7 +965,7 @@ void GLRenderer::flushShapeBatch() {
/** /**
* @brief 线OpenGL绘制调用 * @brief 线OpenGL绘制调用
*/ */
void GLRenderer::flushLineBatch() { void Renderer::flushLineBatch() {
if (lineVertexCount_ == 0) if (lineVertexCount_ == 0)
return; return;
@ -1004,7 +1003,7 @@ void GLRenderer::flushLineBatch() {
* @param desc * @param desc
* @return * @return
*/ */
Ptr<GLFramebuffer> GLRenderer::createFramebuffer(const FramebufferDesc &desc) { Ptr<GLFramebuffer> Renderer::createFramebuffer(const FramebufferDesc &desc) {
auto framebuffer = makePtr<GLFramebuffer>(); auto framebuffer = makePtr<GLFramebuffer>();
if (!framebuffer->init(desc)) { if (!framebuffer->init(desc)) {
E2D_LOG_ERROR("创建帧缓冲区失败"); E2D_LOG_ERROR("创建帧缓冲区失败");
@ -1017,7 +1016,7 @@ Ptr<GLFramebuffer> GLRenderer::createFramebuffer(const FramebufferDesc &desc) {
* @brief * @brief
* @param framebuffer nullptr * @param framebuffer nullptr
*/ */
void GLRenderer::bindFramebuffer(GLFramebuffer *framebuffer) { void Renderer::bindFramebuffer(GLFramebuffer *framebuffer) {
// 先刷新所有待处理的渲染批次 // 先刷新所有待处理的渲染批次
flush(); flush();
flushShapeBatch(); flushShapeBatch();
@ -1039,13 +1038,13 @@ void GLRenderer::bindFramebuffer(GLFramebuffer *framebuffer) {
/** /**
* @brief * @brief
*/ */
void GLRenderer::unbindFramebuffer() { bindFramebuffer(nullptr); } void Renderer::unbindFramebuffer() { bindFramebuffer(nullptr); }
/** /**
* @brief * @brief
* @return * @return
*/ */
Ptr<GLFramebuffer> GLRenderer::getDefaultFramebuffer() const { Ptr<GLFramebuffer> Renderer::getDefaultFramebuffer() const {
if (!defaultFramebuffer_) { if (!defaultFramebuffer_) {
// 延迟创建默认帧缓冲对象代表系统默认帧缓冲ID 为 0 // 延迟创建默认帧缓冲对象代表系统默认帧缓冲ID 为 0
defaultFramebuffer_ = makePtr<GLFramebuffer>(); defaultFramebuffer_ = makePtr<GLFramebuffer>();
@ -1061,7 +1060,7 @@ Ptr<GLFramebuffer> GLRenderer::getDefaultFramebuffer() const {
* @param clearDepth * @param clearDepth
* @param clearStencil * @param clearStencil
*/ */
void GLRenderer::clearFramebuffer(const Color &color, bool clearColor, void Renderer::clearFramebuffer(const Color &color, bool clearColor,
bool clearDepth, bool clearStencil) { bool clearDepth, bool clearStencil) {
GLbitfield mask = 0; GLbitfield mask = 0;

View File

@ -1,5 +1,5 @@
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/graphics/texture/texture_pool.h> #include <extra2d/graphics/texture/texture_pool.h>
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/scene/scene.h> #include <extra2d/scene/scene.h>
#include <algorithm> #include <algorithm>
@ -17,13 +17,8 @@ namespace extra2d {
* *
*/ */
TexturePool::TexturePool() TexturePool::TexturePool()
: scene_(nullptr) : scene_(nullptr), maxMemoryUsage_(0), currentMemoryUsage_(0),
, maxMemoryUsage_(0) cacheHits_(0), cacheMisses_(0), evictionCount_(0) {}
, currentMemoryUsage_(0)
, cacheHits_(0)
, cacheMisses_(0)
, evictionCount_(0) {
}
/** /**
* @brief * @brief
@ -33,12 +28,8 @@ TexturePool::TexturePool()
* *
*/ */
TexturePool::TexturePool(Scene *scene, size_t maxMemoryUsage) TexturePool::TexturePool(Scene *scene, size_t maxMemoryUsage)
: scene_(scene) : scene_(scene), maxMemoryUsage_(maxMemoryUsage), currentMemoryUsage_(0),
, maxMemoryUsage_(maxMemoryUsage) cacheHits_(0), cacheMisses_(0), evictionCount_(0) {
, currentMemoryUsage_(0)
, cacheHits_(0)
, cacheMisses_(0)
, evictionCount_(0) {
E2D_LOG_INFO("TexturePool 已创建,最大内存: {} 字节", maxMemoryUsage); E2D_LOG_INFO("TexturePool 已创建,最大内存: {} 字节", maxMemoryUsage);
} }
@ -77,7 +68,8 @@ TexturePool::~TexturePool() {
* *
* *
*/ */
TextureRef TexturePool::load(const std::string& path, const TextureLoadOptions& options) { TextureRef TexturePool::load(const std::string &path,
const TextureLoadOptions &options) {
return load(path, Rect::Zero(), options); return load(path, Rect::Zero(), options);
} }
@ -112,11 +104,11 @@ TextureRef TexturePool::load(const std::string& path, const Rect& region,
cacheMisses_.fetch_add(1, std::memory_order_relaxed); cacheMisses_.fetch_add(1, std::memory_order_relaxed);
// 获取渲染后端 // 获取渲染后端
RenderBackend* backend = nullptr; Renderer *backend = nullptr;
if (scene_) { if (scene_) {
// 假设 Scene 有获取 RenderBackend 的方法 // 假设 Scene 有获取 Renderer 的方法
// 这里需要根据实际接口调整 // 这里需要根据实际接口调整
backend = nullptr; // TODO: 从 Scene 获取 RenderBackend backend = nullptr; // TODO: 从 Scene 获取 Renderer
} }
if (!backend) { if (!backend) {
@ -135,7 +127,8 @@ TextureRef TexturePool::load(const std::string& path, const Rect& region,
size_t memorySize = calculateTextureMemory(texture.get()); size_t memorySize = calculateTextureMemory(texture.get());
// 检查内存限制 // 检查内存限制
if (maxMemoryUsage_ > 0 && currentMemoryUsage_ + memorySize > maxMemoryUsage_) { if (maxMemoryUsage_ > 0 &&
currentMemoryUsage_ + memorySize > maxMemoryUsage_) {
// 尝试淘汰 // 尝试淘汰
evictLRU(currentMemoryUsage_ + memorySize - maxMemoryUsage_); evictLRU(currentMemoryUsage_ + memorySize - maxMemoryUsage_);
@ -172,8 +165,9 @@ TextureRef TexturePool::load(const std::string& path, const Rect& region,
* *
* *
*/ */
TextureRef TexturePool::loadFromMemory(const uint8_t* data, int width, int height, TextureRef TexturePool::loadFromMemory(const uint8_t *data, int width,
int channels, const std::string& key) { int height, int channels,
const std::string &key) {
TextureKey textureKey(key); TextureKey textureKey(key);
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
@ -190,9 +184,9 @@ TextureRef TexturePool::loadFromMemory(const uint8_t* data, int width, int heigh
cacheMisses_.fetch_add(1, std::memory_order_relaxed); cacheMisses_.fetch_add(1, std::memory_order_relaxed);
// 获取渲染后端 // 获取渲染后端
RenderBackend* backend = nullptr; Renderer *backend = nullptr;
if (scene_) { if (scene_) {
backend = nullptr; // TODO: 从 Scene 获取 RenderBackend backend = nullptr; // TODO: 从 Scene 获取 Renderer
} }
if (!backend) { if (!backend) {
@ -211,7 +205,8 @@ TextureRef TexturePool::loadFromMemory(const uint8_t* data, int width, int heigh
size_t memorySize = calculateTextureMemory(texture.get()); size_t memorySize = calculateTextureMemory(texture.get());
// 检查内存限制 // 检查内存限制
if (maxMemoryUsage_ > 0 && currentMemoryUsage_ + memorySize > maxMemoryUsage_) { if (maxMemoryUsage_ > 0 &&
currentMemoryUsage_ + memorySize > maxMemoryUsage_) {
evictLRU(currentMemoryUsage_ + memorySize - maxMemoryUsage_); evictLRU(currentMemoryUsage_ + memorySize - maxMemoryUsage_);
if (currentMemoryUsage_ + memorySize > maxMemoryUsage_) { if (currentMemoryUsage_ + memorySize > maxMemoryUsage_) {
@ -221,7 +216,8 @@ TextureRef TexturePool::loadFromMemory(const uint8_t* data, int width, int heigh
} }
// 创建缓存条目 // 创建缓存条目
auto result = cache_.emplace(textureKey, TexturePoolEntry(nullptr, textureKey, 0)); auto result =
cache_.emplace(textureKey, TexturePoolEntry(nullptr, textureKey, 0));
if (result.second) { if (result.second) {
result.first->second.texture = texture; result.first->second.texture = texture;
result.first->second.memorySize = memorySize; result.first->second.memorySize = memorySize;
@ -243,7 +239,8 @@ TextureRef TexturePool::loadFromMemory(const uint8_t* data, int width, int heigh
* *
* *
*/ */
TextureRef TexturePool::getOrLoad(const std::string& path, const TextureLoadOptions& options) { TextureRef TexturePool::getOrLoad(const std::string &path,
const TextureLoadOptions &options) {
return getOrLoad(path, Rect::Zero(), options); return getOrLoad(path, Rect::Zero(), options);
} }
@ -277,9 +274,9 @@ TextureRef TexturePool::getOrLoad(const std::string& path, const Rect& region,
cacheMisses_.fetch_add(1, std::memory_order_relaxed); cacheMisses_.fetch_add(1, std::memory_order_relaxed);
RenderBackend* backend = nullptr; Renderer *backend = nullptr;
if (scene_) { if (scene_) {
backend = nullptr; // TODO: 从 Scene 获取 RenderBackend backend = nullptr; // TODO: 从 Scene 获取 Renderer
} }
if (!backend) { if (!backend) {
@ -295,7 +292,8 @@ TextureRef TexturePool::getOrLoad(const std::string& path, const Rect& region,
size_t memorySize = calculateTextureMemory(texture.get()); size_t memorySize = calculateTextureMemory(texture.get());
if (maxMemoryUsage_ > 0 && currentMemoryUsage_ + memorySize > maxMemoryUsage_) { if (maxMemoryUsage_ > 0 &&
currentMemoryUsage_ + memorySize > maxMemoryUsage_) {
evictLRU(currentMemoryUsage_ + memorySize - maxMemoryUsage_); evictLRU(currentMemoryUsage_ + memorySize - maxMemoryUsage_);
if (currentMemoryUsage_ + memorySize > maxMemoryUsage_) { if (currentMemoryUsage_ + memorySize > maxMemoryUsage_) {
@ -352,7 +350,8 @@ uint32_t TexturePool::release(const TextureKey& key) {
auto it = cache_.find(key); auto it = cache_.find(key);
if (it != cache_.end()) { if (it != cache_.end()) {
uint32_t count = it->second.refCount.fetch_sub(1, std::memory_order_relaxed); uint32_t count =
it->second.refCount.fetch_sub(1, std::memory_order_relaxed);
return count > 0 ? count - 1 : 0; return count > 0 ? count - 1 : 0;
} }
return 0; return 0;

View File

@ -511,12 +511,12 @@ void Node::onUpdate(float dt) {
} }
/** /**
* @brief * @brief
* @param renderer * @param renderer
* *
* *
*/ */
void Node::onRender(RenderBackend &renderer) { void Node::onRender(Renderer &renderer) {
if (!visible_) if (!visible_)
return; return;
@ -579,7 +579,7 @@ void Node::update(float dt) { onUpdate(dt); }
* *
* onRender进行渲染 * onRender进行渲染
*/ */
void Node::render(RenderBackend &renderer) { void Node::render(Renderer &renderer) {
if (childrenOrderDirty_) { if (childrenOrderDirty_) {
sortChildren(); sortChildren();
} }

View File

@ -1,8 +1,9 @@
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/graphics/core/render_command.h> #include <extra2d/graphics/core/render_command.h>
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/scene/scene.h> #include <extra2d/scene/scene.h>
#include <extra2d/services/logger_service.h> #include <extra2d/services/logger_service.h>
namespace extra2d { namespace extra2d {
/** /**
@ -48,7 +49,7 @@ void Scene::setViewportSize(const Size &size) {
* *
* *
*/ */
void Scene::renderScene(RenderBackend &renderer) { void Scene::renderScene(Renderer &renderer) {
if (!isVisible()) if (!isVisible())
return; return;
@ -65,7 +66,7 @@ void Scene::renderScene(RenderBackend &renderer) {
* *
* Application CameraService * Application CameraService
*/ */
void Scene::renderContent(RenderBackend &renderer) { void Scene::renderContent(Renderer &renderer) {
if (!isVisible()) if (!isVisible())
return; return;

View File

@ -1,7 +1,7 @@
#include <algorithm> #include <algorithm>
#include <extra2d/app/application.h> #include <extra2d/app/application.h>
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/graphics/core/render_command.h> #include <extra2d/graphics/core/render_command.h>
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/platform/keys.h> #include <extra2d/platform/keys.h>
#include <extra2d/scene/scene_manager.h> #include <extra2d/scene/scene_manager.h>
#include <extra2d/scene/transition_box_scene.h> #include <extra2d/scene/transition_box_scene.h>
@ -13,6 +13,7 @@
#include <extra2d/services/event_service.h> #include <extra2d/services/event_service.h>
#include <extra2d/services/logger_service.h> #include <extra2d/services/logger_service.h>
namespace extra2d { namespace extra2d {
namespace { namespace {
@ -89,13 +90,15 @@ void SceneManager::setupEventListeners() {
return; return;
} }
mouseMoveListener_ = eventService->addListener(EventType::MouseMoved, [this](Event &e) { mouseMoveListener_ =
eventService->addListener(EventType::MouseMoved, [this](Event &e) {
auto &mouseEvent = std::get<MouseMoveEvent>(e.data); auto &mouseEvent = std::get<MouseMoveEvent>(e.data);
mousePos_ = mouseEvent.position; mousePos_ = mouseEvent.position;
mouseDelta_ = mouseEvent.delta; mouseDelta_ = mouseEvent.delta;
}); });
mousePressListener_ = eventService->addListener(EventType::MouseButtonPressed, [this](Event &e) { mousePressListener_ = eventService->addListener(
EventType::MouseButtonPressed, [this](Event &e) {
auto &mouseEvent = std::get<MouseButtonEvent>(e.data); auto &mouseEvent = std::get<MouseButtonEvent>(e.data);
if (mouseEvent.button == static_cast<int>(Mouse::Left)) { if (mouseEvent.button == static_cast<int>(Mouse::Left)) {
mouseLeftPressed_ = true; mouseLeftPressed_ = true;
@ -103,7 +106,8 @@ void SceneManager::setupEventListeners() {
} }
}); });
mouseReleaseListener_ = eventService->addListener(EventType::MouseButtonReleased, [this](Event &e) { mouseReleaseListener_ = eventService->addListener(
EventType::MouseButtonReleased, [this](Event &e) {
auto &mouseEvent = std::get<MouseButtonEvent>(e.data); auto &mouseEvent = std::get<MouseButtonEvent>(e.data);
if (mouseEvent.button == static_cast<int>(Mouse::Left)) { if (mouseEvent.button == static_cast<int>(Mouse::Left)) {
mouseLeftReleased_ = true; mouseLeftReleased_ = true;
@ -111,7 +115,8 @@ void SceneManager::setupEventListeners() {
} }
}); });
scrollListener_ = eventService->addListener(EventType::MouseScrolled, [this](Event &e) { scrollListener_ =
eventService->addListener(EventType::MouseScrolled, [this](Event &e) {
auto &scrollEvent = std::get<MouseScrollEvent>(e.data); auto &scrollEvent = std::get<MouseScrollEvent>(e.data);
scrollDelta_ = scrollEvent.offset.y; scrollDelta_ = scrollEvent.offset.y;
}); });
@ -610,7 +615,7 @@ void SceneManager::update(float dt) {
* *
* 使 * 使
*/ */
void SceneManager::render(RenderBackend &renderer) { void SceneManager::render(Renderer &renderer) {
Color clearColor = Colors::Black; Color clearColor = Colors::Black;
if (!sceneStack_.empty()) { if (!sceneStack_.empty()) {
clearColor = sceneStack_.top()->getBackgroundColor(); clearColor = sceneStack_.top()->getBackgroundColor();

View File

@ -1,10 +1,11 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/graphics/core/render_command.h> #include <extra2d/graphics/core/render_command.h>
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/scene/shape_node.h> #include <extra2d/scene/shape_node.h>
#include <limits> #include <limits>
namespace extra2d { namespace extra2d {
/** /**
@ -196,24 +197,18 @@ Ptr<ShapeNode> ShapeNode::createFilledPolygon(const std::vector<Vec2> &points,
* @brief * @brief
* @param points * @param points
*/ */
void ShapeNode::setPoints(const std::vector<Vec2> &points) { void ShapeNode::setPoints(const std::vector<Vec2> &points) { points_ = points; }
points_ = points;
}
/** /**
* @brief * @brief
* @param point * @param point
*/ */
void ShapeNode::addPoint(const Vec2 &point) { void ShapeNode::addPoint(const Vec2 &point) { points_.push_back(point); }
points_.push_back(point);
}
/** /**
* @brief * @brief
*/ */
void ShapeNode::clearPoints() { void ShapeNode::clearPoints() { points_.clear(); }
points_.clear();
}
/** /**
* @brief * @brief
@ -271,7 +266,7 @@ Rect ShapeNode::getBounds() const {
* Node::onRender pushTransform * Node::onRender pushTransform
* 使 * 使
*/ */
void ShapeNode::onDraw(RenderBackend &renderer) { void ShapeNode::onDraw(Renderer &renderer) {
if (points_.empty()) { if (points_.empty()) {
return; return;
} }
@ -361,16 +356,16 @@ void ShapeNode::generateRenderCommand(std::vector<RenderCommand> &commands,
case ShapeType::Point: case ShapeType::Point:
if (!points_.empty()) { if (!points_.empty()) {
cmd.type = RenderCommandType::FilledCircle; cmd.type = RenderCommandType::FilledCircle;
cmd.data = cmd.data = CircleCommandData{
CircleCommandData{points_[0] + offset, lineWidth_ * 0.5f, color_, 8, 0.0f, true}; points_[0] + offset, lineWidth_ * 0.5f, color_, 8, 0.0f, true};
} }
break; break;
case ShapeType::Line: case ShapeType::Line:
if (points_.size() >= 2) { if (points_.size() >= 2) {
cmd.type = RenderCommandType::Line; cmd.type = RenderCommandType::Line;
cmd.data = LineCommandData{points_[0] + offset, points_[1] + offset, color_, cmd.data = LineCommandData{points_[0] + offset, points_[1] + offset,
lineWidth_}; color_, lineWidth_};
} }
break; break;
@ -380,14 +375,14 @@ void ShapeNode::generateRenderCommand(std::vector<RenderCommand> &commands,
cmd.type = RenderCommandType::FilledRect; cmd.type = RenderCommandType::FilledRect;
Rect rect(points_[0].x, points_[0].y, points_[2].x - points_[0].x, Rect rect(points_[0].x, points_[0].y, points_[2].x - points_[0].x,
points_[2].y - points_[0].y); points_[2].y - points_[0].y);
cmd.data = cmd.data = RectCommandData{Rect(rect.origin + offset, rect.size),
RectCommandData{Rect(rect.origin + offset, rect.size), color_, 0.0f, true}; color_, 0.0f, true};
} else { } else {
cmd.type = RenderCommandType::Rect; cmd.type = RenderCommandType::Rect;
Rect rect(points_[0].x, points_[0].y, points_[2].x - points_[0].x, Rect rect(points_[0].x, points_[0].y, points_[2].x - points_[0].x,
points_[2].y - points_[0].y); points_[2].y - points_[0].y);
cmd.data = cmd.data = RectCommandData{Rect(rect.origin + offset, rect.size),
RectCommandData{Rect(rect.origin + offset, rect.size), color_, lineWidth_, false}; color_, lineWidth_, false};
} }
} }
break; break;
@ -397,12 +392,12 @@ void ShapeNode::generateRenderCommand(std::vector<RenderCommand> &commands,
float radius = points_[1].x; float radius = points_[1].x;
if (filled_) { if (filled_) {
cmd.type = RenderCommandType::FilledCircle; cmd.type = RenderCommandType::FilledCircle;
cmd.data = cmd.data = CircleCommandData{points_[0] + offset, radius, color_,
CircleCommandData{points_[0] + offset, radius, color_, segments_, 0.0f, true}; segments_, 0.0f, true};
} else { } else {
cmd.type = RenderCommandType::Circle; cmd.type = RenderCommandType::Circle;
cmd.data = CircleCommandData{points_[0] + offset, radius, color_, segments_, cmd.data = CircleCommandData{points_[0] + offset, radius, color_,
lineWidth_, false}; segments_, lineWidth_, false};
} }
} }
break; break;
@ -435,7 +430,8 @@ void ShapeNode::generateRenderCommand(std::vector<RenderCommand> &commands,
cmd.data = PolygonCommandData{transformedPoints, color_, 0.0f, true}; cmd.data = PolygonCommandData{transformedPoints, color_, 0.0f, true};
} else { } else {
cmd.type = RenderCommandType::Polygon; cmd.type = RenderCommandType::Polygon;
cmd.data = PolygonCommandData{transformedPoints, color_, lineWidth_, false}; cmd.data =
PolygonCommandData{transformedPoints, color_, lineWidth_, false};
} }
} }
break; break;

View File

@ -1,7 +1,7 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <extra2d/graphics/core/render_backend.h>
#include <extra2d/graphics/core/render_command.h> #include <extra2d/graphics/core/render_command.h>
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/graphics/texture/texture.h> #include <extra2d/graphics/texture/texture.h>
#include <extra2d/scene/sprite.h> #include <extra2d/scene/sprite.h>
@ -127,7 +127,7 @@ Rect Sprite::getBounds() const {
* *
* 使 * 使
*/ */
void Sprite::onDraw(RenderBackend &renderer) { void Sprite::onDraw(Renderer &renderer) {
if (!texture_ || !texture_->isValid()) { if (!texture_ || !texture_->isValid()) {
return; return;
} }
@ -151,7 +151,7 @@ void Sprite::onDraw(RenderBackend &renderer) {
auto anchor = getAnchor(); auto anchor = getAnchor();
// 锚点由 RenderBackend 在绘制时处理,这里只传递位置和尺寸 // 锚点由 Renderer 在绘制时处理,这里只传递位置和尺寸
Rect destRect(worldX, worldY, width * worldScaleX, height * worldScaleY); Rect destRect(worldX, worldY, width * worldScaleX, height * worldScaleY);
// Adjust source rect for flipping // Adjust source rect for flipping
@ -204,7 +204,7 @@ void Sprite::generateRenderCommand(std::vector<RenderCommand> &commands,
auto anchor = getAnchor(); auto anchor = getAnchor();
// 锚点由 RenderBackend 在绘制时处理,这里只传递位置和尺寸 // 锚点由 Renderer 在绘制时处理,这里只传递位置和尺寸
Rect destRect(worldX, worldY, width * worldScaleX, height * worldScaleY); Rect destRect(worldX, worldY, width * worldScaleX, height * worldScaleY);
// 调整源矩形(翻转) // 调整源矩形(翻转)

View File

@ -1,11 +1,12 @@
#include <extra2d/scene/transition_box_scene.h> #include <algorithm>
#include <extra2d/app/application.h> #include <extra2d/app/application.h>
#include <extra2d/core/color.h> #include <extra2d/core/color.h>
#include <extra2d/graphics/core/render_backend.h> #include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/platform/glfw/glfw_window.h> #include <extra2d/platform/glfw/glfw_window.h>
#include <algorithm> #include <extra2d/scene/transition_box_scene.h>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
namespace extra2d { namespace extra2d {
/** /**
@ -25,9 +26,8 @@ TransitionBoxScene::TransitionBoxScene(float duration, Ptr<Scene> inScene,
* @param divisions * @param divisions
* @return * @return
*/ */
Ptr<TransitionBoxScene> TransitionBoxScene::create(float duration, Ptr<TransitionBoxScene>
Ptr<Scene> inScene, TransitionBoxScene::create(float duration, Ptr<Scene> inScene, int divisions) {
int divisions) {
return makePtr<TransitionBoxScene>(duration, inScene, divisions); return makePtr<TransitionBoxScene>(duration, inScene, divisions);
} }
@ -36,8 +36,7 @@ Ptr<TransitionBoxScene> TransitionBoxScene::create(float duration,
* *
* *
*/ */
void TransitionBoxScene::onTransitionStart() { void TransitionBoxScene::onTransitionStart() {}
}
/** /**
* @brief * @brief
@ -53,7 +52,7 @@ void TransitionBoxScene::updateTransition(float dt) {
* *
* *
*/ */
void TransitionBoxScene::renderContent(RenderBackend &renderer) { void TransitionBoxScene::renderContent(Renderer &renderer) {
auto &app = Application::get(); auto &app = Application::get();
float windowWidth = static_cast<float>(app.window()->width()); float windowWidth = static_cast<float>(app.window()->width());
float windowHeight = static_cast<float>(app.window()->height()); float windowHeight = static_cast<float>(app.window()->height());

View File

@ -1,6 +1,6 @@
#include <extra2d/app/application.h> #include <extra2d/app/application.h>
#include <extra2d/core/service_locator.h> #include <extra2d/core/service_locator.h>
#include <extra2d/graphics/core/render_backend.h> #include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/platform/glfw/glfw_window.h> #include <extra2d/platform/glfw/glfw_window.h>
#include <extra2d/scene/transition_fade_scene.h> #include <extra2d/scene/transition_fade_scene.h>
#include <extra2d/services/logger_service.h> #include <extra2d/services/logger_service.h>
@ -50,7 +50,7 @@ void TransitionFadeScene::updateTransition(float dt) {
} }
} }
void TransitionFadeScene::renderContent(RenderBackend &renderer) { void TransitionFadeScene::renderContent(Renderer &renderer) {
auto &app = Application::get(); auto &app = Application::get();
float windowWidth = static_cast<float>(app.window()->width()); float windowWidth = static_cast<float>(app.window()->width());
float windowHeight = static_cast<float>(app.window()->height()); float windowHeight = static_cast<float>(app.window()->height());

View File

@ -1,7 +1,8 @@
#include <extra2d/scene/transition_flip_scene.h>
#include <extra2d/core/math_types.h> #include <extra2d/core/math_types.h>
#include <extra2d/graphics/camera/camera.h> #include <extra2d/graphics/camera/camera.h>
#include <extra2d/graphics/core/render_backend.h> #include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/scene/transition_flip_scene.h>
namespace extra2d { namespace extra2d {
@ -22,9 +23,8 @@ TransitionFlipScene::TransitionFlipScene(float duration, Ptr<Scene> inScene,
* @param axis * @param axis
* @return * @return
*/ */
Ptr<TransitionFlipScene> TransitionFlipScene::create(float duration, Ptr<TransitionFlipScene>
Ptr<Scene> inScene, TransitionFlipScene::create(float duration, Ptr<Scene> inScene, Axis axis) {
Axis axis) {
return makePtr<TransitionFlipScene>(duration, inScene, axis); return makePtr<TransitionFlipScene>(duration, inScene, axis);
} }
@ -33,8 +33,7 @@ Ptr<TransitionFlipScene> TransitionFlipScene::create(float duration,
* *
* *
*/ */
void TransitionFlipScene::onTransitionStart() { void TransitionFlipScene::onTransitionStart() {}
}
/** /**
* @brief * @brief
@ -50,8 +49,9 @@ void TransitionFlipScene::updateTransition(float dt) {
* *
* *
*/ */
void TransitionFlipScene::renderContent(RenderBackend &renderer) { void TransitionFlipScene::renderContent(Renderer &renderer) {
float easeProgress = progress_ < 0.5f ? 2.0f * progress_ * progress_ float easeProgress = progress_ < 0.5f
? 2.0f * progress_ * progress_
: -1.0f + (4.0f - 2.0f * progress_) * progress_; : -1.0f + (4.0f - 2.0f * progress_) * progress_;
float angle = easeProgress * PI_F; float angle = easeProgress * PI_F;
@ -103,7 +103,6 @@ void TransitionFlipScene::renderContent(RenderBackend &renderer) {
} }
} }
} }
} }
} // namespace extra2d } // namespace extra2d

View File

@ -1,7 +1,8 @@
#include <extra2d/scene/transition_scale_scene.h>
#include <extra2d/graphics/camera/camera.h>
#include <extra2d/graphics/core/render_backend.h>
#include <algorithm> #include <algorithm>
#include <extra2d/graphics/camera/camera.h>
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/scene/transition_scale_scene.h>
namespace extra2d { namespace extra2d {
@ -29,8 +30,7 @@ Ptr<TransitionScaleScene> TransitionScaleScene::create(float duration,
* *
* *
*/ */
void TransitionScaleScene::onTransitionStart() { void TransitionScaleScene::onTransitionStart() {}
}
/** /**
* @brief * @brief
@ -46,8 +46,9 @@ void TransitionScaleScene::updateTransition(float dt) {
* *
* *
*/ */
void TransitionScaleScene::renderContent(RenderBackend &renderer) { void TransitionScaleScene::renderContent(Renderer &renderer) {
float easeProgress = progress_ < 0.5f ? 2.0f * progress_ * progress_ float easeProgress = progress_ < 0.5f
? 2.0f * progress_ * progress_
: -1.0f + (4.0f - 2.0f * progress_) * progress_; : -1.0f + (4.0f - 2.0f * progress_) * progress_;
if (outScene_) { if (outScene_) {
@ -83,7 +84,6 @@ void TransitionScaleScene::renderContent(RenderBackend &renderer) {
camera->setZoom(originalZoom); camera->setZoom(originalZoom);
} }
} }
} }
} // namespace extra2d } // namespace extra2d

View File

@ -1,5 +1,5 @@
#include <extra2d/core/service_locator.h> #include <extra2d/core/service_locator.h>
#include <extra2d/graphics/core/render_backend.h> #include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/scene/transition_scene.h> #include <extra2d/scene/transition_scene.h>
#include <extra2d/services/logger_service.h> #include <extra2d/services/logger_service.h>
@ -119,7 +119,7 @@ void TransitionScene::cancel(bool immediate) {
* *
* 退 * 退
*/ */
void TransitionScene::renderContent(RenderBackend &renderer) { void TransitionScene::renderContent(Renderer &renderer) {
drawOutScene(renderer); drawOutScene(renderer);
drawInScene(renderer); drawInScene(renderer);
} }
@ -128,7 +128,7 @@ void TransitionScene::renderContent(RenderBackend &renderer) {
* @brief 退 * @brief 退
* @param renderer * @param renderer
*/ */
void TransitionScene::drawOutScene(RenderBackend &renderer) { void TransitionScene::drawOutScene(Renderer &renderer) {
if (outScene_) { if (outScene_) {
outScene_->renderContent(renderer); outScene_->renderContent(renderer);
} }
@ -138,7 +138,7 @@ void TransitionScene::drawOutScene(RenderBackend &renderer) {
* @brief * @brief
* @param renderer * @param renderer
*/ */
void TransitionScene::drawInScene(RenderBackend &renderer) { void TransitionScene::drawInScene(Renderer &renderer) {
if (inScene_) { if (inScene_) {
inScene_->renderContent(renderer); inScene_->renderContent(renderer);
} }

View File

@ -1,7 +1,8 @@
#include <extra2d/scene/transition_slide_scene.h>
#include <extra2d/graphics/camera/camera.h>
#include <extra2d/graphics/core/render_backend.h>
#include <algorithm> #include <algorithm>
#include <extra2d/graphics/camera/camera.h>
#include <extra2d/graphics/opengl/gl_renderer.h>
#include <extra2d/scene/transition_slide_scene.h>
namespace extra2d { namespace extra2d {
@ -22,8 +23,9 @@ TransitionSlideScene::TransitionSlideScene(float duration, Ptr<Scene> inScene,
* @param direction * @param direction
* @return * @return
*/ */
Ptr<TransitionSlideScene> TransitionSlideScene::create( Ptr<TransitionSlideScene>
float duration, Ptr<Scene> inScene, TransitionDirection direction) { TransitionSlideScene::create(float duration, Ptr<Scene> inScene,
TransitionDirection direction) {
return makePtr<TransitionSlideScene>(duration, inScene, direction); return makePtr<TransitionSlideScene>(duration, inScene, direction);
} }
@ -32,8 +34,7 @@ Ptr<TransitionSlideScene> TransitionSlideScene::create(
* *
* *
*/ */
void TransitionSlideScene::onTransitionStart() { void TransitionSlideScene::onTransitionStart() {}
}
/** /**
* @brief * @brief
@ -49,7 +50,7 @@ void TransitionSlideScene::updateTransition(float dt) {
* *
* *
*/ */
void TransitionSlideScene::renderContent(RenderBackend &renderer) { void TransitionSlideScene::renderContent(Renderer &renderer) {
float screenWidth = 800.0f; float screenWidth = 800.0f;
float screenHeight = 600.0f; float screenHeight = 600.0f;
@ -67,7 +68,8 @@ void TransitionSlideScene::renderContent(RenderBackend &renderer) {
} }
} }
float easeProgress = progress_ < 0.5f ? 2.0f * progress_ * progress_ float easeProgress = progress_ < 0.5f
? 2.0f * progress_ * progress_
: -1.0f + (4.0f - 2.0f * progress_) * progress_; : -1.0f + (4.0f - 2.0f * progress_) * progress_;
if (outScene_) { if (outScene_) {
@ -135,7 +137,6 @@ void TransitionSlideScene::renderContent(RenderBackend &renderer) {
camera->setPos(originalPos); camera->setPos(originalPos);
} }
} }
} }
} // namespace extra2d } // namespace extra2d

View File

@ -68,9 +68,7 @@ bool SceneService::hasScene(const std::string &name) const {
return manager_.hasScene(name); return manager_.hasScene(name);
} }
void SceneService::render(RenderBackend &renderer) { void SceneService::render(Renderer &renderer) { manager_.render(renderer); }
manager_.render(renderer);
}
void SceneService::collectRenderCommands(std::vector<RenderCommand> &commands) { void SceneService::collectRenderCommands(std::vector<RenderCommand> &commands) {
manager_.collectRenderCommands(commands); manager_.collectRenderCommands(commands);

View File

@ -96,7 +96,7 @@ flowchart TB
subgraph Graphics["Graphics (图形系统)"] subgraph Graphics["Graphics (图形系统)"]
direction TB direction TB
RESOURCES[Resources<br/>资源抽象层] RESOURCES[Resources<br/>资源抽象层]
BACKEND[RenderBackend<br/>渲染后端] BACKEND[Renderer<br/>渲染后端]
BATCH[Batch Layer<br/>批处理层] BATCH[Batch Layer<br/>批处理层]
GL[OpenGL Backend<br/>OpenGL 后端] GL[OpenGL Backend<br/>OpenGL 后端]
VK[Vulkan Backend<br/>Vulkan 后端] VK[Vulkan Backend<br/>Vulkan 后端]

View File

@ -229,9 +229,9 @@ cameraService->setZoom(2.0f);
### 渲染后端接口 ### 渲染后端接口
```cpp ```cpp
class RenderBackend { class Renderer {
public: public:
virtual ~RenderBackend() = default; virtual ~Renderer() = default;
// 生命周期 // 生命周期
virtual bool init(IWindow* window) = 0; virtual bool init(IWindow* window) = 0;
@ -276,7 +276,7 @@ public:
virtual void drawText(const FontAtlas &font, const std::string &text, const Vec2 &position, const Color &color) = 0; virtual void drawText(const FontAtlas &font, const std::string &text, const Vec2 &position, const Color &color) = 0;
// 工厂方法 // 工厂方法
static UniquePtr<RenderBackend> create(BackendType type); static UniquePtr<Renderer> create(BackendType type);
}; };
``` ```
@ -407,7 +407,7 @@ public:
virtual void onEnter(); virtual void onEnter();
virtual void onExit(); virtual void onExit();
virtual void onUpdate(float dt); virtual void onUpdate(float dt);
virtual void onRender(RenderBackend& renderer); virtual void onRender(Renderer& renderer);
}; };
``` ```

View File

@ -90,7 +90,7 @@ public:
* @brief * @brief
* @param renderer * @param renderer
*/ */
void onRender(RenderBackend &renderer) override { Scene::onRender(renderer); } void onRender(Renderer &renderer) override { Scene::onRender(renderer); }
}; };
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -107,9 +107,7 @@ int main(int argc, char *argv[]) {
cfg.priority = 0; cfg.priority = 0;
}); });
app.use<RenderModule>([](auto &cfg) { app.use<RenderModule>([](auto &cfg) { cfg.priority = 10; });
cfg.priority = 10;
});
std::cout << "Initializing application..." << std::endl; std::cout << "Initializing application..." << std::endl;
if (!app.init()) { if (!app.init()) {

View File

@ -29,7 +29,7 @@ public:
time_ = 0.0f; time_ = 0.0f;
} }
} }
void onRender(RenderBackend &renderer) override { Scene::onRender(renderer); } void onRender(Renderer &renderer) override { Scene::onRender(renderer); }
private: private:
float time_ = 0.0f; float time_ = 0.0f;
@ -44,9 +44,7 @@ int main(int argc, char *argv[]) {
cfg.w = 800; cfg.w = 800;
cfg.h = 600; cfg.h = 600;
}); });
app.use<RenderModule>([](auto &cfg) { app.use<RenderModule>([](auto &cfg) { cfg.priority = 10; });
cfg.priority = 10;
});
app.use<HelloModule>([](auto &cfg) { app.use<HelloModule>([](auto &cfg) {
cfg.greeting = "Hello from custom module!"; cfg.greeting = "Hello from custom module!";
cfg.repeatCount = 3; cfg.repeatCount = 3;

View File

@ -2,7 +2,7 @@
* @file main.cpp * @file main.cpp
* @brief Extra2D * @brief Extra2D
* *
* 使 RenderBackend * 使 Renderer
* OpenGL * OpenGL
*/ */
@ -40,14 +40,14 @@ public:
void onExit() override { texture_.reset(); } void onExit() override { texture_.reset(); }
void onRender(RenderBackend &renderer) override { void onRender(Renderer &renderer) override {
Scene::onRender(renderer); Scene::onRender(renderer);
if (!texture_) { if (!texture_) {
return; return;
} }
// 使用 RenderBackend 的抽象接口绘制图片 // 使用 Renderer 的抽象接口绘制图片
// 不依赖任何特定后端(如 OpenGL // 不依赖任何特定后端(如 OpenGL
// 自动批处理:无需手动调用 begin/endSpriteBatch // 自动批处理:无需手动调用 begin/endSpriteBatch
@ -70,7 +70,7 @@ public:
float x = (windowWidth - displayWidth) * 0.5f; float x = (windowWidth - displayWidth) * 0.5f;
float y = (windowHeight - displayHeight) * 0.5f; float y = (windowHeight - displayHeight) * 0.5f;
// 使用 RenderBackend 的 drawSprite 方法绘制图片 // 使用 Renderer 的 drawSprite 方法绘制图片
// 参数:纹理、目标矩形、源矩形、颜色、旋转角度、锚点 // 参数:纹理、目标矩形、源矩形、颜色、旋转角度、锚点
Rect destRect(x, y, displayWidth, displayHeight); Rect destRect(x, y, displayWidth, displayHeight);
Rect srcRect(0, 0, imgWidth, imgHeight); Rect srcRect(0, 0, imgWidth, imgHeight);
@ -80,11 +80,11 @@ public:
// 注意:无需手动调用 renderer.endSpriteBatch(),帧结束时会自动刷新 // 注意:无需手动调用 renderer.endSpriteBatch(),帧结束时会自动刷新
} }
void setRenderer(RenderBackend *renderer) { renderer_ = renderer; } void setRenderer(Renderer *renderer) { renderer_ = renderer; }
private: private:
Ptr<Texture> texture_; Ptr<Texture> texture_;
RenderBackend *renderer_ = nullptr; Renderer *renderer_ = nullptr;
}; };
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -103,9 +103,7 @@ int main(int argc, char *argv[]) {
cfg.priority = 0; cfg.priority = 0;
}); });
app.use<RenderModule>([](auto &cfg) { app.use<RenderModule>([](auto &cfg) { cfg.priority = 10; });
cfg.priority = 10;
});
if (!app.init()) { if (!app.init()) {
std::cerr << "Failed to initialize application!" << std::endl; std::cerr << "Failed to initialize application!" << std::endl;
@ -127,7 +125,7 @@ int main(int argc, char *argv[]) {
} }
// 获取渲染器 // 获取渲染器
RenderBackend *renderer = app.renderer(); Renderer *renderer = app.renderer();
// 创建并配置场景 // 创建并配置场景
auto scene = makeShared<ImageDisplayScene>(); auto scene = makeShared<ImageDisplayScene>();

View File

@ -2,7 +2,7 @@
* @file main.cpp * @file main.cpp
* @brief Extra2D * @brief Extra2D
* *
* 使 RenderBackend * 使 Renderer
* OpenGL * OpenGL
*/ */
@ -40,7 +40,7 @@ public:
void onExit() override { font_.reset(); } void onExit() override { font_.reset(); }
void onRender(RenderBackend &renderer) override { void onRender(Renderer &renderer) override {
Scene::onRender(renderer); Scene::onRender(renderer);
if (!font_) { if (!font_) {
@ -85,21 +85,21 @@ public:
Color(0.5f, 0.5f, 0.5f, 1.0f)); Color(0.5f, 0.5f, 0.5f, 1.0f));
} }
void setRenderer(RenderBackend *renderer) { renderer_ = renderer; } void setRenderer(Renderer *renderer) { renderer_ = renderer; }
private: private:
void renderText(RenderBackend &renderer, const std::string &text, float x, void renderText(Renderer &renderer, const std::string &text, float x, float y,
float y, const Color &color) { const Color &color) {
if (!font_) { if (!font_) {
return; return;
} }
// 使用 RenderBackend 的 drawText 方法 // 使用 Renderer 的 drawText 方法
renderer.drawText(*font_, text, Vec2(x, y), color); renderer.drawText(*font_, text, Vec2(x, y), color);
} }
Ptr<FontAtlas> font_; Ptr<FontAtlas> font_;
RenderBackend *renderer_ = nullptr; Renderer *renderer_ = nullptr;
}; };
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
@ -139,7 +139,7 @@ int main(int argc, char *argv[]) {
} }
// 获取渲染器 // 获取渲染器
RenderBackend *renderer = app.renderer(); Renderer *renderer = app.renderer();
// 创建并配置场景 // 创建并配置场景
auto scene = makeShared<TextRenderingScene>(); auto scene = makeShared<TextRenderingScene>();