docs(api): deepen OpenGL vertex array and view docs

This commit is contained in:
2026-03-28 02:08:28 +08:00
parent ae93952ce0
commit bce938ac58
47 changed files with 799 additions and 657 deletions

View File

@@ -1,30 +1,34 @@
# OpenGLDepthStencilView::Bind
公开方法,详见头文件声明。
# OpenGLDepthStencilView::Bind()
```cpp
void Bind();
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
把当前对象持有的 framebuffer 绑定到 `GL_FRAMEBUFFER`
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
实现只有一行:
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::Bind(...)。
(void)object;
}
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
```
## 需要注意
- 不会检查 `m_framebuffer` 是否为 `0`
- 不会验证这个 FBO 是否来自一次成功的初始化。
- 绑定的是 `GL_FRAMEBUFFER`,因此会同时影响读写 framebuffer 绑定点。
- 不会保存或恢复之前的 framebuffer 状态。
## 设计解读
对 OpenGL 后端工具类来说,`Bind()` 越薄,调试时越容易映射回真实驱动调用;但上层系统必须自行承担状态管理责任。这也是为什么商业级渲染框架通常会在更高层额外做 render context、command encoder 或 framebuffer cache 的原因。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Unbind](Unbind.md)
- [BindFramebuffer](BindFramebuffer.md)
- [GetFramebuffer](GetFramebuffer.md)

View File

@@ -1,31 +1,29 @@
# OpenGLDepthStencilView::BindFramebuffer
公开方法,详见头文件声明。
# OpenGLDepthStencilView::BindFramebuffer()
```cpp
static void BindFramebuffer(unsigned int framebuffer);
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `framebuffer` - 参数语义详见头文件声明。
把任意 framebuffer ID 直接绑定到 `GL_FRAMEBUFFER`
**返回:** `void` - 无返回值。
## 参数
**示例:**
- `framebuffer`: 要绑定的 FBO 句柄。传入 `0` 时等价于绑定默认 framebuffer。
## 当前实现行为
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::BindFramebuffer(...)。
(void)object;
}
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
```
## 使用定位
这是一个静态辅助函数,价值主要在于把“绑定 framebuffer”统一留在同一类型文档里便于上层 API 阅读和工具脚本引用。它并没有封装额外策略,也不会检查这个句柄是否来自 `OpenGLDepthStencilView`
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Bind](Bind.md)
- [UnbindFramebuffer](UnbindFramebuffer.md)
- [GetFramebuffer](GetFramebuffer.md)

View File

@@ -1,31 +1,38 @@
# OpenGLDepthStencilView::ClearDepth
清空内部数据。
# OpenGLDepthStencilView::ClearDepth()
```cpp
void ClearDepth(float depth);
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `depth` - 参数语义详见头文件声明。
清除当前视图对应 framebuffer 的深度缓冲。
**返回:** `void` - 无返回值。
## 参数
**示例:**
- `depth`: 要写入深度缓冲的清除值。
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
## 当前实现行为
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::ClearDepth(...)。
(void)object;
}
```
函数会按以下顺序执行:
1. `glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer)`
2. `glClearDepth(depth)`
3. `glClear(GL_DEPTH_BUFFER_BIT)`
## 需要注意
- 不会恢复清除前绑定的 framebuffer。
- 不会检查 `m_framebuffer` 是否有效。
- 不会检查当前附着纹理是否真的具备可用的深度格式。
- 如果对象最后一次初始化失败,这里仍然可能对那个未通过完整性检查的 FBO 进行绑定和清除调用。
## 工程建议
在有状态缓存或 command list 录制层的渲染架构里,清除通常应当和 render pass begin 阶段统一管理,而不是散落在后端 view 对象里。这个接口更适合轻量工具路径、单测或旧代码兼容。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [ClearStencil](ClearStencil.md)
- [ClearDepthStencil](ClearDepthStencil.md)
- [Bind](Bind.md)

View File

@@ -1,32 +1,35 @@
# OpenGLDepthStencilView::ClearDepthStencil
清空内部数据。
# OpenGLDepthStencilView::ClearDepthStencil()
```cpp
void ClearDepthStencil(float depth, uint8_t stencil);
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `depth` - 参数语义详见头文件声明。
- `stencil` - 参数语义详见头文件声明。
同时清除深度和模板缓冲。
**返回:** `void` - 无返回值。
## 参数
**示例:**
- `depth`: 深度清除值。
- `stencil`: 模板清除值。
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
## 当前实现行为
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::ClearDepthStencil(...)。
(void)object;
}
```
函数内部顺序如下:
1. 绑定 `m_framebuffer`
2. `glClearDepth(depth)`
3. `glClearStencil(stencil)`
4. `glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)`
## 实现层面的含义
这个函数把“清除深度”和“清除模板”合并为一次接口调用,形式上接近现代渲染 API 在 render pass load action 阶段的表达方式。但要注意,当前类本身并没有真正维护 depth/stencil attachment 的完整元数据,尤其没有根据格式切换正确 attachment 点。
换句话说,它提供了方便的调用面,却没有提供现代 render pass 系统那种严格的兼容性约束和状态验证。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [ClearDepth](ClearDepth.md)
- [ClearStencil](ClearStencil.md)
- [Bind](Bind.md)

View File

@@ -1,31 +1,32 @@
# OpenGLDepthStencilView::ClearStencil
清空内部数据。
# OpenGLDepthStencilView::ClearStencil()
```cpp
void ClearStencil(uint8_t stencil);
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `stencil` - 参数语义详见头文件声明。
清除当前视图对应 framebuffer 的模板缓冲。
**返回:** `void` - 无返回值。
## 参数
**示例:**
- `stencil`: 要写入模板缓冲的清除值。
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
## 当前实现行为
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::ClearStencil(...)。
(void)object;
}
```
函数会:
1. 绑定 `m_framebuffer`
2. 调用 `glClearStencil(stencil)`
3. 调用 `glClear(GL_STENCIL_BUFFER_BIT)`
## 关键限制
- 当前初始化路径只会把纹理附着到 `GL_DEPTH_ATTACHMENT`,不会显式附着到 `GL_STENCIL_ATTACHMENT``GL_DEPTH_STENCIL_ATTACHMENT`
- 因此,这个函数虽然发出了 stencil clear 指令,但实际是否对期望的模板数据生效,取决于底层纹理格式、驱动行为以及 OpenGL 对该 attachment 组合的接受方式。
- 单元测试并没有覆盖 stencil 有效性的严格验证。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Initialize](Initialize.md)
- [ClearDepthStencil](ClearDepthStencil.md)

View File

@@ -1,28 +1,33 @@
# OpenGLDepthStencilView::OpenGLDepthStencilView()
构造对象。
```cpp
OpenGLDepthStencilView();
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
构造一个尚未绑定任何 OpenGL 资源的深度/模板视图对象
**返回:** `void` - 无返回值。
## 初始状态
**示例:**
构造函数会把内部成员初始化为以下值:
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
- `m_texture = 0`
- `m_framebuffer = 0`
- `m_mipLevel = 0`
- `m_width = 0`
- `m_height = 0`
- `m_type = DepthStencilType::Texture2D`
- `m_format = DepthStencilFormat::D24_UNORM_S8_UINT`
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
}
```
## 设计解读
这种“零句柄 + 默认类型”的构造方式是图形后端工具类里很常见的做法。好处是对象可以先进入容器、再延迟初始化;测试也能先验证默认状态,再单独覆盖创建路径。
但要注意,`m_format` 的默认值并不代表传入纹理真实一定是 `D24_UNORM_S8_UINT`。当前实现只是给成员一个占位初值,后续初始化也不会把它更新成真实纹理格式。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Initialize](Initialize.md)
- [Shutdown](Shutdown.md)
- [~OpenGLDepthStencilView()](Destructor.md)

View File

@@ -1,29 +1,32 @@
# OpenGLDepthStencilView::~OpenGLDepthStencilView()
销毁对象并释放相关资源。
```cpp
~OpenGLDepthStencilView();
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
析构对象,并释放它当前持有的 framebuffer
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
析构函数本身没有额外逻辑,只是直接调用:
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 对象离开作用域时会自动触发析构。
}
Shutdown();
```
这意味着:
- 如果 `m_framebuffer != 0`,析构时会删除该 FBO。
- 其他成员不会在析构前被额外重置。
- 如果对象处于“`Initialize()` 返回 `false``m_framebuffer` 已经生成”的状态,析构仍然会把这个 FBO 删掉。
## 工程意义
这种 RAII 风格能保证调用方即使忘记手工调用 [Shutdown](Shutdown.md),最终也不会把原生 FBO 彻底泄漏掉。对工具代码和异常路径来说,这是必须具备的基本防线。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [OpenGLDepthStencilView()](Constructor.md)
- [Shutdown](Shutdown.md)

View File

@@ -1,30 +1,25 @@
# OpenGLDepthStencilView::GetFramebuffer
获取相关状态或对象。
# OpenGLDepthStencilView::GetFramebuffer()
```cpp
unsigned int GetFramebuffer() const;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回当前对象持有的 framebuffer 对象 ID
**返回:** `unsigned int` - 返回值语义详见头文件声明。
## 返回值
**示例:**
- 当前 `m_framebuffer` 的值。
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
## 需要注意
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::GetFramebuffer(...)
(void)object;
}
```
- 返回非零值并不等价于“这一定是一次成功初始化后的完整 FBO”。
- 因为在失败路径里,`Initialize()` 依然会先生成并保存 FBO再在完整性检查失败后返回 `false`
- 调用 [Shutdown](Shutdown.md) 后,这个 getter 才会重新返回 `0`
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Initialize](Initialize.md)
- [Shutdown](Shutdown.md)
- [BindFramebuffer](BindFramebuffer.md)

View File

