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

108 lines
5.2 KiB
Markdown
Raw Normal View History

2026-03-26 16:45:24 +08:00
# OpenGLTexture
**命名空间**: `XCEngine::RHI`
**类型**: `class`
**头文件**: `XCEngine/RHI/OpenGL/OpenGLTexture.h`
**描述**: OpenGL 后端的纹理资源封装,负责创建原生 texture 对象、缓存资源维度元数据,并提供最基础的绑定与采样参数配置入口。
## 概览
`OpenGLTexture` 承担的是“纹理资源本体”职责,而不是完整的 view 系统。它主要负责:
- 创建 1D / 2D / 2DArray / 3D / Cube / CubeArray 纹理对象
- 上传基础像素数据
- 维护宽高深、mip 数量、OpenGL 纹理类型等缓存字段
- 提供绑定、image bind、mipmap 生成和采样参数设置接口
在商业引擎里,这一层通常只关心“资源如何存在于 GPU 上”;至于它在本次渲染里被当作 SRV、UAV、RTV 还是 DSV 使用,则会交给 resource view 或 framebuffer 层表达。当前 OpenGL 后端也遵循了类似分层思路。
## 设计背景
OpenGL 的纹理对象天然把“资源本体”和“一部分采样状态”绑在一起,这和 D3D12/Vulkan 那种显式分离资源、view、sampler 的风格不同。`OpenGLTexture` 的设计采用了一个实用主义折中:
- 资源分配、上传和基础采样参数由 `OpenGLTexture` 直接负责。
- 更细的资源视图语义交给 `OpenGLResourceView``OpenGLRenderTargetView``OpenGLDepthStencilView` 等类型处理。
这样做的好处是易于落地和调试;代价是某些字段看起来像完整抽象,但实际上只是缓存元数据,必须通过文档把边界讲清楚。
## 相关枚举
### `OpenGLTextureType`
当前支持:
- `Texture1D`
- `Texture2D`
- `Texture2DArray`
- `Texture3D`
- `TextureCube`
- `TextureCubeArray`
它决定了 [Initialize](Initialize.md) 内部选用 `glTexImage1D``glTexImage2D` 还是 `glTexImage3D`,以及默认 wrap 参数如何设置。
### `OpenGLFormat`
头文件中声明了:
- `R8`
- `RG8`
- `RG32F`
- `RGBA8`
- `RGBA16F`
- `RGBA32F`
- `Depth24Stencil8`
- `Depth32F`
- `CompressedDXT1`
- `CompressedDXT5`
但当前 `ToOpenGLFormat()` 实际只处理到 `Depth32F``CompressedDXT1``CompressedDXT5` 在现有实现里不会走压缩纹理上传路径,而会落入默认分支,退化为 `GL_RGBA8` 的普通纹理格式映射。
### `OpenGLInternalFormat`
头文件还声明了 `OpenGLInternalFormat` 数值枚举,但当前 `OpenGLTexture` 的实现并不直接消费它,而是通过 `OpenGLFormat + ToOpenGLFormat()` 获取真正的 OpenGL internal format / format / type 组合。
## 生命周期
- [OpenGLTexture()](Constructor.md) 构造空对象。
- [Initialize](Initialize.md)、[Initialize2D](Initialize2D.md)、[InitializeCubeMap](InitializeCubeMap.md) 负责创建纹理资源。
- [LoadFromFile](LoadFromFile.md) 通过 stb_image 加载文件后转调 [Initialize2D](Initialize2D.md)。
- [Bind](Bind.md)、[BindImage](BindImage.md)、[GenerateMipmap](GenerateMipmap.md)、[SetFiltering](SetFiltering.md)、[SetWrapping](SetWrapping.md) 在使用阶段配置和绑定纹理。
- [Shutdown](Shutdown.md) 删除原生纹理对象。
## 当前实现的真实行为
- 通用 [Initialize](Initialize.md) 只上传或分配 level 0不会按 `mipLevels` 循环创建所有 mip 级别。
- [Initialize2D](Initialize2D.md) 在 `generateMipmap = true` 时会实际调用 `glGenerateMipmap()`,但把 `m_mipLevels` 记成 `0`,而不是真实 mip 数。
- [InitializeCubeMap](InitializeCubeMap.md) 会把同一个 `data` 指针上传到六个 cubemap face且不会自动生成额外 mip 级别。
- [LoadFromFile](LoadFromFile.md) 当前总是以 `STBI_rgb_alpha` 方式读取,并关闭自动 mipmap 生成。
- [BindImage](BindImage.md) 固定绑定 `level 0``layered = GL_FALSE``layer = 0``format = GL_RGBA8`,不是通用 image view 封装。
- [Unbind](Unbind.md) 不接收 slot 参数,只会在“当前 active texture unit”上解绑当前 target。
- [GetFormat](GetFormat.md) 默认返回 `Format::Unknown`,除非外部显式调用 [SetFormat](SetFormat.md)。例如 `OpenGLDevice::CreateTexture()` 会在初始化后补一次 `SetFormat()`
- 单测 `tests/RHI/OpenGL/unit/test_texture.cpp` 只覆盖基本初始化、绑定、mipmap 生成和采样参数调用,不验证复杂格式与 image 绑定语义。
## 使用建议
- 如果纹理是通过 `OpenGLDevice::CreateTexture()` 创建的,`Format` 和初始 `ResourceStates` 元数据会更完整;如果直接调用 `OpenGLTexture::Initialize*()`,这些值需要你自行补齐。
- 不要把 [GetMipLevels](GetMipLevels.md) 在 `Initialize2D(generateMipmap = true)` 后的返回值当作真实 mip 层数。
- 若需要更一般化的 UAV / subresource image 语义,优先查看 `OpenGLResourceView`,不要直接依赖 [BindImage](BindImage.md)。
## 关键方法
- [Initialize](Initialize.md)
- [Initialize2D](Initialize2D.md)
- [InitializeCubeMap](InitializeCubeMap.md)
- [Bind](Bind.md)
- [BindImage](BindImage.md)
- [GenerateMipmap](GenerateMipmap.md)
2026-03-26 16:45:24 +08:00
## 相关文档
- [OpenGL](../OpenGL.md)
- [OpenGLEnums](../OpenGLEnums/OpenGLEnums.md)
- [OpenGLResourceView](../OpenGLResourceView/OpenGLResourceView.md)
- [OpenGLRenderTargetView](../OpenGLRenderTargetView/OpenGLRenderTargetView.md)
- [OpenGLDepthStencilView](../OpenGLDepthStencilView/OpenGLDepthStencilView.md)