#include #include #include #include namespace extra2d { RendererModule::RendererModule() = default; RendererModule::~RendererModule() = default; RendererModule::RendererModule(RendererModule &&other) noexcept : materialPool_(std::move(other.materialPool_)), meshPool_(std::move(other.meshPool_)), texturePool_(std::move(other.texturePool_)), commandBuffer_(std::move(other.commandBuffer_)), commandCount_(other.commandCount_), uniformManager_(std::move(other.uniformManager_)), defaultMaterialHandle_(other.defaultMaterialHandle_), defaultQuadHandle_(other.defaultQuadHandle_), defaultTextureHandle_(other.defaultTextureHandle_), onRenderBeginListener_(std::move(other.onRenderBeginListener_)), onRenderSubmitListener_(std::move(other.onRenderSubmitListener_)), onRenderEndListener_(std::move(other.onRenderEndListener_)), onResizeListener_(std::move(other.onResizeListener_)), onShowListener_(std::move(other.onShowListener_)), glInitialized_(other.glInitialized_), stats_(other.stats_), viewportX_(other.viewportX_), viewportY_(other.viewportY_), viewportWidth_(other.viewportWidth_), viewportHeight_(other.viewportHeight_) { // 重置源对象状态 other.commandCount_ = 0; other.defaultMaterialHandle_ = INVALID_MATERIAL_HANDLE; other.defaultQuadHandle_ = INVALID_MESH_HANDLE; other.defaultTextureHandle_ = INVALID_TEXTURE_HANDLE; other.glInitialized_ = false; other.stats_ = {}; other.viewportX_ = 0; other.viewportY_ = 0; other.viewportWidth_ = 0; other.viewportHeight_ = 0; } RendererModule &RendererModule::operator=(RendererModule &&other) noexcept { if (this != &other) { // 清理当前资源 if (glInitialized_) { destroyDefaultResources(); uniformManager_.shutdown(); } // 移动资源 materialPool_ = std::move(other.materialPool_); meshPool_ = std::move(other.meshPool_); texturePool_ = std::move(other.texturePool_); commandBuffer_ = std::move(other.commandBuffer_); commandCount_ = other.commandCount_; uniformManager_ = std::move(other.uniformManager_); defaultMaterialHandle_ = other.defaultMaterialHandle_; defaultQuadHandle_ = other.defaultQuadHandle_; defaultTextureHandle_ = other.defaultTextureHandle_; onRenderBeginListener_ = std::move(other.onRenderBeginListener_); onRenderSubmitListener_ = std::move(other.onRenderSubmitListener_); onRenderEndListener_ = std::move(other.onRenderEndListener_); onResizeListener_ = std::move(other.onResizeListener_); onShowListener_ = std::move(other.onShowListener_); glInitialized_ = other.glInitialized_; stats_ = other.stats_; viewportX_ = other.viewportX_; viewportY_ = other.viewportY_; viewportWidth_ = other.viewportWidth_; viewportHeight_ = other.viewportHeight_; // 重置源对象状态 other.commandCount_ = 0; other.defaultMaterialHandle_ = INVALID_MATERIAL_HANDLE; other.defaultQuadHandle_ = INVALID_MESH_HANDLE; other.defaultTextureHandle_ = INVALID_TEXTURE_HANDLE; other.glInitialized_ = false; other.stats_ = {}; other.viewportX_ = 0; other.viewportY_ = 0; other.viewportWidth_ = 0; other.viewportHeight_ = 0; } return *this; } bool RendererModule::init() { E2D_LOG_INFO("Initializing RendererModule..."); // 绑定事件监听器 onRenderBeginListener_.bind([this]() { onRenderBegin(); }); onRenderSubmitListener_.bind( [this](const RenderCommand &cmd) { onRenderSubmit(cmd); }); onRenderEndListener_.bind([this]() { onRenderEnd(); }); onResizeListener_.bind([this](int32_t w, int32_t h) { onResize(w, h); }); // 延迟 GL 初始化到窗口显示时 onShowListener_.bind([this]() { onWindowShow(); }); E2D_LOG_INFO("RendererModule initialized (waiting for GL context)"); return true; } void RendererModule::onWindowShow() { if (glInitialized_) { return; } E2D_LOG_INFO("Initializing OpenGL context..."); // 初始化 UBO 管理器(需要 GL 上下文) if (!uniformManager_.initialize()) { E2D_LOG_ERROR("Failed to initialize UniformBufferManager"); return; } // 创建默认资源(需要 GL 上下文) if (!createDefaultResources()) { E2D_LOG_ERROR("Failed to create default resources"); return; } // 设置默认视口 setViewport(0, 0, 800, 600); // 启用深度测试和混合 glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glInitialized_ = true; E2D_LOG_INFO("OpenGL context initialized successfully"); } void RendererModule::shutdown() { E2D_LOG_INFO("Shutting down RendererModule..."); // 只有在 GL 初始化后才销毁 GL 相关资源 if (glInitialized_) { // 销毁默认资源 destroyDefaultResources(); // 关闭 UBO 管理器 uniformManager_.shutdown(); } // 清理资源池 materialPool_.slots.clear(); while (!materialPool_.freeIndices.empty()) materialPool_.freeIndices.pop(); meshPool_.slots.clear(); while (!meshPool_.freeIndices.empty()) meshPool_.freeIndices.pop(); texturePool_.slots.clear(); while (!texturePool_.freeIndices.empty()) texturePool_.freeIndices.pop(); glInitialized_ = false; E2D_LOG_INFO("RendererModule shutdown complete"); } MaterialHandle RendererModule::registerMaterial(Ptr material) { uint64_t handle = materialPool_.acquire(); auto *slot = materialPool_.get(handle); if (slot) { slot->material = material; } return handle; } MeshHandle RendererModule::registerMesh(Ptr mesh) { uint64_t handle = meshPool_.acquire(); auto *slot = meshPool_.get(handle); if (slot) { slot->mesh = mesh; } return handle; } TextureHandle RendererModule::registerTexture(Ptr texture) { uint64_t handle = texturePool_.acquire(); auto *slot = texturePool_.get(handle); if (slot) { slot->texture = texture; } return handle; } void RendererModule::unregisterMaterial(MaterialHandle handle) { materialPool_.release(handle); } void RendererModule::unregisterMesh(MeshHandle handle) { meshPool_.release(handle); } void RendererModule::unregisterTexture(TextureHandle handle) { texturePool_.release(handle); } Ptr RendererModule::getMaterial(MaterialHandle handle) { auto *slot = materialPool_.get(handle); return slot ? slot->material : nullptr; } Ptr RendererModule::getMesh(MeshHandle handle) { auto *slot = meshPool_.get(handle); return slot ? slot->mesh : nullptr; } Ptr RendererModule::getTexture(TextureHandle handle) { auto *slot = texturePool_.get(handle); return slot ? slot->texture : nullptr; } void RendererModule::setViewport(int32 x, int32 y, int32 width, int32 height) { viewportX_ = x; viewportY_ = y; viewportWidth_ = width; viewportHeight_ = height; glViewport(x, y, width, height); } void RendererModule::clear(const Color &color, uint32_t flags) { GLbitfield mask = 0; if (flags & CLEAR_COLOR_FLAG) { glClearColor(color.r, color.g, color.b, color.a); mask |= GL_COLOR_BUFFER_BIT; } if (flags & CLEAR_DEPTH_FLAG) { mask |= GL_DEPTH_BUFFER_BIT; } if (flags & CLEAR_STENCIL_FLAG) { mask |= GL_STENCIL_BUFFER_BIT; } if (mask != 0) { glClear(mask); } } void RendererModule::onRenderBegin() { // 如果 GL 未初始化,跳过渲染 if (!glInitialized_) { return; } // 清空命令缓冲区 commandCount_ = 0; // 重置统计 stats_ = {}; // 重置 UBO 管理器 uniformManager_.resetMaterialUBOs(); } void RendererModule::onRenderSubmit(const RenderCommand &cmd) { // 如果 GL 未初始化,跳过提交 if (!glInitialized_) { return; } // 检查缓冲区是否已满 if (commandCount_ >= MAX_RENDER_COMMANDS) { E2D_LOG_WARN("Render command buffer full!"); return; } // 直接存入预分配缓冲区(无动态分配) commandBuffer_[commandCount_++] = cmd; stats_.commandsSubmitted++; } void RendererModule::onRenderEnd() { // 如果 GL 未初始化,跳过渲染 if (!glInitialized_) { return; } // 排序命令 sortCommands(); // 批处理并绘制 batchAndDraw(); // 输出统计 E2D_LOG_DEBUG("Render: {} commands, {} draw calls, {} batches", stats_.commandsExecuted, stats_.drawCalls, stats_.batches); } void RendererModule::onResize(int32 width, int32 height) { setViewport(0, 0, width, height); } void RendererModule::sortCommands() { // 使用 std::sort 对命令进行排序 std::sort(commandBuffer_.begin(), commandBuffer_.begin() + commandCount_, [](const RenderCommand &a, const RenderCommand &b) { return a.sortKey < b.sortKey; }); } void RendererModule::batchAndDraw() { MaterialHandle lastMaterial = INVALID_MATERIAL_HANDLE; MeshHandle lastMesh = INVALID_MESH_HANDLE; uint32_t batchStart = 0; uint32_t batchCount = 0; for (uint32_t i = 0; i < commandCount_; ++i) { const auto &cmd = commandBuffer_[i]; if (cmd.type != RenderCommandType::DrawMesh) { // 处理非绘制命令 if (batchCount > 0) { drawBatch(batchStart, batchCount, lastMaterial, lastMesh); stats_.batches++; batchCount = 0; } executeCommand(cmd); continue; } // 检查是否需要刷新批次 if (cmd.drawMesh.material != lastMaterial || cmd.drawMesh.mesh != lastMesh) { // 刷新上一批次 if (batchCount > 0) { drawBatch(batchStart, batchCount, lastMaterial, lastMesh); stats_.batches++; } lastMaterial = cmd.drawMesh.material; lastMesh = cmd.drawMesh.mesh; batchStart = i; batchCount = 1; } else { ++batchCount; } stats_.commandsExecuted++; } // 刷新最后一批 if (batchCount > 0) { drawBatch(batchStart, batchCount, lastMaterial, lastMesh); stats_.batches++; } } void RendererModule::drawBatch(uint32_t start, uint32_t count, MaterialHandle materialHandle, MeshHandle meshHandle) { auto material = getMaterial(materialHandle); auto mesh = getMesh(meshHandle); if (!material || !mesh) return; // 应用材质(绑定着色器、上传 UBO、绑定纹理) material->apply(uniformManager_); // 绑定网格 mesh->bind(); if (count == 1) { // 单绘制 mesh->draw(); } else { // 批量绘制 - 使用实例化渲染 // 上传变换矩阵到 UBO std::vector transforms; transforms.reserve(count * 16); for (uint32_t i = 0; i < count; ++i) { const auto &transform = commandBuffer_[start + i].drawMesh.transform; // 将 Transform 转换为 4x4 矩阵并添加到 transforms // 这里简化处理,实际需要完整的矩阵转换 float matrix[16]; transform.toMatrix(matrix); transforms.insert(transforms.end(), matrix, matrix + 16); } // 更新实例 UBO auto *instanceUBO = uniformManager_.acquireMaterialUBO( static_cast(transforms.size() * sizeof(float))); if (instanceUBO) { instanceUBO->update( transforms.data(), static_cast(transforms.size() * sizeof(float))); instanceUBO->bind(INSTANCE_UBO_BINDING); } // 实例化渲染 mesh->drawInstanced(count); } stats_.drawCalls++; } void RendererModule::executeCommand(const RenderCommand &cmd) { switch (cmd.type) { case RenderCommandType::SetViewport: setViewport(cmd.viewport.x, cmd.viewport.y, cmd.viewport.width, cmd.viewport.height); break; case RenderCommandType::Clear: clear(cmd.clear.color, cmd.clear.flags); break; default: break; } } bool RendererModule::createDefaultResources() { // 创建默认着色器 auto defaultShader = makePtr(); if (!defaultShader->loadFromFile("shader/default.vert", "shader/default.frag")) { E2D_LOG_ERROR("Failed to load default shader"); return false; } // 创建默认材质布局 auto defaultLayout = makePtr(); defaultLayout->addParam("tintColor", MaterialParamType::Color); defaultLayout->addParam("opacity", MaterialParamType::Float); defaultLayout->finalize(); // 创建默认材质 auto defaultMaterial = makePtr(); defaultMaterial->setLayout(defaultLayout); defaultMaterial->setShader(defaultShader); defaultMaterial->setColor("tintColor", Color::White); defaultMaterial->setFloat("opacity", 1.0f); defaultMaterialHandle_ = registerMaterial(defaultMaterial); // 创建默认四边形 auto defaultQuad = Mesh::createQuad(Vec2(1.0f, 1.0f)); defaultQuadHandle_ = registerMesh(defaultQuad); // 创建默认纹理(1x1 白色) auto defaultTexture = makePtr(); uint8_t whitePixel[4] = {255, 255, 255, 255}; defaultTexture->loadFromMemory(whitePixel, 1, 1, TextureFormat::RGBA8); defaultTextureHandle_ = registerTexture(defaultTexture); E2D_LOG_INFO("Default resources created"); return true; } void RendererModule::destroyDefaultResources() { if (defaultMaterialHandle_ != INVALID_MATERIAL_HANDLE) { unregisterMaterial(defaultMaterialHandle_); defaultMaterialHandle_ = INVALID_MATERIAL_HANDLE; } if (defaultQuadHandle_ != INVALID_MESH_HANDLE) { unregisterMesh(defaultQuadHandle_); defaultQuadHandle_ = INVALID_MESH_HANDLE; } if (defaultTextureHandle_ != INVALID_TEXTURE_HANDLE) { unregisterTexture(defaultTextureHandle_); defaultTextureHandle_ = INVALID_TEXTURE_HANDLE; } } } // namespace extra2d