405 lines
11 KiB
C++
405 lines
11 KiB
C++
#pragma once
|
||
|
||
#include <array>
|
||
#include <event/events.h>
|
||
#include <module/module.h>
|
||
#include <module/module_registry.h>
|
||
#include <queue>
|
||
#include <renderer/material.h>
|
||
#include <renderer/mesh.h>
|
||
#include <renderer/render_types.h>
|
||
#include <renderer/shader.h>
|
||
#include <renderer/texture.h>
|
||
#include <renderer/uniform_buffer.h>
|
||
#include <vector>
|
||
|
||
namespace extra2d {
|
||
|
||
/**
|
||
* @brief 渲染器模块
|
||
*
|
||
* 核心渲染系统模块,负责:
|
||
* - 通过事件接收渲染命令
|
||
* - 自动批处理和排序
|
||
* - GPU 资源管理
|
||
* - 执行实际渲染
|
||
*/
|
||
class RendererModule : public Module {
|
||
// 自动注册到模块系统,优先级为 3(在 Window、Timer、Input 之后)
|
||
E2D_REGISTER_MODULE(RendererModule, "Renderer", 3)
|
||
|
||
public:
|
||
/**
|
||
* @brief 默认构造函数
|
||
*/
|
||
RendererModule();
|
||
|
||
/**
|
||
* @brief 析构函数
|
||
*/
|
||
~RendererModule() override;
|
||
|
||
// 禁止拷贝
|
||
RendererModule(const RendererModule &) = delete;
|
||
RendererModule &operator=(const RendererModule &) = delete;
|
||
|
||
// 允许移动
|
||
RendererModule(RendererModule &&) noexcept;
|
||
RendererModule &operator=(RendererModule &&) noexcept;
|
||
|
||
/**
|
||
* @brief 初始化模块
|
||
*
|
||
* 绑定事件监听器,等待窗口显示事件进行 GL 初始化
|
||
*
|
||
* @return 初始化是否成功
|
||
*/
|
||
bool init() override;
|
||
|
||
/**
|
||
* @brief 关闭模块
|
||
*
|
||
* 清理所有渲染资源
|
||
*/
|
||
void shutdown() override;
|
||
|
||
//===========================================================================
|
||
// 资源注册接口(供其他模块使用)
|
||
//===========================================================================
|
||
|
||
/**
|
||
* @brief 注册材质
|
||
* @param material 材质对象
|
||
* @return 材质句柄
|
||
*/
|
||
MaterialHandle registerMaterial(Ptr<Material> material);
|
||
|
||
/**
|
||
* @brief 注册网格
|
||
* @param mesh 网格对象
|
||
* @return 网格句柄
|
||
*/
|
||
MeshHandle registerMesh(Ptr<Mesh> mesh);
|
||
|
||
/**
|
||
* @brief 注册纹理
|
||
* @param texture 纹理对象
|
||
* @return 纹理句柄
|
||
*/
|
||
TextureHandle registerTexture(Ptr<Texture> texture);
|
||
|
||
/**
|
||
* @brief 注销材质
|
||
* @param handle 材质句柄
|
||
*/
|
||
void unregisterMaterial(MaterialHandle handle);
|
||
|
||
/**
|
||
* @brief 注销网格
|
||
* @param handle 网格句柄
|
||
*/
|
||
void unregisterMesh(MeshHandle handle);
|
||
|
||
/**
|
||
* @brief 注销纹理
|
||
* @param handle 纹理句柄
|
||
*/
|
||
void unregisterTexture(TextureHandle handle);
|
||
|
||
/**
|
||
* @brief 获取材质
|
||
* @param handle 材质句柄
|
||
* @return 材质对象,无效句柄返回 nullptr
|
||
*/
|
||
Ptr<Material> getMaterial(MaterialHandle handle);
|
||
|
||
/**
|
||
* @brief 获取网格
|
||
* @param handle 网格句柄
|
||
* @return 网格对象,无效句柄返回 nullptr
|
||
*/
|
||
Ptr<Mesh> getMesh(MeshHandle handle);
|
||
|
||
/**
|
||
* @brief 获取纹理
|
||
* @param handle 纹理句柄
|
||
* @return 纹理对象,无效句柄返回 nullptr
|
||
*/
|
||
Ptr<Texture> getTexture(TextureHandle handle);
|
||
|
||
//===========================================================================
|
||
// 默认资源
|
||
//===========================================================================
|
||
|
||
/**
|
||
* @brief 获取默认材质句柄
|
||
* @return 默认材质句柄
|
||
*/
|
||
MaterialHandle getDefaultMaterialHandle() const {
|
||
return defaultMaterialHandle_;
|
||
}
|
||
|
||
/**
|
||
* @brief 获取默认四边形网格句柄
|
||
* @return 默认四边形网格句柄
|
||
*/
|
||
MeshHandle getDefaultQuadHandle() const { return defaultQuadHandle_; }
|
||
|
||
/**
|
||
* @brief 获取默认纹理句柄(1x1 白色纹理)
|
||
* @return 默认纹理句柄
|
||
*/
|
||
TextureHandle getDefaultTextureHandle() const {
|
||
return defaultTextureHandle_;
|
||
}
|
||
|
||
//===========================================================================
|
||
// 渲染状态设置
|
||
//===========================================================================
|
||
|
||
/**
|
||
* @brief 设置视口
|
||
* @param x 视口左上角 X 坐标
|
||
* @param y 视口左上角 Y 坐标
|
||
* @param width 视口宽度
|
||
* @param height 视口高度
|
||
*/
|
||
void setViewport(int32 x, int32 y, int32 width, int32 height);
|
||
|
||
/**
|
||
* @brief 清除缓冲区
|
||
* @param color 清除颜色
|
||
* @param flags 清除标志(组合使用 CLEAR_COLOR_FLAG, CLEAR_DEPTH_FLAG, CLEAR_STENCIL_FLAG)
|
||
*/
|
||
void clear(const Color &color, uint32 flags = CLEAR_COLOR_FLAG);
|
||
|
||
private:
|
||
//===========================================================================
|
||
// 事件处理器
|
||
//===========================================================================
|
||
|
||
/**
|
||
* @brief 渲染开始事件处理
|
||
*
|
||
* 清空命令缓冲区,重置统计信息
|
||
*/
|
||
void onRenderBegin();
|
||
|
||
/**
|
||
* @brief 渲染提交事件处理
|
||
* @param cmd 渲染命令
|
||
*/
|
||
void onRenderSubmit(const RenderCommand &cmd);
|
||
|
||
/**
|
||
* @brief 渲染结束事件处理
|
||
*
|
||
* 排序命令,批处理并执行绘制
|
||
*/
|
||
void onRenderEnd();
|
||
|
||
/**
|
||
* @brief 窗口大小改变事件处理
|
||
* @param width 新宽度
|
||
* @param height 新高度
|
||
*/
|
||
void onResize(int32 width, int32 height);
|
||
|
||
/**
|
||
* @brief 窗口显示事件处理
|
||
*
|
||
* 延迟 GL 初始化到窗口显示时
|
||
*/
|
||
void onWindowShow();
|
||
|
||
//===========================================================================
|
||
// 渲染执行
|
||
//===========================================================================
|
||
|
||
/**
|
||
* @brief 排序渲染命令
|
||
*
|
||
* 根据 sortKey 对命令进行排序以优化绘制顺序
|
||
*/
|
||
void sortCommands();
|
||
|
||
/**
|
||
* @brief 批处理并绘制
|
||
*
|
||
* 将相同材质和网格的命令合并批次绘制
|
||
*/
|
||
void batchAndDraw();
|
||
|
||
/**
|
||
* @brief 绘制批次
|
||
* @param start 批次起始索引
|
||
* @param count 批次命令数量
|
||
* @param materialHandle 材质句柄
|
||
* @param meshHandle 网格句柄
|
||
*/
|
||
void drawBatch(uint32 start, uint32 count, MaterialHandle materialHandle,
|
||
MeshHandle meshHandle);
|
||
|
||
/**
|
||
* @brief 执行单个渲染命令
|
||
* @param cmd 渲染命令
|
||
*/
|
||
void executeCommand(const RenderCommand &cmd);
|
||
|
||
//===========================================================================
|
||
// 默认资源创建与销毁
|
||
//===========================================================================
|
||
|
||
/**
|
||
* @brief 创建默认资源
|
||
* @return 创建是否成功
|
||
*/
|
||
bool createDefaultResources();
|
||
|
||
/**
|
||
* @brief 销毁默认资源
|
||
*/
|
||
void destroyDefaultResources();
|
||
|
||
//===========================================================================
|
||
// 资源句柄管理
|
||
//===========================================================================
|
||
|
||
/**
|
||
* @brief 资源槽位结构
|
||
*
|
||
* 用于管理资源对象和句柄生命周期
|
||
*/
|
||
struct ResourceSlot {
|
||
Ptr<Material> material;
|
||
Ptr<Mesh> mesh;
|
||
Ptr<Texture> texture;
|
||
uint32 generation = 0;
|
||
bool active = false;
|
||
};
|
||
|
||
/**
|
||
* @brief 句柄池模板类
|
||
*
|
||
* 管理资源句柄的分配和回收
|
||
*/
|
||
template <typename T> struct HandlePool {
|
||
std::vector<ResourceSlot> slots;
|
||
std::queue<uint32> freeIndices;
|
||
uint32 nextGeneration = 1;
|
||
|
||
/**
|
||
* @brief 分配新句柄
|
||
* @return 编码后的句柄(高32位索引,低32位世代)
|
||
*/
|
||
uint64 acquire() {
|
||
uint32 index;
|
||
if (!freeIndices.empty()) {
|
||
index = freeIndices.front();
|
||
freeIndices.pop();
|
||
} else {
|
||
index = static_cast<uint32>(slots.size());
|
||
slots.emplace_back();
|
||
}
|
||
|
||
slots[index].active = true;
|
||
slots[index].generation = nextGeneration++;
|
||
|
||
// 编码句柄:高32位是索引,低32位是世代
|
||
return (static_cast<uint64>(index) << 32) | slots[index].generation;
|
||
}
|
||
|
||
/**
|
||
* @brief 释放句柄
|
||
* @param handle 要释放的句柄
|
||
*/
|
||
void release(uint64 handle) {
|
||
uint32 index = static_cast<uint32>(handle >> 32);
|
||
if (index < slots.size() && slots[index].active) {
|
||
slots[index].active = false;
|
||
slots[index].material.reset();
|
||
slots[index].mesh.reset();
|
||
slots[index].texture.reset();
|
||
freeIndices.push(index);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 获取资源槽位
|
||
* @param handle 资源句柄
|
||
* @return 资源槽位指针,无效句柄返回 nullptr
|
||
*/
|
||
ResourceSlot *get(uint64 handle) {
|
||
uint32 index = static_cast<uint32>(handle >> 32);
|
||
uint32 generation = static_cast<uint32>(handle & 0xFFFFFFFF);
|
||
|
||
if (index < slots.size() && slots[index].active &&
|
||
slots[index].generation == generation) {
|
||
return &slots[index];
|
||
}
|
||
return nullptr;
|
||
}
|
||
};
|
||
|
||
HandlePool<Material> materialPool_; // 材质资源池
|
||
HandlePool<Mesh> meshPool_; // 网格资源池
|
||
HandlePool<Texture> texturePool_; // 纹理资源池
|
||
|
||
//===========================================================================
|
||
// 命令缓冲区
|
||
//===========================================================================
|
||
|
||
std::array<RenderCommand, MAX_RENDER_COMMANDS> commandBuffer_; // 预分配命令缓冲区
|
||
uint32 commandCount_ = 0; // 当前命令数量
|
||
|
||
//===========================================================================
|
||
// UBO 管理器
|
||
//===========================================================================
|
||
|
||
UniformBufferManager uniformManager_;
|
||
|
||
//===========================================================================
|
||
// 默认资源句柄
|
||
//===========================================================================
|
||
|
||
MaterialHandle defaultMaterialHandle_ = INVALID_MATERIAL_HANDLE;
|
||
MeshHandle defaultQuadHandle_ = INVALID_MESH_HANDLE;
|
||
TextureHandle defaultTextureHandle_ = INVALID_TEXTURE_HANDLE;
|
||
|
||
//===========================================================================
|
||
// 事件监听器
|
||
//===========================================================================
|
||
|
||
events::OnRenderBegin::Listener onRenderBeginListener_;
|
||
events::OnRenderSubmit::Listener onRenderSubmitListener_;
|
||
events::OnRenderEnd::Listener onRenderEndListener_;
|
||
events::OnResize::Listener onResizeListener_;
|
||
events::OnShow::Listener onShowListener_;
|
||
|
||
//===========================================================================
|
||
// 状态标志
|
||
//===========================================================================
|
||
|
||
bool glInitialized_ = false; // GL 是否已初始化
|
||
|
||
//===========================================================================
|
||
// 渲染统计
|
||
//===========================================================================
|
||
|
||
struct Stats {
|
||
uint32 commandsSubmitted = 0; // 提交的命令数
|
||
uint32 commandsExecuted = 0; // 执行的命令数
|
||
uint32 drawCalls = 0; // 绘制调用次数
|
||
uint32 batches = 0; // 批次数
|
||
} stats_;
|
||
|
||
//===========================================================================
|
||
// 视口状态
|
||
//===========================================================================
|
||
|
||
int32 viewportX_ = 0, viewportY_ = 0;
|
||
int32 viewportWidth_ = 0, viewportHeight_ = 0;
|
||
};
|
||
|
||
} // namespace extra2d
|