#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include 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); /** * @brief 注册网格 * @param mesh 网格对象 * @return 网格句柄 */ MeshHandle registerMesh(Ptr mesh); /** * @brief 注册纹理 * @param texture 纹理对象 * @return 纹理句柄 */ TextureHandle registerTexture(Ptr 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 getMaterial(MaterialHandle handle); /** * @brief 获取网格 * @param handle 网格句柄 * @return 网格对象,无效句柄返回 nullptr */ Ptr getMesh(MeshHandle handle); /** * @brief 获取纹理 * @param handle 纹理句柄 * @return 纹理对象,无效句柄返回 nullptr */ Ptr 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; Ptr mesh; Ptr texture; uint32 generation = 0; bool active = false; }; /** * @brief 句柄池模板类 * * 管理资源句柄的分配和回收 */ template struct HandlePool { std::vector slots; std::queue freeIndices; uint32 nextGeneration = 1; /** * @brief 分配新句柄 * @return 编码后的句柄(高32位索引,低32位世代) */ uint64 acquire() { uint32 index; if (!freeIndices.empty()) { index = freeIndices.front(); freeIndices.pop(); } else { index = static_cast(slots.size()); slots.emplace_back(); } slots[index].active = true; slots[index].generation = nextGeneration++; // 编码句柄:高32位是索引,低32位是世代 return (static_cast(index) << 32) | slots[index].generation; } /** * @brief 释放句柄 * @param handle 要释放的句柄 */ void release(uint64 handle) { uint32 index = static_cast(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(handle >> 32); uint32 generation = static_cast(handle & 0xFFFFFFFF); if (index < slots.size() && slots[index].active && slots[index].generation == generation) { return &slots[index]; } return nullptr; } }; HandlePool materialPool_; // 材质资源池 HandlePool meshPool_; // 网格资源池 HandlePool texturePool_; // 纹理资源池 //=========================================================================== // 命令缓冲区 //=========================================================================== std::array 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