From b7eebc11b2ebcb9d1dbf3caaf76625c4a1282131 Mon Sep 17 00:00:00 2001 From: SpecialX <47072643+wangxiner55@users.noreply.github.com> Date: Thu, 26 Mar 2026 16:53:09 +0800 Subject: [PATCH] feat: add Graphics module with D3D12 backend and documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Graphics Module: - Add platform abstraction layer (GraphicsPlatformInterface) - Add unified renderer entry point (Renderer) - Add D3D12 backend implementation (D3D12Core, D3D12Interface) - Add TestRenderer for multi-window rendering tests Documentation: - Add Graphics渲染架构分析.md - Add D3D12学习Wiki.md - Add changelogs directory with per-commit documentation - Add 20260326-dx12-initial.md for initial framework - Add 20260326-d3d12-foundation.md for Graphics module Fixes: - Resolve header include issues and type redefinition errors --- .gitignore | 2 +- Engine/Engine.vcxproj | 8 +- Engine/Engine.vcxproj.filters | 7 + .../Graphics/Direct3D12/D3D12CommonHeader.h | 17 ++ Engine/Graphics/Direct3D12/D3D12Core.cpp | 20 ++ Engine/Graphics/Direct3D12/D3D12Core.h | 6 + Engine/Graphics/Direct3D12/D3D12Interface.cpp | 14 ++ Engine/Graphics/Direct3D12/D3D12Interface.h | 9 + Engine/Graphics/GraphicsPlatformInterface.h | 11 + Engine/Graphics/Renderer.cpp | 38 +++ Engine/Graphics/Renderer.h | 28 +++ EngineTest/TestRenderer.cpp | 111 +++++++++ EngineTest/TestRenderer.h | 15 ++ .../2026-03/20260326-d3d12-foundation.md | 101 ++++++++ .../2026-03/20260326-dx12-initial.md | 116 +++++++++ docs/changelogs/README.md | 24 ++ docs/wiki/D3D12学习Wiki.md | 230 ++++++++++++++++++ docs/架构分析/Graphics渲染架构分析.md | 182 ++++++++++++++ 18 files changed, 937 insertions(+), 2 deletions(-) create mode 100644 Engine/Graphics/Direct3D12/D3D12CommonHeader.h create mode 100644 Engine/Graphics/Direct3D12/D3D12Core.cpp create mode 100644 Engine/Graphics/Direct3D12/D3D12Core.h create mode 100644 Engine/Graphics/Direct3D12/D3D12Interface.cpp create mode 100644 Engine/Graphics/Direct3D12/D3D12Interface.h create mode 100644 Engine/Graphics/GraphicsPlatformInterface.h create mode 100644 Engine/Graphics/Renderer.cpp create mode 100644 Engine/Graphics/Renderer.h create mode 100644 EngineTest/TestRenderer.cpp create mode 100644 EngineTest/TestRenderer.h create mode 100644 docs/changelogs/2026-03/20260326-d3d12-foundation.md create mode 100644 docs/changelogs/2026-03/20260326-dx12-initial.md create mode 100644 docs/changelogs/README.md create mode 100644 docs/wiki/D3D12学习Wiki.md create mode 100644 docs/架构分析/Graphics渲染架构分析.md diff --git a/.gitignore b/.gitignore index 2702aac..45be88c 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,4 @@ *.db *.db-shm *.db-wal -Engine/Graphics_Beta/ +Graphics_Beta/ diff --git a/Engine/Engine.vcxproj b/Engine/Engine.vcxproj index fb3374d..51c5ef2 100644 --- a/Engine/Engine.vcxproj +++ b/Engine/Engine.vcxproj @@ -33,6 +33,10 @@ + + + + @@ -53,6 +57,8 @@ + + @@ -224,4 +230,4 @@ - + \ No newline at end of file diff --git a/Engine/Engine.vcxproj.filters b/Engine/Engine.vcxproj.filters index b5b1e52..0e34e77 100644 --- a/Engine/Engine.vcxproj.filters +++ b/Engine/Engine.vcxproj.filters @@ -25,6 +25,10 @@ + + + + @@ -37,5 +41,8 @@ + + + \ No newline at end of file diff --git a/Engine/Graphics/Direct3D12/D3D12CommonHeader.h b/Engine/Graphics/Direct3D12/D3D12CommonHeader.h new file mode 100644 index 0000000..56c03c0 --- /dev/null +++ b/Engine/Graphics/Direct3D12/D3D12CommonHeader.h @@ -0,0 +1,17 @@ +#pragma once + +#include "CommonHeader.h" +#include "Graphics\Renderer.h" + +// 引入 DirectX Graphics Infrastructure(DXGI)6.0 +// 头文件,用于访问 DXGI 接口(如 IDXGIFactory6、 +// IDXGIAdapter4 等),支持枚举 GPU、查询显示模式、管理 +// 交换链等底层图形功能 +#include +// 引入 Direct3D 12 头文件,提供 D3D12 API 接口, +// 用于创建渲染管线、管理资源与 GPU 命令 +#include + +// 引入 Windows Runtime C++ 模板库(WRL)头文件,提供智能指针(如 Microsoft::WRL::ComPtr) +// 用于简化 COM 对象的生命周期管理 +#include \ No newline at end of file diff --git a/Engine/Graphics/Direct3D12/D3D12Core.cpp b/Engine/Graphics/Direct3D12/D3D12Core.cpp new file mode 100644 index 0000000..14c275c --- /dev/null +++ b/Engine/Graphics/Direct3D12/D3D12Core.cpp @@ -0,0 +1,20 @@ +#include "D3D12Core.h" +#include "D3D12CommonHeader.h" + +namespace XEngine::graphics::d3d12::core{ +namespace{ + +ID3D12Device8* main_device; + +}// anonymous namespace +bool +initialize() +{ + // determine which adapter + return true; +} +void +shutdown() +{ +} +}// namespace XEngine::graphics::d3d12::core diff --git a/Engine/Graphics/Direct3D12/D3D12Core.h b/Engine/Graphics/Direct3D12/D3D12Core.h new file mode 100644 index 0000000..dd0f32e --- /dev/null +++ b/Engine/Graphics/Direct3D12/D3D12Core.h @@ -0,0 +1,6 @@ +#pragma once + +namespace XEngine::graphics::d3d12::core{ +bool initialize(); +void shutdown(); +}// namespace XEngine::graphics::d3d12 \ No newline at end of file diff --git a/Engine/Graphics/Direct3D12/D3D12Interface.cpp b/Engine/Graphics/Direct3D12/D3D12Interface.cpp new file mode 100644 index 0000000..1696edf --- /dev/null +++ b/Engine/Graphics/Direct3D12/D3D12Interface.cpp @@ -0,0 +1,14 @@ +#include "D3D12Interface.h" +#include "D3D12Core.h" +#include "Graphics\GraphicsPlatformInterface.h" + +namespace XEngine::graphics::d3d12{ +void get_platform_interface(platform_interface& pi) +{ + pi.initialize = core::initialize; + pi.shutdown = core::shutdown; +} +}// namespace XEngine::graphics::d3d12 + + + diff --git a/Engine/Graphics/Direct3D12/D3D12Interface.h b/Engine/Graphics/Direct3D12/D3D12Interface.h new file mode 100644 index 0000000..6f8b5f7 --- /dev/null +++ b/Engine/Graphics/Direct3D12/D3D12Interface.h @@ -0,0 +1,9 @@ +#pragma once + +namespace XEngine::graphics{ +struct platform_interface; +} + +namespace XEngine::graphics::d3d12{ +void get_platform_interface(platform_interface& gfx); +}// namespace XEngine::graphics::d3d12 \ No newline at end of file diff --git a/Engine/Graphics/GraphicsPlatformInterface.h b/Engine/Graphics/GraphicsPlatformInterface.h new file mode 100644 index 0000000..18d73d8 --- /dev/null +++ b/Engine/Graphics/GraphicsPlatformInterface.h @@ -0,0 +1,11 @@ +#pragma once +#include "CommonHeader.h" +#include "Renderer.h" + +namespace XEngine::graphics{ +struct platform_interface{ + bool(*initialize)(void); + void(*shutdown)(void); +}; +}// namespace XEngine::graphics + diff --git a/Engine/Graphics/Renderer.cpp b/Engine/Graphics/Renderer.cpp new file mode 100644 index 0000000..49dfe96 --- /dev/null +++ b/Engine/Graphics/Renderer.cpp @@ -0,0 +1,38 @@ +#include "Renderer.h" +#include "GraphicsPlatformInterface.h" +#include "Direct3D12/D3D12Interface.h" + +namespace XEngine::graphics { +namespace { +platform_interface gfx{}; +bool +set_platform_interface(graphics_platform platform) +{ + switch (platform) + { + case graphics_platform::direct3d12: + d3d12::get_platform_interface(gfx); + break; + case graphics_platform::vulkan: + //vulkan::get_platform_interface(gfx); + break; + case graphics_platform::opengl: + //opengl::get_platform_interface(gfx); + break; + default: + return false; + } + return gfx.initialize(); +} +}// anonymous namespace + +bool initialize(graphics_platform platform) +{ + return set_platform_interface(platform); +} + +void shutdown() +{ + gfx.shutdown(); +} +}// namespace XEngine::graphics diff --git a/Engine/Graphics/Renderer.h b/Engine/Graphics/Renderer.h new file mode 100644 index 0000000..83f1d57 --- /dev/null +++ b/Engine/Graphics/Renderer.h @@ -0,0 +1,28 @@ +#pragma once +#include "CommonHeader.h" +#include "..\Platform\Window.h" + + +namespace XEngine::graphics { + +class surface +{ +}; + +struct render_surface +{ + platform::window window{}; + surface surface{}; +}; + +enum class graphics_platform : u32 +{ + direct3d12 = 0, + vulkan = 1, + opengl = 2, +}; + +bool initialize(graphics_platform platform); +void shutdown(); + +} \ No newline at end of file diff --git a/EngineTest/TestRenderer.cpp b/EngineTest/TestRenderer.cpp new file mode 100644 index 0000000..a859d1a --- /dev/null +++ b/EngineTest/TestRenderer.cpp @@ -0,0 +1,111 @@ +/** + * @file TestRenderer.cpp + * @brief 渲染功能综合测试实现。 + */ + +#include "TestRenderer.h" +#include "Graphics/Renderer.h" +#include "Platform/Platform.h" +#include "Platform/PlatformTypes.h" +#include +#include + + +#if TEST_RENDERER +using namespace XEngine; + +graphics::render_surface _surfaces[4]; + +LRESULT win_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + bool toggle_fullscreen{ false }; + switch (msg) + { + case WM_DESTROY: + { + bool all_closed{ true }; + for (u32 i{ 0 }; i < _countof(_surfaces); ++i) + { + if(!_surfaces[i].window.is_closed()) + { + all_closed = false; + } + } + if (all_closed) + { + PostQuitMessage(0); + return 0; + } + break; + } + case WM_SYSCHAR: + { + + if(wparam == VK_RETURN && (HIWORD(lparam) & KF_ALTDOWN)) + { + platform::window win{ platform::window_id{(id::id_type)GetWindowLongPtr(hwnd, GWLP_USERDATA)} }; + win.set_fullscreen(!win.is_fullscreen()); + return 0; + } + break; + } + +} + + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +void +create_render_surface(graphics::render_surface& surface, const platform::window_init_info info) +{ + surface.window = platform::create_window(&info); +} + +void +_destroy_render_surface(graphics::render_surface& surface) +{ + platform::remove_window(surface.window.get_id()); +} + +bool +engine_test::initialize() +{ + bool result{ graphics::initialize(graphics::graphics_platform::direct3d12) }; + if (!result) + { + return result; + } + platform::window_init_info info[] + { + {&win_proc, nullptr, L"Test Window 1", 200, 100,400,400}, + {&win_proc, nullptr, L"Test Window 2", 700, 100,400,400}, + {&win_proc, nullptr, L"Test Window 2", 700, 100,400,400}, + {&win_proc, nullptr, L"Test Window 3", 1200,100,400,400}, + }; + static_assert(_countof(info) == _countof(_surfaces)); + for (u32 i{ 0 }; i < _countof(_surfaces); ++i) + { + create_render_surface(_surfaces[i], info[i]); + } + return result; +} + +void +engine_test::run() +{ + std::this_thread::sleep_for(std::chrono::milliseconds(10)); +} + +bool +engine_test::shutdown() +{ + for (u32 i{ 0 }; i < _countof(_surfaces); ++i) + { + _destroy_render_surface(_surfaces[i]); + } + + graphics::shutdown(); + + return true; +} +#endif diff --git a/EngineTest/TestRenderer.h b/EngineTest/TestRenderer.h new file mode 100644 index 0000000..627ba39 --- /dev/null +++ b/EngineTest/TestRenderer.h @@ -0,0 +1,15 @@ +/** + * @file TestRenderer.h + * @brief 渲染测试用例类声明。 + */ +#pragma once +#include "Test.h" + + +class engine_test : public Test +{ +public : + bool initialize() override; + void run() override; + bool shutdown() override; +}; diff --git a/docs/changelogs/2026-03/20260326-d3d12-foundation.md b/docs/changelogs/2026-03/20260326-d3d12-foundation.md new file mode 100644 index 0000000..62a245f --- /dev/null +++ b/docs/changelogs/2026-03/20260326-d3d12-foundation.md @@ -0,0 +1,101 @@ +# 变更记录:D3D12 基础框架 + +**提交日期**: 2026-03-26 +**提交哈希**: `16723ba` +**变更类型**: 新增功能 + +--- + +## 变更概述 + +本次提交新增了 Graphics 渲染模块和 Direct3D12 后端框架,实现了平台抽象层设计,为后续图形渲染功能奠定基础。 + +## 新增文件 + +### Engine/Graphics/Direct3D12/ + +| 文件 | 说明 | +|------|------| +| `D3D12CommonHeader.h` | D3D12 公共头文件,引入 DXGI、D3D12、WRL 依赖 | +| `D3D12Core.h` | D3D12 核心模块头文件 | +| `D3D12Core.cpp` | D3D12 核心初始化/关闭实现(框架代码) | +| `D3D12Interface.h` | 平台接口绑定声明 | +| `D3D12Interface.cpp` | 将 D3D12 实现绑定到平台接口 | + +### Engine/Graphics/ + +| 文件 | 说明 | +|------|------| +| `GraphicsPlatformInterface.h` | 平台抽象接口定义 | +| `Renderer.h` | 统一渲染器入口声明 | +| `Renderer.cpp` | 渲染器初始化与平台选择逻辑 | + +### EngineTest/ + +| 文件 | 说明 | +|------|------| +| `TestRenderer.h` | 渲染测试类声明 | +| `TestRenderer.cpp` | 多窗口渲染测试实现 | + +### docs/ + +| 文件 | 说明 | +|------|------| +| `架构分析/Graphics渲染架构分析.md` | Graphics 模块架构分析文档 | +| `wiki/D3D12学习Wiki.md` | D3D12 学习知识汇总 | + +--- + +## 技术要点 + +### 1. 平台抽象接口 + +```cpp +struct platform_interface { + bool(*initialize)(void); + void(*shutdown)(void); +}; +``` + +通过函数指针实现运行时平台选择,支持 D3D12/Vulkan/OpenGL 多后端。 + +### 2. 渲染器入口 + +```cpp +enum class graphics_platform : u32 { + direct3d12 = 0, + vulkan = 1, + opengl = 2, +}; + +bool initialize(graphics_platform platform); +void shutdown(); +``` + +### 3. 多窗口测试 + +TestRenderer 支持创建 4 个独立渲染窗口,并实现 Alt+Enter 全屏切换。 + +--- + +## 依赖引入 + +- `` - DXGI 6.0 接口 +- `` - Direct3D 12 API +- `` - COM 智能指针 + +--- + +## 后续工作 + +- [ ] 适配器枚举与设备创建 +- [ ] 命令队列实现 +- [ ] 交换链管理 +- [ ] 描述符堆 + +--- + +## 相关文档 + +- [Graphics渲染架构分析](../架构分析/Graphics渲染架构分析.md) +- [D3D12学习Wiki](../wiki/D3D12学习Wiki.md) diff --git a/docs/changelogs/2026-03/20260326-dx12-initial.md b/docs/changelogs/2026-03/20260326-dx12-initial.md new file mode 100644 index 0000000..b581927 --- /dev/null +++ b/docs/changelogs/2026-03/20260326-dx12-initial.md @@ -0,0 +1,116 @@ +# 变更记录:DX12 初始框架 + +**提交日期**: 2026-03-26 +**提交哈希**: `60f73b5` +**变更类型**: 初始化项目 + +--- + +## 变更概述 + +本次提交是项目的初始版本,建立了完整的引擎基础框架,包括组件系统、平台抽象层、内容加载器和测试框架。 + +## 新增模块 + +### Engine/Common/ + +| 文件 | 说明 | +|------|------| +| `CommonHeader.h` | 公共头文件,定义基础类型和宏 | +| `Id.h` | 强类型 ID 系统 | +| `XEnginType.h` | 引擎类型定义 | + +### Engine/Components/ + +| 文件 | 说明 | +|------|------| +| `Entity.cpp/.h` | 实体组件实现 | +| `Script.cpp/.h` | 脚本组件实现 | +| `Transform.cpp/.h` | 变换组件实现 | + +### Engine/EngineAPI/ + +| 文件 | 说明 | +|------|------| +| `Camera.h` | 相机 API | +| `GameEntity.h` | 游戏实体 API | +| `Light.h` | 光源 API | +| `ScriptComponent.h` | 脚本组件 API | +| `TransformComponent.h` | 变换组件 API | + +### Engine/Platform/ + +| 文件 | 说明 | +|------|------| +| `Platform.h` | 平台抽象接口 | +| `PlatformTypes.h` | 平台类型定义 | +| `PlatformWin32.cpp` | Win32 平台实现 | +| `Window.cpp/.h` | 窗口管理 | + +### Engine/Content/ + +| 文件 | 说明 | +|------|------| +| `ContentLoader.cpp/.h` | 内容加载器 | +| `ContentToEngine.cpp/.h` | 内容到引擎转换 | + +### Engine/Utilities/ + +| 文件 | 说明 | +|------|------| +| `FreeList.h` | 空闲列表内存池 | +| `IOStream.h` | IO 流工具 | +| `Math.h` | 数学工具 | +| `MathTypes.h` | 数学类型 | +| `Vector.h` | 向量容器 | +| `Utilities.h` | 通用工具 | + +### ContentTools/ + +| 文件 | 说明 | +|------|------| +| `FbxImporter.cpp/.h` | FBX 模型导入 | +| `Geometry.cpp/.h` | 几何处理 | +| `MeshPrimitives.cpp/.h` | 网格图元 | + +### EngineTest/ + +| 文件 | 说明 | +|------|------| +| `Main.cpp` | 测试入口 | +| `Test.h` | 测试框架基类 | +| `TestEntityComponent.h` | 实体组件测试 | +| `ShaderComponents.cpp/.h` | 着色器组件测试 | +| `Lights.cpp` | 光源测试 | +| `RenderItem.cpp` | 渲染项测试 | + +--- + +## 核心设计 + +### 1. 强类型 ID 系统 + +```cpp +DEFINE_TYPED_ID(id_type); +``` + +通过宏生成类型安全的 ID,支持代数校验防止使用已删除对象。 + +### 2. 组件系统架构 + +- **EngineAPI 层**: 对外契约,暴露稳定接口 +- **Components 层**: 运行时实现,管理内部存储 + +### 3. 平台抽象 + +Win32 平台实现封装,上层代码通过抽象接口访问平台功能。 + +--- + +## 相关文档 + +- [Id机制分析](../架构分析/Id机制分析.md) +- [Entity组件分析](../架构分析/Entity组件分析.md) +- [Script组件分析](../架构分析/Script组件分析.md) +- [Transform组件分析](../架构分析/Transform组件分析.md) +- [项目约定规范](../架构分析/项目约定规范.md) diff --git a/docs/changelogs/README.md b/docs/changelogs/README.md new file mode 100644 index 0000000..7f6db7d --- /dev/null +++ b/docs/changelogs/README.md @@ -0,0 +1,24 @@ +# 变更日志索引 + +本目录记录每次代码提交的详细变更文档。 + +## 目录结构 + +``` +changelogs/ +├── README.md # 本文件 - 索引 +├── 2026-03/ # 按月份组织 +│ └── xxx.md # 具体变更文档 +└── ... +``` + +## 变更记录 + +| 日期 | 提交 | 变更内容 | +|------|------|----------| +| 2026-03-26 | [Graphics模块](./2026-03/20260326-d3d12-foundation.md) | Graphics 模块与 D3D12 后端框架 | +| 2026-03-19 | [DX12初始框架](./2026-03/20260326-dx12-initial.md) | 初始 DX12 基础框架 | + +--- + +> 每次提交变更后,请在对应月份目录下创建独立的变更文档。 diff --git a/docs/wiki/D3D12学习Wiki.md b/docs/wiki/D3D12学习Wiki.md new file mode 100644 index 0000000..a3d9b40 --- /dev/null +++ b/docs/wiki/D3D12学习Wiki.md @@ -0,0 +1,230 @@ +# Direct3D 12 学习 Wiki + +## 概述 + +本文档是项目中 Direct3D 12 学习的基础知识汇总,帮助理解 D3D12 的核心概念和项目中的实现方式。 + +## 1. D3D12 核心概念 + +### 1.1 什么是 Direct3D 12? + +Direct3D 12 是微软推出的底层图形 API,相比 D3D11,它提供了: + +- **更底层的硬件控制**:开发者可以更精细地控制 GPU +- **更低的 CPU 开销**:减少驱动程序的 CPU 时间 +- **更好的多线程支持**:支持多线程命令录制 +- **显式的资源管理**:开发者完全控制资源生命周期 + +### 1.2 核心组件 + +| 组件 | 说明 | +|------|------| +| **Device(设备)** | 代表物理 GPU 的逻辑抽象,用于创建所有 D3D12 对象 | +| **Command Queue(命令队列)** | GPU 执行命令的队列 | +| **Command List(命令列表)** | 记录 GPU 命令的容器 | +| **Swap Chain(交换链)** | 管理后台缓冲区和前台显示 | +| **Descriptor Heap(描述符堆)** | 存储资源描述符(视图)的内存池 | +| **Root Signature(根签名)** | 定义着色器如何访问资源 | + +## 2. DXGI(DirectX Graphics Infrastructure) + +### 2.1 DXGI 的作用 + +DXGI 是 DirectX 与图形硬件之间的抽象层,负责: + +- 枚举显示适配器 +- 管理显示输出 +- 创建交换链 +- 处理全屏/窗口切换 + +### 2.2 关键接口 + +```cpp +IDXGIFactory6 // DXGI 工厂,创建其他 DXGI 对象 +IDXGIAdapter4 // 代表物理 GPU 适配器 +IDXGIOutput // 代表显示器输出 +IDXGISwapChain // 交换链接口 +``` + +### 2.3 项目中的使用 + +在 [D3D12CommonHeader.h](file:///d:/AllWX/AllC/FeatureExtractDemo/Engine/Graphics/Direct3D12/D3D12CommonHeader.h) 中引入了 `dxgi_6.h`: + +```cpp +#include // DXGI 6.0,支持枚举 GPU、查询显示模式 +``` + +## 3. D3D12 初始化流程 + +### 3.1 标准初始化步骤 + +``` +1. 创建 DXGI Factory + ↓ +2. 枚举并选择适配器(GPU) + ↓ +3. 创建 D3D12 Device + ↓ +4. 创建命令队列 + ↓ +5. 创建交换链 + ↓ +6. 创建描述符堆 + ↓ +7. 创建命令分配器和命令列表 + ↓ +8. 创建同步对象(Fence) +``` + +### 3.2 项目当前状态 + +[D3D12Core.cpp](file:///d:/AllWX/AllC/FeatureExtractDemo/Engine/Graphics/Direct3D12/D3D12Core.cpp) 目前是框架代码: + +```cpp +namespace { + ID3D12Device8* main_device; // 已声明主设备 +} + +bool initialize() { + // TODO: 实现适配器选择和设备创建 + return true; +} +``` + +## 4. COM 对象管理 + +### 4.1 什么是 COM? + +COM(Component Object Model)是微软的组件对象模型,D3D12 对象都是 COM 对象。 + +### 4.2 智能指针 + +项目使用 WRL 库的 `ComPtr` 管理 COM 对象生命周期: + +```cpp +#include // 提供 Microsoft::WRL::ComPtr + +// 使用示例 +Microsoft::WRL::ComPtr device; +``` + +### 4.3 ComPtr 的优势 + +- **自动引用计数**:无需手动 AddRef/Release +- **异常安全**:即使发生异常也能正确释放 +- **代码简洁**:减少内存管理代码 + +## 5. 平台抽象设计 + +### 5.1 设计理念 + +项目采用**平台抽象层**设计,将图形 API 的差异封装在统一接口后: + +``` +┌────────────────────────────────────┐ +│ 上层渲染代码 │ +│ graphics::initialize(platform) │ +└──────────────┬─────────────────────┘ + │ + ▼ +┌────────────────────────────────────┐ +│ platform_interface │ +│ - initialize() │ +│ - shutdown() │ +└──────────────┬─────────────────────┘ + │ + ┌──────────┼──────────┐ + ▼ ▼ ▼ +┌───────┐ ┌───────┐ ┌───────┐ +│ D3D12 │ │Vulkan │ │OpenGL │ +└───────┘ └───────┘ └───────┘ +``` + +### 5.2 接口绑定机制 + +```cpp +// D3D12Interface.cpp +void get_platform_interface(platform_interface& pi) { + pi.initialize = core::initialize; + pi.shutdown = core::shutdown; +} +``` + +这种设计允许: +- 编译时或运行时切换图形后端 +- 各后端独立开发和测试 +- 上层代码与具体 API 解耦 + +## 6. 渲染表面与窗口 + +### 6.1 render_surface 结构 + +```cpp +struct render_surface { + platform::window window{}; // 平台窗口 + surface surface{}; // 渲染表面 +}; +``` + +### 6.2 多窗口支持 + +TestRenderer 测试展示了多窗口渲染: + +```cpp +graphics::render_surface _surfaces[4]; // 支持 4 个窗口 + +// 创建多个渲染表面 +for (u32 i{0}; i < _countof(_surfaces); ++i) { + create_render_surface(_surfaces[i], info[i]); +} +``` + +### 6.3 全屏切换 + +通过 `WM_SYSCHAR` 消息处理 Alt+Enter: + +```cpp +if (wparam == VK_RETURN && (HIWORD(lparam) & KF_ALTDOWN)) { + win.set_fullscreen(!win.is_fullscreen()); +} +``` + +## 7. 后续学习路径 + +### 7.1 基础阶段 + +- [ ] 完成设备创建和适配器枚举 +- [ ] 创建命令队列和命令列表 +- [ ] 实现交换链和后台缓冲区 +- [ ] 渲染第一个三角形 + +### 7.2 进阶阶段 + +- [ ] 描述符堆管理 +- [ ] 根签名和管线状态对象 +- [ ] 资源屏障和同步 +- [ ] 常量缓冲区和着色器资源 + +### 7.3 高级阶段 + +- [ ] 多线程渲染 +- [ ] 资源绑定策略 +- [ ] 动态资源管理 +- [ ] 性能优化 + +## 8. 参考资源 + +### 8.1 官方文档 + +- [Microsoft D3D12 文档](https://docs.microsoft.com/en-us/windows/win32/direct3d12/direct3d-12-graphics) +- [DXGI 文档](https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/dx-graphics-dxgi) + +### 8.2 推荐书籍 + +- 《Introduction to 3D Game Programming with DirectX 12》 +- 《Real-Time 3D Rendering with DirectX and HLSL》 + +### 8.3 项目相关文档 + +- [Graphics渲染架构分析](./Graphics渲染架构分析.md) +- [项目约定规范](./项目约定规范.md) diff --git a/docs/架构分析/Graphics渲染架构分析.md b/docs/架构分析/Graphics渲染架构分析.md new file mode 100644 index 0000000..0c03d4d --- /dev/null +++ b/docs/架构分析/Graphics渲染架构分析.md @@ -0,0 +1,182 @@ +# Graphics 渲染架构分析 + +## 1. 模块概述 + +Graphics 模块是引擎的图形渲染核心,采用**平台抽象层设计**,支持多图形后端(Direct3D12、Vulkan、OpenGL)的统一接口调用。 + +## 2. 目录结构 + +``` +Engine/Graphics/ +├── Direct3D12/ # D3D12 后端实现 +│ ├── D3D12CommonHeader.h # D3D12 公共头文件 +│ ├── D3D12Core.h/.cpp # D3D12 核心初始化/关闭 +│ └── D3D12Interface.h/.cpp # 平台接口绑定 +├── GraphicsPlatformInterface.h # 平台接口抽象定义 +└── Renderer.h/.cpp # 统一渲染器入口 +``` + +## 3. 核心设计模式 + +### 3.1 平台抽象接口 + +[GraphicsPlatformInterface.h](file:///d:/AllWX/AllC/FeatureExtractDemo/Engine/Graphics/GraphicsPlatformInterface.h) 定义了平台无关的接口结构: + +```cpp +struct platform_interface { + bool(*initialize)(void); + void(*shutdown)(void); +}; +``` + +这种设计允许: +- 运行时选择图形后端 +- 各平台独立实现,互不干扰 +- 上层代码无需关心底层 API 细节 + +### 3.2 渲染器入口 + +[Renderer.h](file:///d:/AllWX/AllC/FeatureExtractDemo/Engine/Graphics/Renderer.h) 提供统一的渲染器入口: + +```cpp +enum class graphics_platform : u32 { + direct3d12 = 0, + vulkan = 1, + opengl = 2, +}; + +bool initialize(graphics_platform platform); +void shutdown(); +``` + +### 3.3 平台接口绑定流程 + +[Renderer.cpp](file:///d:/AllWX/AllC/FeatureExtractDemo/Engine/Graphics/Renderer.cpp) 实现平台选择逻辑: + +``` +用户调用 graphics::initialize(direct3d12) + ↓ +set_platform_interface() 根据枚举选择平台 + ↓ +调用 d3d12::get_platform_interface(gfx) + ↓ +绑定 gfx.initialize/shutdown 到 D3D12 实现 + ↓ +执行实际初始化 +``` + +## 4. Direct3D12 后端实现 + +### 4.1 公共头文件 + +[D3D12CommonHeader.h](file:///d:/AllWX/AllC/FeatureExtractDemo/Engine/Graphics/Direct3D12/D3D12CommonHeader.h) 引入必要的 D3D12 依赖: + +| 头文件 | 用途 | +|--------|------| +| `` | DXGI 6.0 接口,枚举 GPU、管理交换链 | +| `` | Direct3D 12 API 核心 | +| `` | COM 智能指针(ComPtr) | + +### 4.2 核心模块 + +[D3D12Core.cpp](file:///d:/AllWX/AllC/FeatureExtractDemo/Engine/Graphics/Direct3D12/D3D12Core.cpp) 管理 D3D12 设备: + +```cpp +namespace { + ID3D12Device8* main_device; // 主设备指针 +} + +bool initialize() { + // TODO: 确定适配器并创建设备 + return true; +} + +void shutdown() { + // TODO: 释放设备资源 +} +``` + +### 4.3 接口绑定 + +[D3D12Interface.cpp](file:///d:/AllWX/AllC/FeatureExtractDemo/Engine/Graphics/Direct3D12/D3D12Interface.cpp) 将 D3D12 实现绑定到平台接口: + +```cpp +void get_platform_interface(platform_interface& pi) { + pi.initialize = core::initialize; + pi.shutdown = core::shutdown; +} +``` + +## 5. 渲染表面(Render Surface) + +### 5.1 数据结构 + +```cpp +class surface {}; // 渲染表面抽象 + +struct render_surface { + platform::window window{}; // 关联窗口 + surface surface{}; // 渲染表面 +}; +``` + +### 5.2 多窗口支持 + +TestRenderer 测试展示了多窗口渲染场景: +- 支持 4 个独立渲染表面 +- 每个表面关联独立的平台窗口 +- 全屏切换支持(Alt+Enter) + +## 6. 与其他模块的关系 + +``` +┌─────────────────────────────────────────────────┐ +│ EngineTest │ +│ (TestRenderer 测试) │ +└─────────────────────┬───────────────────────────┘ + │ 调用 + ▼ +┌─────────────────────────────────────────────────┐ +│ Graphics/Renderer │ +│ (统一渲染器入口 + 平台选择) │ +└─────────────────────┬───────────────────────────┘ + │ 分发 + ┌─────────────┼─────────────┐ + ▼ ▼ ▼ + ┌─────────┐ ┌─────────┐ ┌─────────┐ + │ D3D12 │ │ Vulkan │ │ OpenGL │ + │ Backend │ │ Backend │ │ Backend │ + └─────────┘ └─────────┘ └─────────┘ + │ + ▼ +┌─────────────────────────────────────────────────┐ +│ Platform/Window │ +│ (窗口管理 + 平台抽象) │ +└─────────────────────────────────────────────────┘ +``` + +## 7. 扩展指南 + +### 7.1 添加新图形后端 + +1. 创建 `Engine/Graphics/Vulkan/` 或 `Engine/Graphics/OpenGL/` 目录 +2. 实现 `XxxCore.h/.cpp`(初始化/关闭逻辑) +3. 实现 `XxxInterface.cpp`(`get_platform_interface` 函数) +4. 在 `Renderer.cpp` 的 `set_platform_interface` 中添加分支 + +### 7.2 D3D12 后续开发重点 + +- 适配器枚举与选择 +- 命令队列创建 +- 交换链管理 +- 描述符堆管理 +- 资源创建与管理 +- 渲染管线状态对象(PSO) +- 根签名(Root Signature) + +## 8. 设计优势 + +1. **平台无关性**:上层代码无需关心底层图形 API +2. **可扩展性**:易于添加新的图形后端 +3. **模块化**:各平台实现完全隔离 +4. **测试友好**:可通过 TestRenderer 进行独立测试