345 lines
8.4 KiB
C++
345 lines
8.4 KiB
C++
#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_INFO("正在初始化 RHI 模块...");
|
||
|
||
// 注册窗口显示事件监听,在窗口显示时创建 OpenGL 上下文
|
||
onShowListener_ = std::make_unique<events::OnShow::Listener>();
|
||
onShowListener_->bind([this]() { this->onWindowShow(); });
|
||
|
||
E2D_INFO("RHI 模块已初始化 (等待窗口显示)");
|
||
return true;
|
||
}
|
||
|
||
void RHIModule::onWindowShow() {
|
||
if (initialized_) {
|
||
return;
|
||
}
|
||
|
||
E2D_INFO("RHI 模块: 正在创建 OpenGL 设备...");
|
||
|
||
// 获取窗口模块
|
||
auto *windowModule = getModule<WindowModule>();
|
||
if (!windowModule) {
|
||
E2D_ERROR("窗口模块不可用");
|
||
return;
|
||
}
|
||
|
||
// 等待窗口创建完成
|
||
if (!windowModule->handle()) {
|
||
E2D_ERROR("窗口尚未创建");
|
||
return;
|
||
}
|
||
|
||
// 创建 OpenGL 设备并传入窗口句柄
|
||
device_ = CreateGLDevice();
|
||
if (!device_) {
|
||
E2D_ERROR("创建 RHI 设备失败");
|
||
return;
|
||
}
|
||
|
||
if (!device_->initialize(windowModule->handle())) {
|
||
E2D_ERROR("初始化 RHI 设备失败");
|
||
device_.reset();
|
||
return;
|
||
}
|
||
|
||
context_ = device_->getContext();
|
||
if (!context_) {
|
||
E2D_ERROR("获取 RHI 上下文失败");
|
||
device_->shutdown();
|
||
device_.reset();
|
||
return;
|
||
}
|
||
// 注意:context 已在 GLDevice::initialize() 中初始化,这里不需要再次初始化
|
||
|
||
initialized_ = true;
|
||
E2D_INFO("RHI模块 初始化成功 (后端:{})", device_->getBackendName());
|
||
|
||
// RHI 初始化完成,再次触发 OnShow 事件通知其他模块
|
||
// 这样 RendererModule 等依赖 RHI 的模块可以完成初始化
|
||
events::OnShow::emit();
|
||
}
|
||
|
||
void RHIModule::shutdown() {
|
||
if (!initialized_ && !device_ && !context_ && !onShowListener_) {
|
||
return;
|
||
}
|
||
|
||
E2D_INFO("正在关闭 RHI模块...");
|
||
|
||
// 清理事件监听器
|
||
onShowListener_.reset();
|
||
|
||
context_ = nullptr;
|
||
|
||
if (device_) {
|
||
device_->shutdown();
|
||
device_.reset();
|
||
}
|
||
|
||
initialized_ = false;
|
||
|
||
E2D_INFO("RHI模块 关闭完成");
|
||
}
|
||
|
||
RHIModule *RHIModule::get() { return g_rhiModule; }
|
||
|
||
std::unique_ptr<RHIBuffer> RHIModule::createBuffer(const BufferDesc &desc) {
|
||
if (!device_) {
|
||
E2D_ERROR("无法创建缓冲区:RHI 设备未初始化");
|
||
return nullptr;
|
||
}
|
||
return device_->createBuffer(desc);
|
||
}
|
||
|
||
std::unique_ptr<RHITexture> RHIModule::createTexture(const TextureDesc &desc) {
|
||
if (!device_) {
|
||
E2D_ERROR("无法创建纹理: RHI 设备未初始化");
|
||
return nullptr;
|
||
}
|
||
return device_->createTexture(desc);
|
||
}
|
||
|
||
std::unique_ptr<RHIShader> RHIModule::createShader(const ShaderDesc &desc) {
|
||
if (!device_) {
|
||
E2D_ERROR("无法创建着色器: RHI 设备未初始化");
|
||
return nullptr;
|
||
}
|
||
return device_->createShader(desc);
|
||
}
|
||
|
||
std::unique_ptr<RHIPipeline>
|
||
RHIModule::createPipeline(const PipelineDesc &desc) {
|
||
if (!device_) {
|
||
E2D_ERROR("无法创建管线: RHI 设备未初始化");
|
||
return nullptr;
|
||
}
|
||
return device_->createPipeline(desc);
|
||
}
|
||
|
||
std::unique_ptr<RHIFramebuffer>
|
||
RHIModule::createFramebuffer(const RenderPassDesc &desc) {
|
||
if (!device_) {
|
||
E2D_ERROR("无法创建帧缓冲区: RHI 设备未初始化");
|
||
return nullptr;
|
||
}
|
||
return device_->createFramebuffer(desc);
|
||
}
|
||
|
||
std::unique_ptr<RHICommandList> RHIModule::createCommandList() {
|
||
if (!device_) {
|
||
E2D_ERROR("无法创建命令列表: RHI 设备未初始化");
|
||
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
|