137 lines
3.3 KiB
Markdown
137 lines
3.3 KiB
Markdown
|
|
# D3D12SwapChain
|
|||
|
|
|
|||
|
|
DirectX 12 交换链的 D3D12 实现,封装了 `IDXGISwapChain3`。
|
|||
|
|
|
|||
|
|
## 头文件
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
#include <XCEngine/RHI/D3D12/D3D12SwapChain.h>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 继承关系
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
RHISwapChain (interface)
|
|||
|
|
└── D3D12SwapChain (implementation)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 公共成员函数
|
|||
|
|
|
|||
|
|
### 构造函数与析构函数
|
|||
|
|
|
|||
|
|
#### `D3D12SwapChain()`
|
|||
|
|
默认构造函数。
|
|||
|
|
|
|||
|
|
#### `~D3D12SwapChain() override`
|
|||
|
|
析构函数,确保调用 `Shutdown()`。
|
|||
|
|
|
|||
|
|
### 初始化
|
|||
|
|
|
|||
|
|
#### `bool Initialize(IDXGIFactory4* factory, ID3D12CommandQueue* commandQueue, HWND windowHandle, uint32_t width, uint32_t height, uint32_t bufferCount = 2)`
|
|||
|
|
创建新的交换链。
|
|||
|
|
- `factory`: DXGI Factory
|
|||
|
|
- `commandQueue`: 命令队列
|
|||
|
|
- `windowHandle`: 窗口句柄
|
|||
|
|
- `width` / `height`: 交换链尺寸
|
|||
|
|
- `bufferCount`: 后台缓冲区数量(默认 2)
|
|||
|
|
- 返回: 初始化是否成功
|
|||
|
|
|
|||
|
|
#### `bool Initialize(IDXGISwapChain* swapChain, uint32_t width, uint32_t height)`
|
|||
|
|
从现有 `IDXGISwapChain` 初始化。
|
|||
|
|
- `swapChain`: 已存在的交换链
|
|||
|
|
- `width` / `height`: 尺寸
|
|||
|
|
- 返回: 初始化是否成功
|
|||
|
|
|
|||
|
|
#### `void Shutdown() override`
|
|||
|
|
释放交换链资源。
|
|||
|
|
|
|||
|
|
### 交换链操作
|
|||
|
|
|
|||
|
|
#### `uint32_t GetCurrentBackBufferIndex() const override`
|
|||
|
|
获取当前后台缓冲区索引。
|
|||
|
|
|
|||
|
|
#### `RHITexture* GetCurrentBackBuffer() override`
|
|||
|
|
获取当前后台缓冲区纹理。
|
|||
|
|
|
|||
|
|
#### `D3D12Texture* GetBackBuffer(uint32_t index) const`
|
|||
|
|
获取指定索引的后台缓冲区。
|
|||
|
|
|
|||
|
|
#### `void Present(uint32_t syncInterval = 1, uint32_t flags = 0) override`
|
|||
|
|
呈现(显示)内容。
|
|||
|
|
- `syncInterval`: 垂直同步间隔 (0=立即, 1-4=等待)
|
|||
|
|
- `flags`: 附加标志
|
|||
|
|
|
|||
|
|
#### `void Resize(uint32_t width, uint32_t height) override`
|
|||
|
|
调整交换链尺寸。
|
|||
|
|
|
|||
|
|
### 显示模式
|
|||
|
|
|
|||
|
|
#### `void SetFullscreen(bool fullscreen) override`
|
|||
|
|
切换全屏模式。
|
|||
|
|
|
|||
|
|
#### `bool IsFullscreen() const override`
|
|||
|
|
检查是否处于全屏模式。
|
|||
|
|
|
|||
|
|
### 事件处理
|
|||
|
|
|
|||
|
|
#### `bool ShouldClose() const override`
|
|||
|
|
检查是否应该关闭(全屏时按 Alt+Enter)。
|
|||
|
|
|
|||
|
|
#### `void SetShouldClose(bool shouldClose)`
|
|||
|
|
设置关闭标志。
|
|||
|
|
|
|||
|
|
#### `void PollEvents() override`
|
|||
|
|
轮询窗口事件。
|
|||
|
|
|
|||
|
|
### 原生接口
|
|||
|
|
|
|||
|
|
#### `void* GetNativeHandle() override`
|
|||
|
|
获取原生句柄。
|
|||
|
|
|
|||
|
|
#### `IDXGISwapChain3* GetSwapChain() const`
|
|||
|
|
获取底层 `IDXGISwapChain3` 指针。
|
|||
|
|
|
|||
|
|
## 内部成员
|
|||
|
|
|
|||
|
|
| 成员 | 类型 | 描述 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| `m_swapChain` | `ComPtr<IDXGISwapChain3>` | DXGI 交换链 |
|
|||
|
|
| `m_commandQueue` | `ComPtr<ID3D12CommandQueue>` | 命令队列引用 |
|
|||
|
|
| `m_windowHandle` | `HWND` | 窗口句柄 |
|
|||
|
|
| `m_width` | `uint32_t` | 宽度 |
|
|||
|
|
| `m_height` | `uint32_t` | 高度 |
|
|||
|
|
| `m_bufferCount` | `uint32_t` | 缓冲区数量 |
|
|||
|
|
| `m_backBuffers` | `vector<D3D12Texture>` | 后台缓冲区纹理 |
|
|||
|
|
|
|||
|
|
## 使用示例
|
|||
|
|
|
|||
|
|
```cpp
|
|||
|
|
D3D12SwapChain swapChain;
|
|||
|
|
swapChain.Initialize(
|
|||
|
|
device->GetFactory(),
|
|||
|
|
cmdQueue->GetCommandQueue(),
|
|||
|
|
hwnd, 1920, 1080, 2);
|
|||
|
|
|
|||
|
|
// Render loop
|
|||
|
|
while (!swapChain.ShouldClose()) {
|
|||
|
|
swapChain.PollEvents();
|
|||
|
|
|
|||
|
|
auto backBuffer = swapChain.GetCurrentBackBuffer();
|
|||
|
|
// Transition to render target state
|
|||
|
|
// Render...
|
|||
|
|
// Transition to present state
|
|||
|
|
|
|||
|
|
swapChain.Present(1, 0);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Resize
|
|||
|
|
swapChain.Resize(3840, 2160);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 备注
|
|||
|
|
|
|||
|
|
- `syncInterval = 0`: 立即呈现,可能产生撕裂
|
|||
|
|
- `syncInterval = 1`: 等待垂直同步(推荐)
|
|||
|
|
- 全屏模式切换需要处理窗口消息
|
|||
|
|
- 窗口尺寸改变后必须调用 `Resize`
|