运行电脑样本
可以从 GitHub 下载 Microsoft 游戏开发工具包 (GDK) 的示例。 Microsoft 游戏开发工具包 (GDK) 安装中不包括这些示例。
这些样本的组织结构如下。
- Kits:样本使用的共享实用工具代码
- Media:样本使用的各种共享资产
- GDKSamples:
- Audio:与 XAudio2、WASAPI 等相关的样本
- IntroGraphics:介绍性 DirectX 12 样本
- Live:Xbox 服务示例
- Graphics:DirectX 12.X 样本
- System:与输入、IO、内存等相关的样本
- Tools:用于处理 Microsoft 游戏开发工具包 (GDK) 的各种样本工具
注意
某些样本仅适用于 Xbox 主机。
生成示例
有关详细信息,请参阅每个特定样本的 Readme.docx。
- 安装所需的开发工具:
Visual Studio 2019 或 Visual Studio 2022、Windows 10 SDK 和 Microsoft 游戏开发工具包 (GDK) 。 - 打开 Visual Studio。
- 选择“文件”>“打开”>“项目/解决方案”。。 导航到样本(例如 GDKSamples\IntroGraphics\SimpleTriangleDesktop)。 选择“SimpleTriangleDesktop”。
- 选择 F5 生成、部署和调试。
由于示例使用 DirectX 12,它们需要 Windows 10 或 Windows 11、视频卡以及支持 DirectX 12 的视频驱动程序。
在这些样本的调试配置版本中,如果 DirectX 12 设备不可用,则样本将改为尝试使用 WARP12 软件设备。 在调试输出窗口中,这种情况记录为“Direct3D Adapter - WARP12”。 在 Windows 10 系统上启用可选功能“图形工具”,可安装 WARP12(和 Direct3D 12 调试设备)。 有关详细信息,请参阅 Visual Studio 2015 和 Windows 10 图形工具博客文章。
由于 WARP12 仅在开发人员系统上可用,因此,如果找不到可运行 DirectX 12 的硬件,则发布配置版本不会尝试使用软件设备,而会失败。
Visual Studio 备注
默认情况下,示例设置为使用 Visual Studio 2019 平台工具集 v142
。 使用 Visual Studio 2022 时,可以使用 设置生成示例 v142
,或者将示例重定向到 v143
。
建议在安装 Visual Studio 2022 时,包括 MSVC v142 - VS 2019 C++ x64/x86 生成工具可选组件 (Microsoft.VisualStudio.ComponentGroup.VC.Tools.142.x86.x64
)。
样本一览
大多数样本使用相同的基本结构,并且包含以下文件。
samplename.cpp
和samplename.h
(名称与示例匹配)包含核心示例功能,可以从这里开始查看源代码。Main.cpp
包含入口点、窗口创建和主消息循环。DeviceResources.cpp
和DeviceResources.h
包含 Direct3D 12 设备和交换链的抽象。 有关详细信息,请参阅 GitHub 上的 DeviceResources。 要更加详细地了解如何创建设备和交换链,请参阅 IntroGraphics 样本 SimpleDeviceAndSwapChain。StepTimer.h
包含可变和固定步骤游戏计时的简单抽象。 有关更多信息,请参阅 GitHub 上的StepTimer。pch.h
和pch.cpp
实现示例的预编译头文件和全局#include
语句。Assets 文件夹包含本地媒体,其中包括用于打包的启动屏幕和徽标。 示例还包括 MicrosoftGameConfig.mgc 文件。
注意
GDK 模板使用相同的结构,但使用 Game.cpp
和 Game.h
,而不是 samplename.cpp
和 samplename.h
。 主类称为 Game
,而不是 Sample
。
构造函数
样本的核心功能在 Sample
类中实现。 构造函数最基本的实现只是创建 DeviceResources
实例,如下所示。
Sample::Sample() noexcept(false) :
m_frame(0)
{
m_deviceResources = std::make_unique<DX::DeviceResources>();
}
DeviceResources
构造函数具有一些可选默认参数,以控制呈现目标的格式、深度模具格式(如果不需要深度模具缓冲区则可以设置为 DXGI_UNKNOWN
)、返回缓冲区计数(2 或 3),以及可选功能标志。 有关详细信息,请参阅 GitHub 上的 DeviceResources。
初始化
首次启动样本时,执行操作会传递到 Sample::Initialize
方法,该方法会处理到演示窗口,它会初始化 Direct3D 设备、资源和其他资产,如下所示。
// Initialize the Direct3D resources that are required to run.
void Sample::Initialize(HWND window)
{
m_deviceResources->SetWindow(window);
m_deviceResources->CreateDeviceResources();
CreateDeviceDependentResources();
m_deviceResources->CreateWindowSizeDependentResources();
CreateWindowSizeDependentResources();
}
Sample::CreateDeviceDependentResources
帮助程序创建需要 Direct3D 12 设备的资源,但 Sample::CreateWindowSizeDependentResources
创建需要某台设备并且依赖于演示窗口大小的资源。
更新
Sample::Update
方法处理输入和状态修改,以及基于时间的动画和模拟。 通常,每帧调用一次该方法,尽管 StepTimer
也可以使用固定时间更新,每帧可以更新 0 次或多次,如下所示。
void Sample::Update(DX::StepTimer const&)
{
auto pad = m_gamePad->GetState(0);
if (pad.IsConnected())
{
if (pad.IsViewPressed())
{
ExitSample();
}
}
}
多数样本使用游戏板、键盘和鼠标的 DirectX 工具包输入抽象。
由于音频样本通常处理从 Tick
直接调用的音频呈现,所以这些样本会每帧处理一次而不会将其放入 Update
。
呈现
Sample::Render
方法用于呈现场景的单个帧。 调用 DeviceResources::Present
方法以提交主要命令列表并显示呈现的帧时即告结束,如下所示。
void Sample::Render()
{
// Don't try to render anything before the first Update.
if (m_timer.GetFrameCount() == 0)
{
return;
}
// Prepare the command list to render a new frame.
m_deviceResources->Prepare();
Clear();
auto commandList = m_deviceResources->GetCommandList();
...
// Show the new frame.
m_deviceResources->Present();
m_graphicsMemory->Commit(m_deviceResources->GetCommandQueue());
}
DeviceResources::Prepare
方法用于准备主要命令列表。
Sample::Clear
方法用于设置呈现目标并将其设置为背景颜色,同时设置初始呈现视区和剪式矩形。
因为大多数样本使用 DirectX 工具包,所以必须在每帧结束后调用 GraphicsMemory::Commit
方法,以便跟踪动态 GPU 内存使用情况的生命周期。 有关详细信息,请参阅 GitHub 上的 GraphicsMemory。
事件
进程周期管理 (PLM) 通过 Sample::OnSuspending
和 Sample::OnResuming
方法处理。 对于 Xbox 样本,这通常只需调用所需的 GPU 暂停和恢复方法并重置 StepTimer
。
桌面样本具有与通过 Sample::OnWindowMoved
和 Sample::OnWindowSizeChanged
更改窗口大小相关的消息。 Xbox 示例使用固定演示大小,所以它们没有这些方法。
桌面示例还具有处理以通过 Sample::OnDeviceLost
和 Sample::OnDeviceRestored
应对设备丢失 情形。 当 Present
遇到 DXGI_ERROR_DEVICE_REMOVED
或 DXGI_ERROR_DEVICE_RESET
时即触发这些方法。 Xbox 上不会发生设备丢失,因此这些样本中不需要这种处理。
智能指针
样本使用 Microsoft::WRL::ComPtr
智能指针简化 Direct3D 和其他 Nano-COM 对象的生命周期管理。 有关此智能指针的详细信息,请参阅 GitHub 上的 ComPtr。
错误处理
许多 Direct3D 功能和其他 nano-COM API 都返回 HRESULT
错误代码。 为了获得可靠性和更轻松的调试,请始终检查返回 HRESULT
的每个函数的结果。 如果可以肯定特定函数不存在任何错误状况,那么该函数本身将返回 void
而不是 HRESULT
。
要检测和处理运行时无法处理的快速致命错误,样本可以在 DX
命名空间中使用简单的帮助程序函数 ThrowIfFailed
,如下所示。 有关此帮助器的详细信息,请参阅 GitHub 上的 ThrowIfFailed。
DX::ThrowIfFailed(D3D12SerializeRootSignature(...));
建议对所有 x64 本机开发使用 C++ 异常处理 /EHsc
,因为它对代码生成或性能几乎没有或完全没有影响。 在运行时引发 C++ 异常不是性能方案,因此我们不使用它们来控制流向。 有关使用与 C++ 异常相关的 Visual Studio 调试程序设置的详细信息,请参阅使用 Visual Studio 中的调试器管理异常。
工具包
样本使用的主要实用工具代码是 GitHub 上提供的用于 DX12 的 DirectX 工具包。 一些样本使用 DirectXTex(同样可以在 GitHub 上找到它)。 相关文档,请参阅相应项目 wiki。 DirectX 工具包和 DirectXTex 中的 Microsoft 游戏开发工具包 (GDK) 支持受 MIT 许可证的约束,是核心项目的一部分。
样本还使用 ATG 工具包中的源代码,该工具包位于 ATGTK 文件夹中。 此源代码是 MIT 许可代码(在各个头文件中标明),只能在样本中使用。