@@ -1,30 +1,18 @@
# OpenGLDepthStencilView::GetHeight
获取相关状态或对象。
# OpenGLDepthStencilView::GetHeight()
```cpp
int GetHeight() const;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回视图高度
**返回:** `int` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::GetHeight(...)。
(void)object;
}
```
和 [GetWidth](GetWidth.md) 一样,当前实现从不更新 `m_height`,所以返回值始终是 `0`
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [GetWidth](GetWidth.md)
- [Initialize](Initialize.md)

View File

@@ -1,30 +1,28 @@
# OpenGLDepthStencilView::GetMipLevel
获取相关状态或对象。
# OpenGLDepthStencilView::GetMipLevel()
```cpp
int GetMipLevel() const;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回当前视图记录的 mip 级别
**返回:** `int` - 返回值语义详见头文件声明。
## 返回值
**示例:**
- 当前 `m_mipLevel` 的值。
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
## 当前实现行为
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::GetMipLevel(...)
(void)object;
}
```
- 在 [Initialize](Initialize.md) 中,它直接取自 `desc.mipLevel`
- 在 [InitializeCubemap](InitializeCubemap.md) 中,它直接取自传入的 `mipLevel`
- `Shutdown()` 不会把它恢复为 `0`
## 工程意义
这个 getter 的价值主要在于调试和上层记录,而不是驱动状态查询。它反映的是对象内部缓存的“最近一次配置意图”,不是从 OpenGL 反查出来的真实资源信息。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Initialize](Initialize.md)
- [InitializeCubemap](InitializeCubemap.md)

View File

@@ -1,30 +1,27 @@
# OpenGLDepthStencilView::GetTexture
获取相关状态或对象。
# OpenGLDepthStencilView::GetTexture()
```cpp
unsigned int GetTexture() const;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回最近一次写入到该视图对象中的纹理 ID
**返回:** `unsigned int` - 返回值语义详见头文件声明。
## 返回值
**示例:**
- 当前 `m_texture` 的值。
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
## 需要注意
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::GetTexture(...)
(void)object;
}
```
- 这个值在 `Initialize()` / `InitializeCubemap()` 开始时就会被写入。
- 即使初始化后续失败,它也不会自动回滚。
- 调用 [Shutdown](Shutdown.md) 不会把它清零
因此,这个 getter 更适合回答“这个对象最近被配置成引用哪张纹理”,而不是“当前是否仍然拥有一个有效、完整的深度视图”。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Initialize](Initialize.md)
- [InitializeCubemap](InitializeCubemap.md)
- [Shutdown](Shutdown.md)

View File

@@ -1,30 +1,28 @@
# OpenGLDepthStencilView::GetWidth
获取相关状态或对象。
# OpenGLDepthStencilView::GetWidth()
```cpp
int GetWidth() const;
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
返回视图宽度
**返回:** `int` - 返回值语义详见头文件声明。
## 当前实现行为
**示例:**
当前实现不会在任何初始化路径里更新 `m_width`,因此这个函数始终返回构造时的默认值 `0`
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
## 为什么这很重要
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::GetWidth(...)。
(void)object;
}
```
很多图形接口会把 view 尺寸缓存下来,便于:
- 自动设置 viewport / scissor
- 做 attachment 兼容性检查
- 为 render graph 提供分辨率信息
而当前实现没有这些行为,所以调用方不能把它当作可信的尺寸来源。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [GetHeight](GetHeight.md)
- [Initialize](Initialize.md)

View File

@@ -1,46 +1,60 @@
# OpenGLDepthStencilView::Initialize
初始化内部状态。
该方法在 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h` 中提供了 2 个重载,当前页面统一汇总这些公开声明。
## 重载 1: 声明
# OpenGLDepthStencilView::Initialize()
```cpp
bool Initialize(unsigned int texture, const OpenGLDepthStencilViewDesc& desc);
```
**参数:**
- `texture` - 参数语义详见头文件声明。
- `desc` - 参数语义详见头文件声明。
**返回:** `bool` - 返回值语义详见头文件声明。
## 重载 2: 声明
```cpp
bool Initialize(unsigned int texture, int mipLevel = 0);
```
**参数:**
- `texture` - 参数语义详见头文件声明。
- `mipLevel` - 参数语义详见头文件声明。
## 作用
**返回:** `bool` - 返回值语义详见头文件声明
为指定纹理子资源创建一个专用 FBO并把它作为当前深度视图的后端承载对象
**示例:**
## 参数
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
- `texture`: 需要附着到 FBO 上的 OpenGL 纹理对象 ID。
- `desc`: 视图描述。决定纹理类型、mip 级别和数组层/立方体面。
- `mipLevel`: 简化重载使用的 mip 级别。它会构造一个默认 `Texture2D` 描述,再转调完整重载。
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::Initialize(...)
(void)object;
}
```
## 返回值
- `true`: framebuffer 完整性检查通过
- `false`: `glCheckFramebufferStatus(GL_FRAMEBUFFER)` 结果不是 `GL_FRAMEBUFFER_COMPLETE`
## 当前实现行为
完整重载的执行顺序可以概括为:
1. 先写入成员 `m_texture``m_mipLevel``m_type`
2. 调用 `glGenFramebuffers()` 生成 `m_framebuffer`
3. 绑定 `GL_FRAMEBUFFER` 到这个新 FBO。
4.`desc.type` 选择附着方式:
- `Texture2D`: `glFramebufferTexture2D(..., GL_TEXTURE_2D, texture, desc.mipLevel)`
- `Texture2DArray`: `glFramebufferTextureLayer(..., texture, desc.mipLevel, desc.baseArraySlice)`
- `TextureCube`: `glFramebufferTexture2D(..., GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc.baseArraySlice, texture, desc.mipLevel)`
5. 调用 `glCheckFramebufferStatus(GL_FRAMEBUFFER)` 验证完整性。
6. 无论成功还是失败,都在返回前把 `GL_FRAMEBUFFER` 解绑到 `0`
## 描述字段的真实消费情况
- `desc.type` 会决定附着 API 和目标子资源类型。
- `desc.mipLevel` 会写入 `m_mipLevel`,并参与 FBO 附着。
- `desc.baseArraySlice` 对数组纹理表示层索引,对 cubemap 表示 face 偏移。
- `desc.arraySize` 当前未使用。
- `desc.layer` 当前未使用。
## 重要限制
- 附着点始终来自 `ToOpenGLDepthAttachment()`,当前它固定返回 `GL_DEPTH_ATTACHMENT`。也就是说,这个类虽然名为 “DepthStencilView”但初始化路径并不会显式使用 `GL_STENCIL_ATTACHMENT``GL_DEPTH_STENCIL_ATTACHMENT`
- 当前不会查询并写回纹理尺寸,所以 [GetWidth](GetWidth.md) 和 [GetHeight](GetHeight.md) 仍然返回 `0`
- 当前不会根据底层纹理真实格式更新 `m_format`
- 初始化失败时不会删除刚刚创建的 FBO也不会回滚前面已经写入的成员状态。失败后对象处于“持有 FBO 句柄但初始化未完成”的状态,调用方应尽快执行 [Shutdown](Shutdown.md)。
## 设计说明
这种“每个 view 自己持有一个 FBO”的方案本质上是在用 OpenGL framebuffer 去模拟更现代 API 里的 view 描述对象。它的优点是简单直观,适合旧代码迁移和快速落地;缺点是对象粒度偏细,状态缓存和复用空间有限,也不利于统一描述复杂附件组合。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [InitializeCubemap](InitializeCubemap.md)
- [Shutdown](Shutdown.md)
- [GetFramebuffer](GetFramebuffer.md)

View File

@@ -1,33 +1,45 @@
# OpenGLDepthStencilView::InitializeCubemap
初始化内部状态。
# OpenGLDepthStencilView::InitializeCubemap()
```cpp
bool InitializeCubemap(unsigned int cubemap, int face, int mipLevel = 0);
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
- `cubemap` - 参数语义详见头文件声明。
- `face` - 参数语义详见头文件声明。
- `mipLevel` - 参数语义详见头文件声明。
为 cubemap 的单个 face 创建深度视图。这是针对立方体纹理场景提供的便捷接口。
**返回:** `bool` - 返回值语义详见头文件声明。
## 参数
**示例:**
- `cubemap`: cubemap 纹理对象 ID。
- `face`: 要附着的面索引。实现会直接计算 `GL_TEXTURE_CUBE_MAP_POSITIVE_X + face`
- `mipLevel`: 需要附着的 mip 级别。
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
## 返回值
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::InitializeCubemap(...)。
(void)object;
}
```
- `true`: framebuffer 完整性检查通过。
- `false`: framebuffer 不完整。
## 当前实现行为
-`m_texture` 设置为 `cubemap`
-`m_mipLevel` 设置为 `mipLevel`
-`m_type` 设置为 `DepthStencilType::TextureCube`
- 生成并绑定一个新的 FBO。
- 调用 `glFramebufferTexture2D(GL_FRAMEBUFFER, ToOpenGLDepthAttachment(), GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap, mipLevel)`
- 之后执行 framebuffer 完整性检查,最后解绑回 `0`
## 需要注意
- 当前没有对 `face` 做范围校验,调用方应保证它是合法 cubemap face 偏移。
- 失败路径不会删除刚创建的 FBO也不会回滚成员状态。
- 和通用 [Initialize](Initialize.md) 一样,这里依旧只使用 `GL_DEPTH_ATTACHMENT`
## 适用场景
这个接口适合阴影立方图、点光源 shadow map、环境探针等“一次只处理一个 cubemap face”的流程。相比手写 `OpenGLDepthStencilViewDesc`,它能减少样板代码,但抽象能力并没有更强。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Initialize](Initialize.md)
- [Bind](Bind.md)
- [ClearDepth](ClearDepth.md)

View File

