Files
XCEngine/docs/api/XCEngine/RHI/OpenGL/OpenGLBuffer/OpenGLBuffer.md

4.5 KiB
Raw Blame History

OpenGLBuffer

命名空间: XCEngine::RHI

类型: class

头文件: XCEngine/RHI/OpenGL/OpenGLBuffer.h

描述: OpenGL 后端的通用缓冲区封装,负责创建原生 buffer 对象,并在引擎侧缓存一部分跨后端元数据。

概览

OpenGLBuffer 是 OpenGL RHI 里最基础的资源包装之一。它做的事情其实很直接:

  • 按指定 OpenGLBufferType 创建一个 OpenGL buffer
  • 记录大小、动态标记和目标类型
  • 提供绑定、映射、更新数据等常见入口
  • 额外缓存 BufferTypestridenamestate 这类跨后端元数据

从商业引擎的设计视角看,这种“原生对象 + 少量 RHI 元数据”的组合非常常见。原因是底层驱动对象本身只知道“这是一块 buffer”但上层渲染框架还需要知道它被当作顶点缓冲、索引缓冲、常量缓冲还是别的什么角色来使用。

设计背景

现代显式 API 往往把“资源本体”和“如何使用它”拆得更细。例如 D3D12/Vulkan 里 buffer 的用途、状态和 view 往往由更多配套对象共同表达。OpenGL 则更多依赖“把同一个 buffer 绑定到不同 target”来体现用途。

OpenGLBuffer 的策略是:

  • OpenGLBufferType 决定当前 buffer 的主要 OpenGL 绑定目标。
  • BufferTypestridestate 等字段补充跨后端语义。

这样做的好处是接口统一上层代码比较容易跨后端复用代价是调用方必须清楚地区分“OpenGL 原生目标”和“RHI 语义元数据”不是同一个概念。

OpenGLBufferType 与绑定目标

当前枚举和 ToOpenGL(OpenGLBufferType) 的映射关系如下:

  • Vertex -> GL_ARRAY_BUFFER
  • Index -> GL_ELEMENT_ARRAY_BUFFER
  • Uniform -> GL_UNIFORM_BUFFER
  • CopyRead -> GL_COPY_READ_BUFFER
  • CopyWrite -> GL_COPY_WRITE_BUFFER
  • AtomicCounter -> GL_ATOMIC_COUNTER_BUFFER
  • DispatchIndirect -> GL_DISPATCH_INDIRECT_BUFFER
  • DrawIndirect -> GL_DRAW_INDIRECT_BUFFER
  • ShaderBindingTable -> GL_SHADER_STORAGE_BUFFER

最后这一项尤其值得注意: ShaderBindingTable 在当前 OpenGL 后端并不对应真正的硬件光追 SBT而是退化映射到了 GL_SHADER_STORAGE_BUFFER。这正是商业级跨后端抽象里常见的做法: 保留统一语义名,但允许某些后端落到“最接近、但不完全等价”的实现。

生命周期

当前实现的真实行为

  • Initialize 当前始终返回 true,没有显式错误处理或状态回滚。
  • m_isIndexBuffer 会在初始化时根据 OpenGLBufferType::Index 设置,但当前没有公开 getter也没有在其他逻辑里继续参与行为。
  • m_bufferTypem_stridem_namem_state 都不会在初始化时自动推导,需要调用方自行设置。
  • Map 固定使用 GL_WRITE_ONLY,不支持读映射、持久映射或显式 map flag。
  • Unmap 会调用 glUnmapBuffer(),但忽略它的返回值。
  • SetData 只有在“整块覆盖且大小等于原始 m_size”时才走 glBufferData(),否则走 glBufferSubData(),不会做越界检查,也不会更新 m_size
  • 单测 tests/RHI/OpenGL/unit/test_buffer.cpp 主要覆盖初始化、绑定和写映射路径,没有覆盖复杂错误场景。

使用建议

  • 如果你的调用逻辑依赖 RHI 侧的 BufferTypestridestate,请显式设置,不要假设 Initialize() 会自动填好。
  • 如果需要把同一个 buffer 绑定到 indexed target使用 BindBase 时要明确传入正确的 OpenGL target函数不会帮你从 m_type 推断。
  • 当前不要把 ShaderBindingTable 视为真正的 OpenGL ray tracing SBT 支持。

关键方法

相关文档