Extra2D/src/renderer/rhi_module.cpp

353 lines
8.6 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.

#include <module/module_registry.h>
#include <platform/window_module.h>
#include <renderer/rhi_module.h>
#include <utils/logger.h>
// 包含 OpenGL 设备实现
// 注意GLDevice 定义在 gl_device.cpp 中,需要确保链接时包含
namespace extra2d {
// 前向声明 GLDevice 类
class GLDevice;
} // namespace extra2d
namespace extra2d {
// 全局实例指针
static RHIModule *g_rhiModule = nullptr;
// GLDevice 创建函数声明 - 在 gl_device.cpp 中定义
std::unique_ptr<RHIDevice> CreateGLDevice();
RHIModule::RHIModule() : context_(nullptr) { g_rhiModule = this; }
RHIModule::~RHIModule() {
shutdown();
g_rhiModule = nullptr;
}
bool RHIModule::init() {
E2D_LOG_INFO("Initializing RHIModule...");
// 注册窗口显示事件监听,在窗口显示时创建 OpenGL 上下文
onShowListener_ = std::make_unique<events::OnShow::Listener>();
onShowListener_->bind([this]() { this->onWindowShow(); });
E2D_LOG_INFO("RHIModule initialized (waiting for window show)");
return true;
}
void RHIModule::onWindowShow() {
if (initialized_) {
return;
}
E2D_LOG_INFO("RHIModule: Creating OpenGL device...");
// 获取窗口模块
auto *windowModule = getModule<WindowModule>();
if (!windowModule) {
E2D_LOG_ERROR("WindowModule not available");
return;
}
// 等待窗口创建完成
if (!windowModule->handle()) {
E2D_LOG_ERROR("Window not created yet");
return;
}
// 创建 OpenGL 设备并传入窗口句柄
device_ = CreateGLDevice();
if (!device_) {
E2D_LOG_ERROR("Failed to create RHI device");
return;
}
if (!device_->initialize(windowModule->handle())) {
E2D_LOG_ERROR("Failed to initialize RHI device");
device_.reset();
return;
}
context_ = device_->getContext();
if (!context_) {
E2D_LOG_ERROR("Failed to get RHI context");
device_->shutdown();
device_.reset();
return;
}
// 初始化上下文
if (!context_->initialize()) {
E2D_LOG_ERROR("Failed to initialize RHI context");
device_->shutdown();
device_.reset();
context_ = nullptr;
return;
}
initialized_ = true;
E2D_LOG_INFO("RHIModule initialized successfully (backend: {})",
device_->getBackendName());
// RHI 初始化完成,再次触发 OnShow 事件通知其他模块
// 这样 RendererModule 等依赖 RHI 的模块可以完成初始化
events::OnShow::emit();
}
void RHIModule::shutdown() {
E2D_LOG_INFO("Shutting down RHIModule...");
// 清理事件监听器
onShowListener_.reset();
if (context_) {
context_->shutdown();
context_ = nullptr;
}
if (device_) {
device_->shutdown();
device_.reset();
}
initialized_ = false;
E2D_LOG_INFO("RHIModule shutdown complete");
}
RHIModule *RHIModule::get() { return g_rhiModule; }
std::unique_ptr<RHIBuffer> RHIModule::createBuffer(const BufferDesc &desc) {
if (!device_) {
E2D_LOG_ERROR("Cannot create buffer: RHI device not initialized");
return nullptr;
}
return device_->createBuffer(desc);
}
std::unique_ptr<RHITexture> RHIModule::createTexture(const TextureDesc &desc) {
if (!device_) {
E2D_LOG_ERROR("Cannot create texture: RHI device not initialized");
return nullptr;
}
return device_->createTexture(desc);
}
std::unique_ptr<RHIShader> RHIModule::createShader(const ShaderDesc &desc) {
if (!device_) {
E2D_LOG_ERROR("Cannot create shader: RHI device not initialized");
return nullptr;
}
return device_->createShader(desc);
}
std::unique_ptr<RHIPipeline>
RHIModule::createPipeline(const PipelineDesc &desc) {
if (!device_) {
E2D_LOG_ERROR("Cannot create pipeline: RHI device not initialized");
return nullptr;
}
return device_->createPipeline(desc);
}
std::unique_ptr<RHIFramebuffer>
RHIModule::createFramebuffer(const RenderPassDesc &desc) {
if (!device_) {
E2D_LOG_ERROR("Cannot create framebuffer: RHI device not initialized");
return nullptr;
}
return device_->createFramebuffer(desc);
}
std::unique_ptr<RHICommandList> RHIModule::createCommandList() {
if (!device_) {
E2D_LOG_ERROR("Cannot create command list: RHI device not initialized");
return nullptr;
}
return device_->createCommandList();
}
// BufferDesc 静态方法实现
BufferDesc BufferDesc::vertex(uint32_t size, BufferUsage usage) {
BufferDesc desc;
desc.type = BufferType::Vertex;
desc.usage = usage;
desc.size = size;
return desc;
}
BufferDesc BufferDesc::index(uint32_t size, BufferUsage usage) {
BufferDesc desc;
desc.type = BufferType::Index;
desc.usage = usage;
desc.size = size;
return desc;
}
BufferDesc BufferDesc::uniform(uint32_t size) {
BufferDesc desc;
desc.type = BufferType::Uniform;
desc.usage = BufferUsage::Dynamic;
desc.size = size;
return desc;
}
// BlendState 静态方法实现
BlendState BlendState::opaque() {
BlendState state;
state.enabled = false;
state.srcFactor = BlendFactor::One;
state.dstFactor = BlendFactor::Zero;
state.op = BlendOp::Add;
state.srcAlphaFactor = BlendFactor::One;
state.dstAlphaFactor = BlendFactor::Zero;
state.alphaOp = BlendOp::Add;
return state;
}
BlendState BlendState::alphaBlend() {
BlendState state;
state.enabled = true;
state.srcFactor = BlendFactor::SrcAlpha;
state.dstFactor = BlendFactor::OneMinusSrcAlpha;
state.op = BlendOp::Add;
state.srcAlphaFactor = BlendFactor::One;
state.dstAlphaFactor = BlendFactor::OneMinusSrcAlpha;
state.alphaOp = BlendOp::Add;
return state;
}
BlendState BlendState::additive() {
BlendState state;
state.enabled = true;
state.srcFactor = BlendFactor::SrcAlpha;
state.dstFactor = BlendFactor::One;
state.op = BlendOp::Add;
state.srcAlphaFactor = BlendFactor::SrcAlpha;
state.dstAlphaFactor = BlendFactor::One;
state.alphaOp = BlendOp::Add;
return state;
}
// DepthStencilState 静态方法实现
DepthStencilState DepthStencilState::depthTest() {
DepthStencilState state;
state.depthTestEnabled = true;
state.depthWriteEnabled = true;
state.depthCompare = CompareFunc::Less;
state.stencilEnabled = false;
return state;
}
DepthStencilState DepthStencilState::depthTestWrite() {
DepthStencilState state;
state.depthTestEnabled = true;
state.depthWriteEnabled = true;
state.depthCompare = CompareFunc::Less;
state.stencilEnabled = false;
return state;
}
DepthStencilState DepthStencilState::depthTestNoWrite() {
DepthStencilState state;
state.depthTestEnabled = true;
state.depthWriteEnabled = false;
state.depthCompare = CompareFunc::Less;
state.stencilEnabled = false;
return state;
}
DepthStencilState DepthStencilState::noDepthTest() {
DepthStencilState state;
state.depthTestEnabled = false;
state.depthWriteEnabled = false;
state.depthCompare = CompareFunc::Always;
state.stencilEnabled = false;
return state;
}
// RasterizerState 静态方法实现
RasterizerState RasterizerState::cullBack() {
RasterizerState state;
state.cullEnabled = true;
state.cullFrontFace = false;
state.frontCCW = false;
state.scissorEnabled = false;
state.wireframe = false;
return state;
}
RasterizerState RasterizerState::cullFront() {
RasterizerState state;
state.cullEnabled = true;
state.cullFrontFace = true;
state.frontCCW = false;
state.scissorEnabled = false;
state.wireframe = false;
return state;
}
RasterizerState RasterizerState::noCull() {
RasterizerState state;
state.cullEnabled = false;
state.cullFrontFace = false;
state.frontCCW = false;
state.scissorEnabled = false;
state.wireframe = false;
return state;
}
// VertexLayout 方法实现
void VertexLayout::addAttribute(uint32_t location, VertexFormat format,
uint32_t offset, uint32_t bufferIndex) {
VertexAttribute attr;
attr.location = location;
attr.format = format;
attr.offset = offset;
attr.bufferIndex = bufferIndex;
attributes.push_back(attr);
}
// VertexAttribute 方法实现
uint32_t VertexAttribute::getSize(VertexFormat format) {
switch (format) {
case VertexFormat::Float1:
return 4;
case VertexFormat::Float2:
return 8;
case VertexFormat::Float3:
return 12;
case VertexFormat::Float4:
return 16;
case VertexFormat::Int1:
return 4;
case VertexFormat::Int2:
return 8;
case VertexFormat::Int3:
return 12;
case VertexFormat::Int4:
return 16;
case VertexFormat::UInt1:
return 4;
case VertexFormat::UInt2:
return 8;
case VertexFormat::UInt3:
return 12;
case VertexFormat::UInt4:
return 16;
case VertexFormat::Byte4:
return 4;
case VertexFormat::Byte4Normalized:
return 4;
case VertexFormat::UByte4:
return 4;
case VertexFormat::UByte4Normalized:
return 4;
default:
return 0;
}
}
} // namespace extra2d