@@ -6,44 +6,94 @@
**头文件**: `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`
**描述**: 定义 `XCEngine/RHI/OpenGL` 子目录中的 `OpenGLDepthStencilView` public API
**描述**: OpenGL 后端的轻量级深度/模板视图封装,为单个纹理子资源创建并管理一个专用 framebuffer
## 概
## 概
`OpenGLDepthStencilView.h``XCEngine/RHI/OpenGL` 子目录 下的 public header当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明
在现代图形 API 里,深度视图通常表示“同一张纹理资源的某个可渲染子资源视角”。这样做的价值是把“资源怎么分配”和“本次渲染如何把它当作深度附件使用”拆开,渲染图、阴影图、反射探针等系统都可以围绕同一张底层纹理复用不同 view
## 声明概览
OpenGL 没有 D3D12/Vulkan 那种独立的 depth-stencil view 对象,所以当前实现采用了引擎里常见的一种折中办法: 为每个 view 创建一个独立 FBO再把指定纹理、mip 和 layer/face 附着到这个 FBO 上。这样上层可以继续沿用“先构造 view再绑定 view”的组织方式而不必每次手写 framebuffer 配置细节。
| 声明 | 类型 | 说明 |
|------|------|------|
| `DepthStencilFormat` | `enum class` | 头文件中的公开声明。 |
| `DepthStencilType` | `enum class` | 头文件中的公开声明。 |
| `OpenGLDepthStencilViewDesc` | `struct` | 头文件中的公开声明。 |
| `OpenGLDepthStencilView` | `class` | 头文件中的公开声明。 |
## 设计背景
## 公共方法
`OpenGLDepthStencilView` 的定位更接近“后端适配层工具对象”,而不是完整的跨后端深度附件抽象。
| 方法 | 描述 |
|------|------|
| [OpenGLDepthStencilView()](Constructor.md) | 构造对象。 |
| [~OpenGLDepthStencilView()](Destructor.md) | 销毁对象并释放相关资源。 |
| [Initialize](Initialize.md) | 初始化内部状态。 |
| [InitializeCubemap](InitializeCubemap.md) | 初始化内部状态。 |
| [Shutdown](Shutdown.md) | 关闭并清理内部状态。 |
| [Bind](Bind.md) | 公开方法,详见头文件声明。 |
| [Unbind](Unbind.md) | 公开方法,详见头文件声明。 |
| [ClearDepth](ClearDepth.md) | 清空内部数据。 |
| [ClearStencil](ClearStencil.md) | 清空内部数据。 |
| [ClearDepthStencil](ClearDepthStencil.md) | 清空内部数据。 |
| [GetFramebuffer](GetFramebuffer.md) | 获取相关状态或对象。 |
| [GetTexture](GetTexture.md) | 获取相关状态或对象。 |
| [GetMipLevel](GetMipLevel.md) | 获取相关状态或对象。 |
| [GetWidth](GetWidth.md) | 获取相关状态或对象。 |
| [GetHeight](GetHeight.md) | 获取相关状态或对象。 |
| [BindFramebuffer](BindFramebuffer.md) | 公开方法,详见头文件声明。 |
| [UnbindFramebuffer](UnbindFramebuffer.md) | 公开方法,详见头文件声明。 |
- 好处是实现直接、调试简单,单元测试和工具代码很容易验证绑定行为。
- 好处是可以把 `Texture2D`、数组纹理切片、cubemap face 这几类常见子资源统一封装到一个接口里。
- 代价是它没有和更新一代的 `OpenGLFramebuffer` / `OpenGLResourceView` 体系彻底对齐,很多字段只是保留了抽象层接口形状,并没有被完整消费。
如果目标是商业级引擎里的长期演进路径,通常会更偏向“显式 framebuffer 描述 + 统一 resource view”的方案因为那条路线更容易支持多附件组合、渲染图编排、缓存复用和更严格的状态验证。`OpenGLDepthStencilView` 更适合作为旧路径兼容层或轻量工具接口。
## 相关声明
### `DepthStencilFormat`
头文件中声明了四种格式枚举:
- `D16_UNORM`
- `D24_UNORM_S8_UINT`
- `D32_FLOAT`
- `D32_FLOAT_S8X24_UINT`
但当前类实现并不会从传入纹理推导真实格式,也没有公开接口返回实际 attachment 格式。内部成员 `m_format` 在构造时固定初始化为 `D24_UNORM_S8_UINT`,之后也不会更新。
### `DepthStencilType`
当前支持三种视图类型:
- `Texture2D`
- `Texture2DArray`
- `TextureCube`
它们直接决定 `Initialize()` 内部选用 `glFramebufferTexture2D()` 还是 `glFramebufferTextureLayer()`
### `OpenGLDepthStencilViewDesc`
描述结构包含以下字段:
- `type`: 选择纹理视图类别。
- `mipLevel`: 指定附着的 mip 级别。
- `baseArraySlice`: 对数组纹理表示层索引,对 cubemap 表示 face 偏移。
- `arraySize`: 当前实现未使用。
- `layer`: 当前实现未使用。
这说明它的接口形状已经在向更通用的 view 描述靠拢,但 OpenGL 后端的落地仍然是一个较薄的子集。
## 生命周期
- [OpenGLDepthStencilView()](Constructor.md) 把对象初始化为空状态。
- [Initialize](Initialize.md) 或 [InitializeCubemap](InitializeCubemap.md) 创建 FBO 并附着指定子资源。
- [Bind](Bind.md) / [Unbind](Unbind.md) 切换当前 framebuffer。
- [ClearDepth](ClearDepth.md)、[ClearStencil](ClearStencil.md)、[ClearDepthStencil](ClearDepthStencil.md) 在当前对象对应的 FBO 上执行清除。
- [Shutdown](Shutdown.md) 删除 FBO。
## 当前实现的真实行为
- 每次成功或失败的初始化路径都会先生成一个新的 FBO并把它写入 `m_framebuffer`
- 附着点始终来自 `ToOpenGLDepthAttachment()`,当前它固定返回 `GL_DEPTH_ATTACHMENT`,并不会根据纹理格式切换到 `GL_STENCIL_ATTACHMENT``GL_DEPTH_STENCIL_ATTACHMENT`
- 初始化失败时函数会返回 `false`,但不会立即删除刚创建的 FBO也不会回滚 `m_texture``m_mipLevel``m_type` 等成员。调用方应继续执行 [Shutdown](Shutdown.md) 或依赖析构清理。
- `GetWidth()` / `GetHeight()` 当前始终返回默认值 `0`,因为实现没有从纹理查询并写回尺寸。
- `Clear*` 方法会直接绑定自己的 framebuffer 并清除,但不会恢复调用前的 framebuffer 绑定状态。
- 单元测试 `tests/RHI/OpenGL/unit/test_depth_stencil_view.cpp` 只覆盖了初始化、绑定和简单 getter不能把它视为格式兼容性或 stencil 行为的完备证明。
## 使用建议
- 当你只是需要“把某张纹理的某个子资源临时当作深度附件使用”时,这个类足够直接。
- 如果你需要多附件 FBO、统一的 render pass 组织、显式 attachment 配置或更强的后端一致性,优先考虑更完整的 framebuffer / resource view 路径。
- 当前不要依赖 [GetWidth](GetWidth.md) 和 [GetHeight](GetHeight.md)。
- 如果 `Initialize()` 失败,最好显式调用一次 [Shutdown](Shutdown.md),避免把半初始化状态留在对象里继续复用。
## 关键方法
- [Initialize](Initialize.md)
- [InitializeCubemap](InitializeCubemap.md)
- [Bind](Bind.md)
- [ClearDepthStencil](ClearDepthStencil.md)
- [Shutdown](Shutdown.md)
## 相关文档
- [当前目录](../OpenGL.md) - 返回 `OpenGL` 平行目录
- [API 总索引](../../../../main.md) - 返回顶层索引
- [OpenGL](../OpenGL.md)
- [OpenGLTexture](../OpenGLTexture/OpenGLTexture.md)
- [OpenGLFramebuffer](../OpenGLFramebuffer/OpenGLFramebuffer.md)
- [OpenGLResourceView](../OpenGLResourceView/OpenGLResourceView.md)

View File

@@ -1,30 +1,36 @@
# OpenGLDepthStencilView::Shutdown
关闭并清理内部状态。
# OpenGLDepthStencilView::Shutdown()
```cpp
void Shutdown();
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
删除当前对象持有的 framebuffer并把 framebuffer 句柄重置为 `0`
**返回:** `void` - 无返回值。
## 当前实现行为
**示例:**
- 如果 `m_framebuffer != 0`,调用 `glDeleteFramebuffers(1, &m_framebuffer)`
- 然后把 `m_framebuffer` 设回 `0`
- 其他成员保持原值,不会被清空。
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
## 这意味着什么
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::Shutdown(...)
(void)object;
}
```
调用 `Shutdown()` 之后:
- [GetFramebuffer](GetFramebuffer.md) 会返回 `0`
- [GetTexture](GetTexture.md) 仍然可能返回上一次初始化写入的纹理 ID。
- [GetMipLevel](GetMipLevel.md)、`m_type``m_width``m_height``m_format` 不会被复位。
这种实现是典型的“只回收后端资源,不重建完整逻辑对象状态”。它对简单工具类足够,但如果调用方把 `Shutdown()` 视为“彻底回到构造态”,就会产生误判。
## 使用建议
- 初始化失败后,建议显式调用一次 `Shutdown()` 清理失败路径留下的 FBO。
- 如果打算复用同一个对象重新初始化,也应先调用 `Shutdown()`,避免旧句柄残留。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [OpenGLDepthStencilView()](Constructor.md)
- [~OpenGLDepthStencilView()](Destructor.md)
- [Initialize](Initialize.md)

View File

@@ -1,30 +1,25 @@
# OpenGLDepthStencilView::Unbind
公开方法,详见头文件声明。
# OpenGLDepthStencilView::Unbind()
```cpp
void Unbind();
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
解除当前 framebuffer 绑定,恢复到默认 framebuffer `0`
**返回:** `void` - 无返回值。
**示例:**
## 当前实现行为
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::Unbind(...)。
(void)object;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
```
## 需要注意
- 它不会恢复“调用 `Bind()` 之前的那个 FBO”而是无条件切回默认 framebuffer。
- 如果当前渲染流程本来就在使用另一个自定义 FBO调用这个函数会直接打断那段状态。
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Bind](Bind.md)
- [UnbindFramebuffer](UnbindFramebuffer.md)

