Extra2D/include/renderer/renderer_module.h

439 lines
12 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

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

#pragma once
#include <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 <renderer/viewport_adapter.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);
/**
* @brief 获取视口适配器
* @return 视口适配器引用
*/
ViewportAdapter &getViewportAdapter() { return viewportAdapter_; }
/**
* @brief 获取视口适配器const版本
* @return 视口适配器const引用
*/
const ViewportAdapter &getViewportAdapter() const { return viewportAdapter_; }
private:
//===========================================================================
// 事件处理器
//===========================================================================
/**
* @brief 渲染开始事件处理
*
* 清空命令缓冲区,重置统计信息
*/
void onRenderBegin();
/**
* @brief 渲染提交事件处理
* @param cmd 渲染命令
*/
void onRenderSubmit(const RenderCommand &cmd);
/**
* @brief 渲染设置相机事件处理
* @param viewProj 视图投影矩阵
*/
void onRenderSetCamera(const Mat4 &viewProj);
/**
* @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::OnRenderSetCamera::Listener onRenderSetCameraListener_;
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;
//===========================================================================
// 视口适配器
//===========================================================================
ViewportAdapter viewportAdapter_; // 视口适配器
//===========================================================================
// 相机矩阵
//===========================================================================
Mat4 viewProjectionMatrix_; // 当前视图投影矩阵
};
} // namespace extra2d