# RHI 模块严重问题:OpenGL 后端 RHI 状态不生效 ## 问题严重程度 **严重级别**: 🔴 Critical Bug ## 问题定位 `OpenGLPipelineState` 维护了两套状态系统,但它们之间没有关联。 ### 两套状态系统 **RHI 抽象层状态** (`OpenGLPipelineState.h:131-133`): ```cpp RasterizerDesc m_rasterizerDesc; BlendDesc m_blendDesc; DepthStencilStateDesc m_depthStencilDesc; ``` **OpenGL 特定状态** (`OpenGLPipelineState.h:141-143`): ```cpp OpenGLDepthStencilState m_glDepthStencilState; OpenGLBlendState m_glBlendState; OpenGLRasterizerState m_glRasterizerState; ``` ## 问题详述 ### RHI 接口设置的状态只存储不生效 ```cpp // OpenGLPipelineState.cpp:19-21 void OpenGLPipelineState::SetRasterizerState(const RasterizerDesc& state) { m_rasterizerDesc = state; // ❌ 只存储到 m_rasterizerDesc } void OpenGLPipelineState::SetBlendState(const BlendDesc& state) { m_blendDesc = state; // ❌ 只存储到 m_blendDesc } void OpenGLPipelineState::SetDepthStencilState(const DepthStencilStateDesc& state) { m_depthStencilDesc = state; // ❌ 只存储到 m_depthStencilDesc } ``` ### Apply() 使用的是另一套状态 ```cpp // OpenGLPipelineState.cpp:133-149 void OpenGLPipelineState::ApplyRasterizer() { if (m_glRasterizerState.cullFaceEnable) { // ✅ 使用的是 m_glRasterizerState glEnable(GL_CULL_FACE); glCullFace(static_cast(m_glRasterizerState.cullFace)); // ... } } void OpenGLPipelineState::ApplyBlend() { if (m_glBlendState.blendEnable) { // ✅ 使用的是 m_glBlendState glEnable(GL_BLEND); // ... } } void OpenGLPipelineState::ApplyDepthStencil() { if (m_glDepthStencilState.depthTestEnable) { // ✅ 使用的是 m_glDepthStencilState glEnable(GL_DEPTH_TEST); // ... } } ``` ## 导致的后果 **通过 RHI 抽象层设置的状态完全不会生效!** ```cpp // 上层代码 RasterizerDesc raster; raster.cullMode = 2; // 设置剔除模式 pso->SetRasterizerState(raster); // 通过 RHI 接口设置 // 实际渲染时 pso->Bind(); // 调用 ApplyRasterizer() // ❌ m_glRasterizerState.cullMode 仍然是默认值,不是设置的值! ``` ## 对比 D3D12 后端 D3D12 后端正确地在 `CreateD3D12PSO()` 中使用了 RHI 状态: ```cpp // D3D12PipelineState.cpp:157-161 desc.RasterizerState.FillMode = static_cast(m_rasterizerDesc.fillMode); desc.RasterizerState.CullMode = static_cast(m_rasterizerDesc.cullMode); // ✅ 直接使用 m_rasterizerDesc ``` ## 根本原因 OpenGL 后端有两个 `SetRasterizerState` 重载: ```cpp // RHI 接口 - 只存储 void SetRasterizerState(const RasterizerDesc& state); // OpenGL 特定接口 - 会生效 void SetRasterizerState(const OpenGLRasterizerState& state); ``` RHI 接口的实现缺少状态转换逻辑。 ## 修复方案 在 `SetRasterizerState(const RasterizerDesc& state)` 中添加转换逻辑: ```cpp void OpenGLPipelineState::SetRasterizerState(const RasterizerDesc& state) { m_rasterizerDesc = state; // 转换到 OpenGL 状态 m_glRasterizerState.cullFaceEnable = (state.cullMode != 0); // CullMode::None m_glRasterizerState.cullFace = static_cast(state.cullMode); m_glRasterizerState.frontFace = static_cast(state.frontFace); m_glRasterizerState.polygonMode = static_cast(state.fillMode); m_glRasterizerState.depthClipEnable = state.depthClipEnable; // ... 其他字段 } ``` 同样需要修复 `SetBlendState` 和 `SetDepthStencilState`。 ## 相关文件 - `engine/include/XCEngine/RHI/OpenGL/OpenGLPipelineState.h` - `engine/src/RHI/OpenGL/OpenGLPipelineState.cpp` ## 影响范围 1. **所有通过 RHI 抽象层设置的状态都不会生效** 2. **OpenGL 集成测试能工作是因为使用了 OpenGL 特定 API** 3. **上层代码如果使用 RHI 接口,行为会与预期不符**