View File

@@ -1,30 +1,20 @@
# OpenGLDepthStencilView::UnbindFramebuffer
公开方法,详见头文件声明。
# OpenGLDepthStencilView::UnbindFramebuffer()
```cpp
static void UnbindFramebuffer();
```
该方法声明于 `XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h`,当前页面用于固定 `OpenGLDepthStencilView` 类目录下的方法级 canonical 路径。
## 作用
**参数:**
解除当前 framebuffer 绑定,切回默认 framebuffer `0`
**返回:** `void` - 无返回值。
**示例:**
## 当前实现行为
```cpp
#include <XCEngine/RHI/OpenGL/OpenGLDepthStencilView.h>
void Example() {
XCEngine::RHI::OpenGLDepthStencilView object;
// 根据上下文补齐参数后调用 OpenGLDepthStencilView::UnbindFramebuffer(...)。
(void)object;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
```
## 相关文档
- [返回类总览](OpenGLDepthStencilView.md)
- [返回模块目录](../OpenGL.md)
- [Unbind](Unbind.md)
- [BindFramebuffer](BindFramebuffer.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::Bind
# OpenGLRenderTargetView::Bind()
```cpp
void Bind(unsigned int slot = 0);
@@ -7,30 +7,60 @@ void Bind(unsigned int count, const unsigned int* framebuffers, const int* drawB
## 作用
一个或多个 framebuffer 绑定到当前 OpenGL 上下文
绑定一个或多个 framebuffer,供后续绘制使用
## 参数
### 单对象重载
- `slot`: 逻辑上的颜色槽位索引。
### 多对象重载
- `count`: 传入 framebuffer 数量。
- `framebuffers`: framebuffer ID 数组。
- `drawBuffers`: 绘制缓冲数组。实现会把它强制转换为 `const GLenum*` 使用。
## 当前实现行为
### `Bind(unsigned int slot = 0)`
### `Bind(unsigned int slot)`
- 直接执行 `glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer)`
- `slot` 参数当前被忽略,只是为了维持接口形状。
实现只有两部分:
```cpp
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
(void)slot;
```
也就是说,`slot` 参数当前完全没有参与行为。
### `Bind(unsigned int count, const unsigned int* framebuffers, const int* drawBuffers)`
-`count == 1` 时,只绑定 `framebuffers[0]`
-`count > 1` 时:
- 绑定默认 framebuffer `0`
- 然后循环绑定每个 framebuffer
- 每次调用 `glDrawBuffers(1, &drawBuffers[i])`
- 这种“逐个绑定并切换 draw buffer”的行为更像旧式辅助函数并不是现代 MRT 绑定的理想抽象。
-`count > 1`,先绑定默认 framebuffer `0`,然后进入循环:
- 绑定 `framebuffers[i]`
- 调用 `glDrawBuffers(1, (const GLenum*)&drawBuffers[i])`
- 循环结束后,最后一个 framebuffer 会保持为当前绑定对象。
## 使用建议
## 为什么这不是完整的 MRT 抽象
- 单目标渲染时优先使用无参版本,它的行为最直接。
- 多渲染目标场景更推荐走 [OpenGLFramebuffer](../OpenGLFramebuffer/OpenGLFramebuffer.md) 或 [OpenGLResourceView](../OpenGLResourceView/OpenGLResourceView.md) 的新路径。
真正的 MRT 一般意味着:
- 同一个 FBO 上同时配置多个颜色附件
- 一次性提交完整的 draw buffer 列表
- 让渲染阶段以一致的附件组合执行
而当前实现是“逐个 framebuffer 绑定 + 每次只设置一个 draw buffer”。它更像历史过渡代码中的辅助接口而不是现代渲染后端应长期依赖的多渲染目标模型。
## 需要注意
- 不会检查传入指针是否为空。
- 不会验证 `drawBuffers` 中的值是否是合法 `GLenum`
- `count == 0` 时没有显式保护逻辑。
- 不会保存或恢复之前的 framebuffer 状态。
## 相关文档
- [OpenGLRenderTargetView](OpenGLRenderTargetView.md)
- [Unbind](Unbind.md)
- [BindFramebuffer](BindFramebuffer.md)
- [OpenGLFramebuffer](../OpenGLFramebuffer/OpenGLFramebuffer.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::BindFramebuffer
# OpenGLRenderTargetView::BindFramebuffer()
```cpp
static void BindFramebuffer(unsigned int framebuffer);
@@ -6,22 +6,23 @@ static void BindFramebuffer(unsigned int framebuffer);
## 作用
静态绑定指定的 framebuffer。
直接绑定任意 framebuffer`GL_FRAMEBUFFER`
## 参数说明
## 参数
- `framebuffer`: 要绑定的 OpenGL framebuffer id
- `framebuffer`: 要绑定的 FBO 句柄;传入 `0` 表示默认 framebuffer。
## 当前实现行为
- 仅执行 `glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)`
- 不校验 `framebuffer` 是否有效,也不保存之前的绑定状态。
```cpp
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
```
## 使用建议
## 使用定位
- 这是一个薄的静态包装,适合在工具代码或测试代码中直接切换 FBO
- 如果你需要面向 RHI 抽象层的绑定流程,更推荐使用 [OpenGLFramebuffer](../OpenGLFramebuffer/OpenGLFramebuffer.md) 或命令列表接口。
这是一个非常薄的静态辅助接口,不附带额外策略、校验或缓存。它的价值主要在于保持 API 组织一致,而不是在于提供比原生 OpenGL 更强的抽象
## 相关文档
- [Bind](Bind.md)
- [UnbindFramebuffer](UnbindFramebuffer.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::Clear
# OpenGLRenderTargetView::Clear()
```cpp
void Clear(float r, float g, float b, float a);
@@ -7,33 +7,45 @@ void Clear(float r, float g, float b, float a, float depth, uint8_t stencil);
## 作用
清除当前 `OpenGLRenderTargetView` 关联的 framebuffer
清除当前视图对应 framebuffer 的颜色缓冲,或同时清除颜色、深度和模板缓冲
## 参数
- `r``g``b``a`: 颜色清除值。
- `depth`: 深度清除值。
- `stencil`: 模板清除值。
## 当前实现行为
### `Clear(float r, float g, float b, float a)`
### 颜色清除重载
- 绑定 `m_framebuffer`
- 调用 `glClearColor(r, g, b, a)`
- 调用 `glClear(GL_COLOR_BUFFER_BIT)`
函数会:
### `Clear(float r, float g, float b, float a, float depth, uint8_t stencil)`
1. 绑定 `m_framebuffer`
2. `glClearColor(r, g, b, a)`
3. `glClear(GL_COLOR_BUFFER_BIT)`
- 绑定 `m_framebuffer`
- 依次设置颜色、深度和模板清除值。
- 调用 `glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)`
### 颜色 + 深度 + 模板清除重载
## 重要限制
函数会:
- 两个重载都不会恢复清除前的 framebuffer 绑定状态。
- 该类型本身只附加颜色附件;如果 framebuffer 实际没有深度/模板附件,第二个重载里的深度/模板清除并不代表一定存在有效目标。
1. 绑定 `m_framebuffer`
2. `glClearColor(r, g, b, a)`
3. `glClearDepth(depth)`
4. `glClearStencil(stencil)`
5. `glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)`
## 使用建议
## 关键限制
- 在显式命令列表体系下,更推荐通过 render pass + framebuffer 的组合表达清除意图
- 如果直接调用该接口,调用方应自己管理前后绑定状态
- 这两个函数都不会恢复调用前的 framebuffer 绑定
- 当前类本身只负责创建颜色附件,并不会顺带创建深度/模板附件
- 因此第二个重载虽然发出了深度/模板清除命令,但其真实效果取决于这个 FBO 是否在别处被补充了对应附件。
## 设计说明
把清除接口挂在 view 对象上,能让简单样例代码非常直接;但在更成熟的渲染框架里,清除通常属于 render pass begin 阶段的职责。那样更有利于统一 load/store 语义、状态缓存和调试可视化。
## 相关文档
- [Bind](Bind.md)
- [OpenGLRenderTargetView](OpenGLRenderTargetView.md)
- [OpenGLDepthStencilView](../OpenGLDepthStencilView/OpenGLDepthStencilView.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::OpenGLRenderTargetView
# OpenGLRenderTargetView::OpenGLRenderTargetView()
```cpp
OpenGLRenderTargetView();
@@ -6,25 +6,26 @@ OpenGLRenderTargetView();
## 作用
构造一个空的 render target view 辅助对象。
构造一个尚未持有任何 FBO 的颜色渲染目标视图对象。
## 当前实现行为
## 初始状态
- 使用默认值初始化:
- `m_texture = 0`
- `m_framebuffer = 0`
- `m_mipLevel = 0`
- `m_width = 0`
- `m_height = 0`
- `m_type = RenderTargetType::Texture2D`
- 不执行任何 OpenGL 调用。
构造函数会把成员初始化:
## 使用建议
- `m_texture = 0`
- `m_framebuffer = 0`
- `m_mipLevel = 0`
- `m_width = 0`
- `m_height = 0`
- `m_type = RenderTargetType::Texture2D`
- `m_framebuffers` 为空数组
- 构造后应调用 [Initialize](Initialize.md) 或 [InitializeCubemap](InitializeCubemap.md)。
- 不要把默认的 `m_width` / `m_height` 视为纹理真实尺寸,它们在当前实现中不会被后续初始化更新。
## 设计解读
这是典型的图形后端延迟初始化模式。对象先进入可用但未分配 GPU 资源的状态,之后再通过 [Initialize](Initialize.md) 真正创建 FBO。这样做便于容器管理、测试编排和错误路径清理。
## 相关文档
- [Initialize](Initialize.md)
- [OpenGLRenderTargetView](OpenGLRenderTargetView.md)
- [Shutdown](Shutdown.md)
- [~OpenGLRenderTargetView()](Destructor.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::~OpenGLRenderTargetView
# OpenGLRenderTargetView::~OpenGLRenderTargetView()
```cpp
~OpenGLRenderTargetView();
@@ -6,19 +6,27 @@
## 作用
销毁对象并删除它创建的 framebuffer。
析构对象,并释放它持有的 framebuffer 资源
## 当前实现行为
- 析构函数内部调用 [Shutdown](Shutdown.md)。
- 会删除 `m_framebuffer`,并在 `m_framebuffers` 非空时批量删除其中保存的 framebuffer id。
析构函数只做一件事:
## 使用建议
```cpp
Shutdown();
```
- 如果对象已经手动 `Shutdown()` 过,析构再次调用也是安全的。
- 该析构不会删除关联的纹理对象,只删除本类型自己创建的 FBO。
因此:
- 当前 `m_framebuffer` 对应的 FBO 会被删除。
- `m_framebuffers` 里如果存在额外句柄,也会在 `Shutdown()` 内尝试删除。
- 失败初始化路径里生成但未回滚的 FBO同样会在析构时被清理。
## 工程意义
这类轻量 OpenGL 封装如果没有析构兜底,调用方一旦在多分支代码或异常路径中遗漏 `Shutdown()`,就很容易留下 GPU 资源泄漏。RAII 不是“高级特性”,而是底层封装最基本的可靠性要求。
## 相关文档
- [Shutdown](Shutdown.md)
- [GetTexture](GetTexture.md)
- [OpenGLRenderTargetView()](Constructor.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::GetFramebuffer
# OpenGLRenderTargetView::GetFramebuffer()
```cpp
unsigned int GetFramebuffer() const;
@@ -6,19 +6,19 @@ unsigned int GetFramebuffer() const;
## 作用
返回该对象内部管理的 framebuffer id
返回当前对象持有的 framebuffer ID
## 返回值
- 初始化成功后返回非零 FBO id
- 构造后、初始化失败后或 `Shutdown()` 之后返回 `0`
- 当前 `m_framebuffer` 的值
## 当前实现行为
## 需要注意
- 这是直接返回成员变量的轻量 getter
- 返回的是该辅助类自己创建的独立 FBO不是引擎新路径中 `OpenGLFramebuffer` 对象的句柄
- 返回非零值不代表该 FBO 一定通过了最近一次完整性检查
- 因为初始化失败路径也会保留已经生成的 FBO 句柄,直到 [Shutdown](Shutdown.md) 或析构时才释放
## 相关文档
- [Bind](Bind.md)
- [Initialize](Initialize.md)
- [Shutdown](Shutdown.md)
- [BindFramebuffer](BindFramebuffer.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::GetHeight
# OpenGLRenderTargetView::GetHeight()
```cpp
int GetHeight() const;
@@ -6,19 +6,13 @@ int GetHeight() const;
## 作用
返回对象记录的高度
返回视图高度。
## 当前实现行为
- 当前实现始终返回成员 `m_height`
-`Initialize()``InitializeCubemap()` 都没有给 `m_height` 赋值,因此它通常保持构造时的 `0`
## 使用建议
- 不要依赖该方法获取真实纹理尺寸。
- 如果你需要宽高,应直接查询创建该 view 的纹理对象,或使用更新后的 framebuffer / resource view 路径。
和 [GetWidth](GetWidth.md) 一样,当前实现不会维护 `m_height`,因此返回值始终为 `0`
## 相关文档
- [GetWidth](GetWidth.md)
- [OpenGLRenderTargetView](OpenGLRenderTargetView.md)
- [Initialize](Initialize.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::GetMipLevel
# OpenGLRenderTargetView::GetMipLevel()
```cpp
int GetMipLevel() const;
@@ -6,18 +6,19 @@ int GetMipLevel() const;
## 作用
返回当前绑定到该 RTV 的 mip 级别。
返回当前视图记录的 mip 级别。
## 返回值
- 返回最近一次 `Initialize()` / `InitializeCubemap()` 保存到 `m_mipLevel` 的值。
- 当前 `m_mipLevel` 的值。
## 当前实现行为
- 这是直接返回成员变量的 getter
- 单元测试 `tests/RHI/OpenGL/unit/test_render_target_view.cpp` 会校验 2D 初始化后的 mip 值
- [Initialize](Initialize.md) 会把它设置为 `desc.mipLevel`
- [InitializeCubemap](InitializeCubemap.md) 会把它设置为传入的 `mipLevel`
- [Shutdown](Shutdown.md) 不会重置这个值。
## 相关文档
- [Initialize](Initialize.md)
- [InitializeCubemap](InitializeCubemap.md)
- [GetTexture](GetTexture.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::GetTexture
# OpenGLRenderTargetView::GetTexture()
```cpp
unsigned int GetTexture() const;
@@ -6,20 +6,21 @@ unsigned int GetTexture() const;
## 作用
返回该 view 当前关联的纹理 id
返回最近一次写入到该视图对象中的纹理 ID
## 返回值
- 返回 `m_texture`
- 在尚未初始化时通常为 `0`
- 当前 `m_texture` 的值
## 当前实现行为
## 需要注意
- 该值在 `Initialize()` / `InitializeCubemap()`写入。
- 该接口只暴露原生纹理 id不提供纹理对象本身的生命周期管理
- 单元测试会校验返回值与初始化时传入的纹理 id 一致
- 这个值在初始化开始阶段就会被写入。
- 初始化失败不会回滚它
- `Shutdown()` 也不会清空它
所以它适合用于调试“这个 view 最近指向了哪张纹理”,而不是判断当前对象是否仍然处于完全有效的初始化状态。
## 相关文档
- [Initialize](Initialize.md)
- [GetFramebuffer](GetFramebuffer.md)
- [InitializeCubemap](InitializeCubemap.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::GetWidth
# OpenGLRenderTargetView::GetWidth()
```cpp
int GetWidth() const;
@@ -6,17 +6,15 @@ int GetWidth() const;
## 作用
返回对象记录的宽度
返回视图宽度。
## 当前实现行为
- 当前实现始终返回成员 `m_width`
-`Initialize()``InitializeCubemap()` 没有更新该成员,因此通常仍为 `0`
当前实现不会在任何初始化路径里写入 `m_width`,因此返回值始终为 `0`
## 使用建议
## 为什么要明确写出来
- 该返回值目前更像占位字段,不应被当作可靠尺寸来源
- 实际渲染尺寸应以纹理描述或上层 framebuffer 配置为准。
在商业引擎里,渲染目标尺寸通常会被广泛用于 viewport 设置、attachment 校验、render graph 调度和调试工具显示。这个 getter 目前不具备那样的可信度,所以文档必须明确告诉调用方它只是占位接口
## 相关文档

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::Initialize
# OpenGLRenderTargetView::Initialize()
```cpp
bool Initialize(unsigned int texture, const OpenGLRenderTargetViewDesc& desc);
@@ -7,51 +7,59 @@ bool Initialize(unsigned int texture, int mipLevel = 0);
## 作用
定纹理创建一个独立的 framebuffer并把一个颜色附件绑定到 `GL_COLOR_ATTACHMENT0`
定纹理子资源创建一个颜色渲染目标 view并在内部生成承载它的 framebuffer
## 参数说明
## 参数
- `texture`: OpenGL 纹理 id
- `desc`: 旧式 RTV 描述结构指定纹理类型、mip、数组层或立方体面
- `mipLevel`: `Texture2D` 简化重载使用的 mip 级别。
- `texture`: 要附着到颜色槽位的 OpenGL 纹理对象 ID
- `desc`: 视图描述
- `mipLevel`: 简化重载使用的 mip 级别,它会构造一个 `Texture2D` 描述再转调完整重载
## 返回值
- framebuffer 完整时返回 `true`
- `glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE` 时返回 `false`
- `true`: framebuffer 完整性检查通过
- `false`: framebuffer 不完整
## 当前实现行为
### `Initialize(unsigned int texture, const OpenGLRenderTargetViewDesc& desc)`
完整重载会执行以下步骤:
- 保存 `m_texture``m_mipLevel``m_type`
- 调用 `glGenFramebuffers()` 创建独立 FBO
- 把目标附件固定绑定到 `GL_COLOR_ATTACHMENT0`
- 根据 `desc.type` 选择不同附着路径:
- `Texture2D`: `glFramebufferTexture2D`
- `Texture2DArray`: `glFramebufferTextureLayer`
- `Texture3D`: `glFramebufferTextureLayer`
- `TextureCube`: `glFramebufferTexture2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc.baseArraySlice, ...)`
- `TextureCubeArray`: `glFramebufferTextureLayer`
- 完成后检查 FBO 完整性,并在退出前解绑 `GL_FRAMEBUFFER`
1.`texture``desc.mipLevel``desc.type` 分别写入 `m_texture``m_mipLevel``m_type`
2. 调用 `glGenFramebuffers()` 生成 `m_framebuffer`
3. 绑定该 FBO
4. 计算 `unsigned int target = ToOpenGL(desc.type);`,但这个局部变量之后没有参与任何调用。
5. 固定把附件槽位设为 `GL_COLOR_ATTACHMENT0`
6.`desc.type` 选择附着路径:
- `Texture2D`: `glFramebufferTexture2D(..., GL_TEXTURE_2D, texture, desc.mipLevel)`
- `Texture2DArray`: `glFramebufferTextureLayer(..., texture, desc.mipLevel, desc.baseArraySlice)`
- `Texture3D`: `glFramebufferTextureLayer(..., texture, desc.mipLevel, desc.layer)`
- `TextureCube`: `glFramebufferTexture2D(..., GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc.baseArraySlice, texture, desc.mipLevel)`
- `TextureCubeArray`: `glFramebufferTextureLayer(..., texture, desc.mipLevel, desc.baseArraySlice)`
7. 调用 `glCheckFramebufferStatus(GL_FRAMEBUFFER)` 检查完整性。
8. 返回前总是解绑到默认 framebuffer `0`
### `Initialize(unsigned int texture, int mipLevel = 0)`
## 描述字段的真实消费情况
- 构造一个 `Texture2D` 的默认描述
- 然后转调主重载
- `desc.type` 会决定附着逻辑
- `desc.mipLevel` 会被真正使用
- `desc.baseArraySlice` 会用于数组纹理、cubemap 和 cubemap array。
- `desc.layer` 只在 `Texture3D` 路径中参与附着。
- `desc.arraySize` 当前未使用。
- `desc.format` 当前未使用。
## 重要限制
- 该类型只处理单颜色附件
- 即使初始化成功,`m_width` / `m_height` 仍不会被写入
- 初始化失败时,函数会解绑 framebuffer 并返回 `false`,但已经创建出的 FBO id 仍依赖后续 `Shutdown()` 统一删除
- 当前永远只附着到 `GL_COLOR_ATTACHMENT0`,没有表达“第 N 个颜色附件”的能力
- 失败路径不会回滚成员状态,也不会马上删除 FBO
- `m_width` / `m_height` 不会被更新,因此尺寸 getter 不可信
- 当前没有对传入纹理是否真能作为渲染目标做额外验证,除了最终的 FBO 完整性检查。
## 使用建议
## 设计说明
- 在现代 RHI 流程中,更推荐使用 [OpenGLFramebuffer](../OpenGLFramebuffer/OpenGLFramebuffer.md) 与 [OpenGLResourceView](../OpenGLResourceView/OpenGLResourceView.md) 的组合
- 该类更适合兼容旧路径、快速工具渲染或测试。
商业引擎里常见的长期方案,是把“资源 view 描述”和“framebuffer 组合”分成两层: 前者描述单个子资源视角,后者描述一次 pass 里有哪些颜色/深度附件。这种设计更易复用和缓存。当前类把这两层部分合并了,所以简单,但能力边界比较早就会暴露出来
## 相关文档
- [InitializeCubemap](InitializeCubemap.md)
- [Bind](Bind.md)
- [Shutdown](Shutdown.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::InitializeCubemap
# OpenGLRenderTargetView::InitializeCubemap()
```cpp
bool InitializeCubemap(unsigned int cubemap, int face, int mipLevel = 0);
@@ -6,31 +6,40 @@ bool InitializeCubemap(unsigned int cubemap, int face, int mipLevel = 0);
## 作用
立方体贴图的单个面创建一个颜色渲染目标。
cubemap 的单个 face 创建颜色渲染目标 view
## 参数说明
## 参数
- `cubemap`: 立方体贴图的 OpenGL 纹理 id
- `face`: 立方体面索引,会直接映射到 `GL_TEXTURE_CUBE_MAP_POSITIVE_X + face`
- `mipLevel`: 需要附着的 mip 级别
- `cubemap`: cubemap 纹理对象 ID
- `face`: 目标面索引。实现会直接映射到 `GL_TEXTURE_CUBE_MAP_POSITIVE_X + face`
- `mipLevel`: 目标 mip。
## 返回值
- framebuffer 完整时返回 `true`,否则返回 `false`
- `true`: framebuffer 完整。
- `false`: framebuffer 不完整。
## 当前实现行为
- 保存 `m_texture``m_mipLevel``m_type = RenderTargetType::TextureCube`
- 创建独立 FBO
- 使用 `glFramebufferTexture2D` 把指定 cube face 绑定到 `GL_COLOR_ATTACHMENT0`
- 检查 FBO 完整性后解绑 `GL_FRAMEBUFFER`
- `m_texture` 设置为 `cubemap`
- `m_mipLevel` 设置为 `mipLevel`
- `m_type` 设置为 `RenderTargetType::TextureCube`
- 生成并绑定一个新的 FBO
- 使用 `glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, cubemap, mipLevel)` 进行附着。
- 做完整性检查后解绑回 `0`
## 使用建议
## 需要注意
- `face` 参数当前不会额外校验范围,调用方应确保它位于立方体面的有效区间
- 如果你需要表达 cubemap array 或多附件渲染,建议改用新路径,而不是继续扩展这个旧辅助类
- 当前没有对 `face` 做范围校验
- 失败时不会回滚成员状态,也不会删除刚创建的 FBO
- 这个接口只是便捷包装,并没有比 [Initialize](Initialize.md) 提供更多能力。
## 适用场景
它适合环境贴图预处理、反射探针、立方体阴影贴图等“逐 face 渲染”的流程,因为那类场景天然就是一次只激活一个 cubemap 面。
## 相关文档
- [Initialize](Initialize.md)
- [GetMipLevel](GetMipLevel.md)
- [Bind](Bind.md)
- [Clear](Clear.md)

View File

@@ -6,55 +6,76 @@
**头文件**: `XCEngine/RHI/OpenGL/OpenGLRenderTargetView.h`
**描述**: 旧式 OpenGL 颜色渲染目标辅助类,内部为单个纹理附件创建独立 framebuffer。
**描述**: OpenGL 后端的轻量级颜色渲染目标视图封装,为单个纹理子资源创建并管理一个专用 framebuffer。
## 概览
`OpenGLRenderTargetView` 来自较早的 OpenGL 封装路径。它的核心思路非常直接:
在商业级图形引擎里render target view 的核心价值通常不是“拥有一张纹理”,而是“定义这张纹理在本次渲染里以什么子资源视角、什么附件槽位被使用”。这样资源分配、生命周期管理、渲染图编排和具体渲染阶段可以解耦。
- 接收一个已经存在的纹理 id
- 创建一个专属 framebuffer
- 把该纹理的某个 mip、数组层或 cubemap face 附着到 `GL_COLOR_ATTACHMENT0`
这和现代显式图形 API 中的 render-target view 概念有相似之处,但在当前引擎里,它已经与更新的 `OpenGLFramebuffer + OpenGLResourceView` 方案产生职责重叠。
OpenGL 没有独立的 RTV 对象,所以 `OpenGLRenderTargetView` 走的是常见的适配做法: 为每个颜色视图生成一个单独 FBO再把纹理的某个 mip、数组层或 cubemap face 附着到 `GL_COLOR_ATTACHMENT0`。这让上层仍然可以保留“创建 view -> 绑定 view -> 清除 / 绘制”的使用方式。
## 设计定位
可以把这个类理解成“快速创建单附件 FBO 的旧工具层”
这个类更像旧路径兼容层或工具层封装,而不是完整、长期的 framebuffer 抽象
它的优点是:
- 它的优点是调用直接、很适合单测和小型渲染样例。
- 它的优点是把 2D、数组、3D、cubemap、cubemap array 这些常见纹理形态都统一进了一个入口。
- 它的缺点是能力边界明显: 当前只附着到 `GL_COLOR_ATTACHMENT0`,没有真正表达多颜色附件组合,也没有和更完整的 framebuffer 描述体系完全融合。
- 实现非常直观
- 测试与工具代码里使用成本低
- 不需要先构造更完整的 framebuffer 描述
如果目标是更接近商业引擎的现代组织方式,`OpenGLFramebuffer``OpenGLResourceView` 那条路径更适合承载复杂 render pass、MRT、缓存复用和严格状态校验。`OpenGLRenderTargetView` 适合保持旧接口稳定,或者作为“快速把一张纹理当作单附件颜色目标使用”的轻量层。
它的缺点也很明显:
## 相关声明
- 只覆盖单颜色附件路径
- 没有和统一的 descriptor / framebuffer 体系深度融合
- `GetWidth()` / `GetHeight()` 这类字段没有真正维护
### `RenderTargetType`
如果你在构建商业级渲染架构,新的 `OpenGLFramebuffer` / `OpenGLResourceView` 路径更接近统一 RHI 的长期方案。
当前支持五种视图类型:
- `Texture2D`
- `Texture2DArray`
- `Texture3D`
- `TextureCube`
- `TextureCubeArray`
它们决定初始化时使用 `glFramebufferTexture2D()` 还是 `glFramebufferTextureLayer()`
### `OpenGLRenderTargetViewDesc`
描述结构包含:
- `type`: 视图类型。
- `mipLevel`: 目标 mip。
- `baseArraySlice`: 数组层索引,或 cubemap / cubemap array 的 face / slice 偏移。
- `arraySize`: 当前实现未使用。
- `layer`: 仅 `Texture3D` 路径会真正使用。
- `format`: 当前实现未使用。
可以看出,接口已经朝“更通用的 subresource view 描述”靠拢,但落地实现仍然只消费了其中的一部分字段。
## 生命周期
- 构造时不创建任何 OpenGL 对象。
- `Initialize()` / `InitializeCubemap()` 成功后持有一个独立 FBO
- `Shutdown()` 或析构时删除该 FBO
## 线程语义
- 当前实现没有同步保护。
- 所有调用都应视为依赖当前 OpenGL 上下文,通常应在拥有该上下文的渲染线程执行。
- [OpenGLRenderTargetView()](Constructor.md) 构造空对象。
- [Initialize](Initialize.md) 或 [InitializeCubemap](InitializeCubemap.md) 生成 FBO 并附着颜色纹理子资源
- [Bind](Bind.md) / [Unbind](Unbind.md) 切换 framebuffer
- [Clear](Clear.md) 在当前 view 对应的 FBO 上执行清除。
- [Shutdown](Shutdown.md) 删除内部 FBO。
## 当前实现的真实行为
- 只操作颜色附件,不直接表达深度/模板附件创建
- `Bind(slot)``slot` 参数被忽略
- 多 framebuffer 的 `Bind(count, ...)` 是一套明显偏旧的辅助逻辑,不等价于现代 MRT 抽象
- `Clear()` 不会恢复之前的 framebuffer 绑定
- `GetWidth()` / `GetHeight()` 当前基本恒为 `0`
- 单元测试 `tests/RHI/OpenGL/unit/test_render_target_view.cpp` 只覆盖了初始化、绑定/解绑、纹理 id 和 mip 访问这些基础能力
- 所有初始化路径都只把纹理附着到 `GL_COLOR_ATTACHMENT0`
- `Initialize()` 里虽然计算了 `unsigned int target = ToOpenGL(desc.type);`,但这个局部变量最终没有被使用
- 初始化失败时函数返回 `false`,但不会立即删除刚生成的 FBO也不会回滚成员状态
- [Bind](Bind.md) 的 `slot` 参数当前被完全忽略
- 多 FBO 重载 `Bind(count, framebuffers, drawBuffers)` 并不是真正的 MRT 抽象。它只是逐个绑定传入 framebuffer并分别调用一次 `glDrawBuffers(1, ...)`,最终留下最后一个 FBO 处于绑定状态
- [GetWidth](GetWidth.md) / [GetHeight](GetHeight.md) 始终返回 `0`,因为实现没有维护尺寸
- `m_framebuffers` 在 [Shutdown](Shutdown.md) 中会被尝试统一删除,但当前实现里没有任何地方向这个数组写入内容。
- 单测 `tests/RHI/OpenGL/unit/test_render_target_view.cpp` 只验证了初始化、绑定/解绑和基础 getter不能把它看成复杂 attachment 行为的严格证明。
## 使用建议
- 当你需要快速把单张纹理的某个子资源作为颜色渲染目标使用时,这个类非常直接。
- 当前不要把 `slot``arraySize``format`、[GetWidth](GetWidth.md)、[GetHeight](GetHeight.md) 当作可靠能力。
- 如果需求已经涉及 MRT、统一 render pass 描述、framebuffer 复用或更严格的后端一致性,应优先转向更完整的 framebuffer / resource view 路径。
- `Initialize()` 失败后,建议立即调用 [Shutdown](Shutdown.md) 清理半初始化状态。
## 关键方法
@@ -67,5 +88,6 @@
## 相关文档
- [OpenGL](../OpenGL.md)
- [OpenGLTexture](../OpenGLTexture/OpenGLTexture.md)
- [OpenGLFramebuffer](../OpenGLFramebuffer/OpenGLFramebuffer.md)
- [OpenGLResourceView](../OpenGLResourceView/OpenGLResourceView.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::Shutdown
# OpenGLRenderTargetView::Shutdown()
```cpp
void Shutdown();
@@ -6,20 +6,27 @@ void Shutdown();
## 作用
删除该对象创建的 framebuffer,并清理批量 framebuffer 缓存
释放当前对象持有的 framebuffer 资源
## 当前实现行为
- 如果 `m_framebuffer != 0`,调用 `glDeleteFramebuffers(1, &m_framebuffer)`,然后把它重置为 `0`
- 如果 `m_framebuffers` 非空,调用 `glDeleteFramebuffers(count, data)` 后清空数组。
- 不会重置 `m_texture``m_mipLevel``m_width``m_height` `m_type`
函数包含两段清理逻辑:
1. 如果 `m_framebuffer != 0`,删除这个单独的 FBO并把 `m_framebuffer` 设回 `0`
2. 如果 `m_framebuffers` 非空,调用一次 `glDeleteFramebuffers()` 删除数组里的所有句柄,然后清空数组。
## 关键事实
- 当前实现中没有任何地方向 `m_framebuffers` 写入内容,所以第二段逻辑大多数情况下不会实际发生作用。
- `m_texture``m_mipLevel``m_type``m_width``m_height` 不会被重置。
## 使用建议
- 调用后,`GetFramebuffer()` 会变成 `0`,但 `GetTexture()` 仍可能返回旧值,因为纹理句柄没有被清空
- 如果你依赖“完全复位”的对象状态,应该销毁对象重新构造,而不是只依赖 `Shutdown()`
- 如果 `Initialize()` 失败,最好显式调用一次 `Shutdown()`
- 若要复用同一个对象重新初始化,也应先执行 `Shutdown()`,避免旧 FBO 遗留在对象状态里
## 相关文档
- [Destructor](Destructor.md)
- [~OpenGLRenderTargetView()](Destructor.md)
- [Initialize](Initialize.md)
- [GetFramebuffer](GetFramebuffer.md)

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::Unbind
# OpenGLRenderTargetView::Unbind()
```cpp
void Unbind();
@@ -6,12 +6,18 @@ void Unbind();
## 作用
当前 framebuffer,恢复到默认 framebuffer `0`
当前 framebuffer 绑定,切回默认 framebuffer。
## 当前实现行为
- 直接执行 `glBindFramebuffer(GL_FRAMEBUFFER, 0)`
- 不恢复 draw buffer、viewport 或其他状态。
```cpp
glBindFramebuffer(GL_FRAMEBUFFER, 0);
```
## 需要注意
- 它不会恢复先前绑定的某个自定义 FBO而是总是切回 `0`
- 如果上层状态机期望恢复到先前 pass 的 framebuffer这个函数本身并不提供那层语义。
## 相关文档

View File

@@ -1,4 +1,4 @@
# OpenGLRenderTargetView::UnbindFramebuffer
# OpenGLRenderTargetView::UnbindFramebuffer()
```cpp
static void UnbindFramebuffer();
@@ -6,14 +6,15 @@ static void UnbindFramebuffer();
## 作用
静态解绑当前 framebuffer。
解除当前 framebuffer 绑定,切回默认 framebuffer。
## 当前实现行为
- 仅执行 `glBindFramebuffer(GL_FRAMEBUFFER, 0)`
- 行为与实例方法 [Unbind](Unbind.md) 一致,只是无需依赖对象实例。
```cpp
glBindFramebuffer(GL_FRAMEBUFFER, 0);
```
## 相关文档
- [BindFramebuffer](BindFramebuffer.md)
- [Unbind](Unbind.md)
- [BindFramebuffer](BindFramebuffer.md)

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::AddVertexBuffer
# OpenGLVertexArray::AddVertexBuffer()
```cpp
void AddVertexBuffer(unsigned int buffer, const VertexAttribute& attribute);
@@ -6,28 +6,28 @@ void AddVertexBuffer(unsigned int buffer, const VertexAttribute& attribute);
## 作用
把一个顶点缓冲及其属性描述写入当前 VAO。
把一个顶点缓冲和对应属性描述写入当前 VAO。
## 参数说明
## 参数
- `buffer`: 顶点缓冲对象 id。
- `attribute`: 顶点属性描述,包含 attribute index、分量数、类型、是否归一化、步长和偏移
- `buffer`: 顶点缓冲对象 ID
- `attribute`: 顶点属性描述,包括位置、分量数、类型、步长和偏移
## 当前实现行为
- 绑定当前 VAO。
- 绑定 `buffer` `GL_ARRAY_BUFFER`
- 调用 `glEnableVertexAttribArray(attribute.index)`
- 通过 `glVertexAttribPointer()` 写入属性格式
- 随后解绑 `GL_ARRAY_BUFFER` 和 VAO
-`m_vertexBufferCount` 自增 1。
- 绑定当前 `m_vao`
- 绑定 `GL_ARRAY_BUFFER = buffer`
- 调用 `glEnableVertexAttribArray(attribute.index)`
- 调用 `glVertexAttribPointer(...)` 写入属性格式
- 然后把 `GL_ARRAY_BUFFER``VAO` 都解绑
- 最后`m_vertexBufferCount` 加一
## 重要限制
## 需要特别注意
- 当前实现无论属性类型是否为整数或双精度,都统一走 `glVertexAttribPointer()`,没有使用 `glVertexAttribIPointer()` `glVertexAttribLPointer()`
- 这意味着某些非浮点属性路径在语义上是简化实现。
- 当前始终使用 `glVertexAttribPointer()`,没有针对整数属性使用 `glVertexAttribIPointer()`,也没有针对 double 属性使用 `glVertexAttribLPointer()`
- `m_vertexBufferCount` 只是内部计数,当前没有对外查询接口,也不参与其他逻辑
## 相关文档
- [Initialize](Initialize.md)
- [Bind](Bind.md)
- [SetIndexBuffer](SetIndexBuffer.md)

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::Bind
# OpenGLVertexArray::Bind()
```cpp
void Bind() const;
@@ -6,12 +6,11 @@ void Bind() const;
## 作用
绑定当前 VAO。
当前 VAO 绑定为活动顶点数组对象
## 当前实现行为
- 直接执行 `glBindVertexArray(m_vao)`
- 不检查 `m_vao` 是否有效。
- 直接调用 `glBindVertexArray(m_vao)`
## 相关文档

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::OpenGLVertexArray
# OpenGLVertexArray::OpenGLVertexArray()
```cpp
OpenGLVertexArray();
@@ -6,17 +6,14 @@ OpenGLVertexArray();
## 作用
构造一个空的 VAO 封装对象。
构造一个尚未创建原生 VAO 对象。
## 当前实现行为
- 初始化默认值:
- `m_vao = 0`
- `m_indexBuffer = 0`
- `m_indexCount = 0`
- `m_vertexBufferCount = 0`
- `m_vao``m_indexBuffer``m_indexCount` 置为 `0`
- `m_vertexBufferCount` 置为 `0`
## 相关文档
- [Initialize](Initialize.md)
- [OpenGLVertexArray](OpenGLVertexArray.md)
- [GetID](GetID.md)

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::~OpenGLVertexArray
# OpenGLVertexArray::~OpenGLVertexArray()
```cpp
~OpenGLVertexArray();
@@ -6,14 +6,13 @@
## 作用
销毁对象并删除底层 VAO
析构 VAO 包装对象
## 当前实现行为
- 析构函数内部调用 [Shutdown](Shutdown.md)
- 只负责删除 VAO不负责删除顶点缓冲或索引缓冲。
- 析构函数直接调用 [Shutdown](Shutdown.md)
## 相关文档
- [Shutdown](Shutdown.md)
- [SetIndexBuffer](SetIndexBuffer.md)
- [OpenGLVertexArray](OpenGLVertexArray.md)

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::GetID
# OpenGLVertexArray::GetID()
```cpp
unsigned int GetID() const;
@@ -6,14 +6,13 @@ unsigned int GetID() const;
## 作用
返回底层 VAO id
返回底层 OpenGL VAO 对象名
## 返回值
## 当前实现行为
- 初始化成功后通常为非零值。
- 构造后或 `Shutdown()` 之后返回 `0`
- 直接返回 `m_vao`
## 相关文档
- [Bind](Bind.md)
- [Shutdown](Shutdown.md)
- [Initialize](Initialize.md)

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::GetIndexBuffer
# OpenGLVertexArray::GetIndexBuffer()
```cpp
unsigned int GetIndexBuffer() const;
@@ -6,16 +6,12 @@ unsigned int GetIndexBuffer() const;
## 作用
返回当前记录的索引缓冲 id
返回当前记录的索引缓冲对象 ID
## 当前实现行为
- 该值仅在 [SetIndexBuffer](SetIndexBuffer.md) 时更新。
- `Shutdown()` 不会把它重置回 `0`
## 使用建议
- 它表示“上次通过该封装记录的索引缓冲”,不是对 OpenGL 当前绑定状态的实时查询。
- 直接返回 `m_indexBuffer`
- 该值只会在 [SetIndexBuffer](SetIndexBuffer.md) 中更新
## 相关文档

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::GetIndexCount
# OpenGLVertexArray::GetIndexCount()
```cpp
unsigned int GetIndexCount() const;
@@ -6,17 +6,12 @@ unsigned int GetIndexCount() const;
## 作用
返回当前记录的索引数量。
返回当前对象记录的索引数量。
## 当前实现行为
- 当前实现始终返回成员 `m_indexCount`
-源码中没有任何地方更新这个成员,因此它默认保持`0`
## 使用建议
- 不要把它当作可靠的绘制索引数量来源。
- 实际绘制计数需要由上层 draw 调用参数或资源描述维护。
- 直接返回 `m_indexCount`
-当前实现里 `m_indexCount` 从未被更新,因此通常恒`0`
## 相关文档

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::Initialize
# OpenGLVertexArray::Initialize()
```cpp
bool Initialize();
@@ -6,18 +6,19 @@ bool Initialize();
## 作用
创建一个底层 OpenGL vertex array object
创建底层 OpenGL VAO
## 返回值
- 当前实现恒定返回 `true`
`bool`当前实现始终返回 `true`
## 当前实现行为
- 调用 `glGenVertexArrays(1, &m_vao)`
- 不检查返回结果,也不验证生成的 id 是否非零
- 调用 `glGenVertexArrays(1, &m_vao)`
- 不检查生成结果是否非零
- 不检查 OpenGL 错误
## 相关文档
- [AddVertexBuffer](AddVertexBuffer.md)
- [GetID](GetID.md)
- [Shutdown](Shutdown.md)

View File

@@ -10,49 +10,45 @@
## 概览
`OpenGLVertexArray` 是一个相对旧式、直接的 OpenGL 工具封装。它做的事情很简单:
`OpenGLVertexArray` 是一个非常直接的原生 VAO 包装器。它主要负责三件事:
- 创建一个 VAO
- 把顶点属性描述写入这个 VAO
- 记录一个索引缓冲绑定
- 创建 VAO
- 往 VAO 里写顶点属性描述
- 记录一个索引缓冲对象 ID
并不尝试成为完整的跨后端输入布局系统。更现代的路径已经更多依赖 `OpenGLCommandList` 和 pipeline / input layout 的组合去驱动属性配置
## 设计定位
可以把它看成“对原生 VAO 的薄封装”,适合:
- 单元测试
- OpenGL 集成样例
- 较直接的后端实验代码
但它不是一个高度完备的商业级输入装配抽象,当前实现里仍有明显的简化点。
## 生命周期
- 构造后为空对象。
- [Initialize](Initialize.md) 创建原生 VAO。
- [AddVertexBuffer](AddVertexBuffer.md) / [SetIndexBuffer](SetIndexBuffer.md) 向 VAO 写入状态。
- [Shutdown](Shutdown.md) 删除 VAO。
## 线程语义
- 无锁。
- 所有操作依赖 OpenGL 上下文,应在渲染线程或拥有当前上下文的线程执行。
不是完整的现代输入装配系统,也不是跨后端 `InputLayout` 的全部落地点。当前引擎里更完整的绘制路径仍然依赖 `OpenGLCommandList``OpenGLPipelineState` 和更高层的输入布局描述
## 当前实现的真实行为
- `AddVertexBuffer()` 总是`glVertexAttribPointer()` 写属性。
- `SetIndexBuffer()` 会绑定 `GL_ELEMENT_ARRAY_BUFFER`,但 `type` 参数当前被忽略。
- `m_indexCount` 从未被更新,因此 [GetIndexCount](GetIndexCount.md) 目前基本没有实际意义。
- `Shutdown()` 只删除 VAO不清理缓存的索引缓冲字段。
- 单元测试 `tests/RHI/OpenGL/unit/test_vertex_array.cpp` 覆盖了初始化、顶点缓冲添加、索引缓冲设置、绑定/解绑和多属性场景。
- [Initialize](Initialize.md) 只调`glGenVertexArrays`
- [AddVertexBuffer](AddVertexBuffer.md) 统一走 `glVertexAttribPointer`
- [SetIndexBuffer](SetIndexBuffer.md) 会绑定 `GL_ELEMENT_ARRAY_BUFFER`,但 `type` 参数当前被忽略
- [GetIndexCount](GetIndexCount.md) 当前没有实际意义,因为 `m_indexCount` 从未更新
- [Shutdown](Shutdown.md) 只删除 VAO不会清空 `m_indexBuffer``m_indexCount``m_vertexBufferCount`
## 设计背景
VAO 属于典型的 OpenGL 原生状态对象。把它保留为一个单独的小封装,有两个实际好处:
- 测试和 OpenGL 专用样例代码可以直接操作它
- 上层不必每次都重复写一遍 VAO 创建与属性配置样板代码
但从商业级引擎角度看,它更像“后端工具层”,而不是长期唯一的输入装配抽象。
## 生命周期
- [OpenGLVertexArray()](Constructor.md) 初始化为空对象
- [Initialize](Initialize.md) 创建原生 VAO
- [AddVertexBuffer](AddVertexBuffer.md) / [SetIndexBuffer](SetIndexBuffer.md) 写入状态
- [Bind](Bind.md) / [Unbind](Unbind.md) 切换当前 VAO
- [Shutdown](Shutdown.md) 删除原生 VAO
## 当前限制
- 不区分整数属性和浮点属性写入路径
- 不维护真实索引数量
- 不是当前 RHI 输入布局路径的唯一或最终方案。
- 不区分浮点、整数、双精度属性专用写入路径
- 不维护真实索引数量
- `type` 参数只保留接口形状,没有参与行为
- 缺少错误处理和状态校验
## 关键方法
@@ -64,5 +60,6 @@
## 相关文档
- [OpenGL](../OpenGL.md)
- [OpenGLCommandList](../OpenGLCommandList/OpenGLCommandList.md)
- [OpenGLBuffer](../OpenGLBuffer/OpenGLBuffer.md)
- [OpenGLPipelineState](../OpenGLPipelineState/OpenGLPipelineState.md)

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::SetIndexBuffer
# OpenGLVertexArray::SetIndexBuffer()
```cpp
void SetIndexBuffer(unsigned int buffer, unsigned int type);
@@ -6,24 +6,24 @@ void SetIndexBuffer(unsigned int buffer, unsigned int type);
## 作用
一个索引缓冲绑定到当前 VAO。
把索引缓冲绑定到当前 VAO。
## 参数说明
## 参数
- `buffer`: 索引缓冲对象 id。
- `type`: 索引类型参数
- `buffer`: 索引缓冲对象 ID
- `type`: 预留的索引类型参数
## 当前实现行为
- 绑定当前 VAO。
-`buffer` 绑定到 `GL_ELEMENT_ARRAY_BUFFER`
- 解绑 VAO
- 保存 `m_indexBuffer = buffer`
- 绑定当前 `m_vao`
-`GL_ELEMENT_ARRAY_BUFFER` 绑定到 `buffer`
- 然后解绑 VAO
- `m_indexBuffer` 更新为 `buffer`
## 重要限制
## 需要特别注意
- `type` 参数当前完全没有被使用
- 该函数也不会更新 `m_indexCount`
- `type` 参数当前完全使用
- `m_indexCount` 也不会在这里更新
## 相关文档

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::Shutdown
# OpenGLVertexArray::Shutdown()
```cpp
void Shutdown();
@@ -6,19 +6,15 @@ void Shutdown();
## 作用
删除底层 VAO。
删除当前 VAO。
## 当前实现行为
- 如果 `m_vao != 0`,调用 `glDeleteVertexArrays(1, &m_vao)`
- 然后把 `m_vao` `0`
-重置 `m_indexBuffer``m_indexCount``m_vertexBufferCount`
## 使用建议
- 如果你需要“完全复位”的对象状态,建议重新构造对象,而不是复用 `Shutdown()` 之后的实例。
- `m_vao != 0`,调用 `glDeleteVertexArrays(1, &m_vao)`
- 然后把 `m_vao` `0`
- 不重置 `m_indexBuffer``m_indexCount``m_vertexBufferCount`
## 相关文档
- [Destructor](Destructor.md)
- [GetID](GetID.md)
- [Initialize](Initialize.md)

View File

@@ -1,4 +1,4 @@
# OpenGLVertexArray::Unbind
# OpenGLVertexArray::Unbind()
```cpp
void Unbind() const;
@@ -6,13 +6,13 @@ void Unbind() const;
## 作用
解绑当前 VAO恢复到默认 VAO `0`
解绑当前 VAO切回默认顶点数组状态
## 当前实现行为
- 直接执行 `glBindVertexArray(0)`
- 直接调用 `glBindVertexArray(0)`
## 相关文档
- [Bind](Bind.md)
- [Shutdown](Shutdown.md)
- [GetID](GetID.md)

View File

@@ -1,6 +1,6 @@
# API 文档重构状态
**生成时间**: `2026-03-28 01:38:41`
**生成时间**: `2026-03-28 02:07:52`
**来源**: `docs/api/_tools/audit_api_docs.py`