Extra2D/src/renderer/renderer_module.cpp

289 lines
7.9 KiB
C++
Raw Normal View History

#include <assets/assets_module.h>
#include <platform/window_module.h>
#include <renderer/instance_buffer.h>
#include <renderer/render_graph.h>
#include <renderer/renderer_module.h>
#include <renderer/rhi_module.h>
#include <utils/logger.h>
namespace extra2d {
RendererModule::RendererModule() = default;
RendererModule::~RendererModule() = default;
bool RendererModule::init() {
E2D_LOG_INFO("Initializing RendererModule...");
// 绑定事件监听器
onRenderBeginListener_.bind([this]() { onRenderBegin(); });
onRenderSubmitListener_.bind(
[this](const RenderCommand &cmd) { onRenderSubmit(cmd); });
onRenderSetCameraListener_.bind(
[this](const Mat4 &viewProj) { onRenderSetCamera(viewProj); });
onRenderEndListener_.bind([this]() { onRenderEnd(); });
onResizeListener_.bind([this](int32 w, int32 h) { onResize(w, h); });
onShowListener_.bind([this]() { onWindowShow(); });
E2D_LOG_INFO("RendererModule initialized (waiting for window show)");
return true;
}
void RendererModule::onWindowShow() {
if (initialized_) {
return;
}
E2D_LOG_INFO("Initializing RendererModule context...");
// 初始化 RHI 模块
auto *rhiModule = RHIModule::get();
if (!rhiModule) {
E2D_LOG_ERROR("RHIModule not available");
return;
}
if (!rhiModule->getDevice()) {
// RHI 设备尚未初始化,这是正常的时序问题
// RHIModule 会在窗口显示后初始化设备,然后再次触发此函数
E2D_LOG_INFO("RHIDevice not ready yet, waiting for RHI initialization...");
return;
}
// 初始化渲染图
if (!renderGraph_.initialize()) {
E2D_LOG_ERROR("Failed to initialize RenderGraph");
return;
}
commandQueue_ = renderGraph_.getCommandQueue();
// 添加默认的几何渲染通道
auto geometryPass = std::make_unique<GeometryRenderPass>("Geometry");
renderGraph_.addPass(std::move(geometryPass));
E2D_LOG_INFO("Added default geometry render pass");
auto windowModule = getModule<WindowModule>();
if (!windowModule) {
E2D_LOG_ERROR("WindowModule not available");
return;
}
setViewport(0, 0, static_cast<int32>(windowModule->getSize().w),
static_cast<int32>(windowModule->getSize().h));
initialized_ = true;
E2D_LOG_INFO("RendererModule context initialized successfully");
}
void RendererModule::shutdown() {
E2D_LOG_INFO("Shutting down RendererModule...");
renderGraph_.shutdown();
commandQueue_ = nullptr;
initialized_ = false;
// 注意:事件监听器是值类型,会在析构时自动清理
E2D_LOG_INFO("RendererModule shutdown complete");
}
RHIContext *RendererModule::getRHIContext() const {
auto *rhiModule = RHIModule::get();
if (rhiModule && rhiModule->getDevice()) {
return rhiModule->getDevice()->getContext();
}
return nullptr;
}
Handle<Material> RendererModule::getDefaultMaterialHandle() const {
auto *assets = getAssets();
return assets ? assets->getDefaultMaterial() : Handle<Material>::invalid();
}
Handle<Mesh> RendererModule::getDefaultQuadHandle() const {
auto *assets = getAssets();
return assets ? assets->getDefaultQuad() : Handle<Mesh>::invalid();
}
Handle<Texture> RendererModule::getDefaultTextureHandle() const {
auto *assets = getAssets();
return assets ? assets->getDefaultTexture() : Handle<Texture>::invalid();
}
void RendererModule::setViewport(int32 x, int32 y, int32 width, int32 height) {
viewportX_ = x;
viewportY_ = y;
viewportWidth_ = width;
viewportHeight_ = height;
viewportAdapter_.update(width, height);
// 更新渲染图输出尺寸
renderGraph_.setOutputSize(static_cast<uint32_t>(width),
static_cast<uint32_t>(height));
// 通过 RHI 设置视口
if (initialized_) {
auto *context = getRHIContext();
if (context) {
auto result = viewportAdapter_.getResult();
context->setViewport(static_cast<int32_t>(result.viewport.x),
static_cast<int32_t>(result.viewport.y),
static_cast<uint32_t>(result.viewport.w),
static_cast<uint32_t>(result.viewport.h));
}
}
}
void RendererModule::clear(const Color &color, uint32 flags) {
if (!initialized_)
return;
if (commandQueue_) {
commandQueue_->submitClear(color, flags);
}
}
void RendererModule::onRenderBegin() {
if (!initialized_) {
return;
}
// 重置统计
stats_ = {};
// 开始渲染帧 - 清空命令队列准备接收新的渲染命令
if (commandQueue_) {
commandQueue_->beginFrame();
}
// 帧开始
}
void RendererModule::onRenderSubmit(const RenderCommand &cmd) {
if (!initialized_ || !commandQueue_) {
E2D_LOG_WARN(
"onRenderSubmit: RendererModule not initialized or no command queue");
return;
}
(void)cmd; // 避免未使用警告
// 将渲染命令转换为绘制命令提交到队列
switch (cmd.type) {
case RenderCommandType::DrawMesh: {
auto *assets = getAssets();
if (!assets)
return;
// 获取材质,如果没有指定则使用默认材质
Material *material = assets->get(cmd.drawMesh.material);
if (!material) {
material = assets->get(assets->getDefaultMaterial());
}
// 获取网格,如果没有指定则使用默认四边形
Mesh *mesh = assets->get(cmd.drawMesh.mesh);
if (!mesh) {
mesh = assets->get(assets->getDefaultQuad());
}
if (material && mesh) {
Transform transform(cmd.drawMesh.pos, cmd.drawMesh.scale,
cmd.drawMesh.rot);
commandQueue_->submitDraw(Ptr<Material>(material), Ptr<Mesh>(mesh),
transform, cmd.drawMesh.color);
stats_.commandsSubmitted++;
} else {
E2D_LOG_WARN("Failed to submit draw command: material={}, mesh={}",
material ? "valid" : "null", mesh ? "valid" : "null");
}
break;
}
case RenderCommandType::DrawMeshInstanced: {
auto *assets = getAssets();
if (!assets)
return;
Material *material = assets->get(cmd.drawInstanced.material);
Mesh *mesh = assets->get(cmd.drawInstanced.mesh);
InstanceBuffer *instanceBuffer =
static_cast<InstanceBuffer *>(cmd.drawInstanced.instanceBuffer);
if (material && mesh && instanceBuffer && instanceBuffer->isValid()) {
commandQueue_->submitDrawInstanced(
Ptr<Material>(material), Ptr<Mesh>(mesh),
BufferHandle(instanceBuffer->getRHIBuffer()),
cmd.drawInstanced.instanceCount);
stats_.commandsSubmitted++;
}
break;
}
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;
}
}
}
void RendererModule::onRenderSetCamera(const Mat4 &viewProj) {
if (!initialized_) {
return;
}
viewProjectionMatrix_ = viewProj;
// 更新全局 UBO通过 RenderGraph 的命令队列)
// 实际的 UBO 更新会在 RenderGraph 执行时进行
}
void RendererModule::onRenderEnd() {
if (!initialized_) {
E2D_LOG_WARN("onRenderEnd: RendererModule not initialized");
return;
}
// 执行渲染图,传递视图投影矩阵
renderGraph_.execute(0.016f, viewProjectionMatrix_);
// 获取统计信息
if (commandQueue_) {
stats_.drawCalls = commandQueue_->getCommandCount();
}
// 渲染完成
}
void RendererModule::onResize(int32 width, int32 height) {
setViewport(0, 0, width, height);
}
void RendererModule::executeCommand(const RenderCommand &cmd) {
// 此方法保留用于直接执行特定命令
// 大部分命令现在通过 RenderGraph 处理
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;
}
}
} // namespace extra2d