Skip to main content

面向 XBOX One 的 Microsoft 游戏开发工具包移植指南

本主题概述了将现有代码库移植到面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 平台的相关技术。对于已经进行 XBOX One 开发的开发者,大多数子系统会比较熟悉,只不过采用了不同的 API 设计。像 Direct3D 图形这样的部分基本没有变化。本主题提供整体移植过程的高层概述、指向具体章节的链接,以及一些避免常见陷阱的技巧和窍门。 对本指南有反馈?欢迎在 Microsoft 游戏开发工具包 (GDK) 开发者论坛 与我们分享。 如果你是在 Microsoft 游戏开发工具包 (GDK) 平台上开发新游戏而不是移植现有游戏,请参阅“使用 GDK 开发新游戏”。

关于 Microsoft 游戏开发工具包 (GDK)

作为我们的游戏开发合作伙伴,你们向 Microsoft Gaming 团队提供了宝贵的反馈,告诉我们哪些做得好、哪些需要改进。我们对 Microsoft 游戏开发工具包 (GDK) 的主要目标是直接回应你们的反馈,并确保你们能够:
  • 完全按照当前的方式继续开发游戏
  • 尽可能多地在 Microsoft 所有游戏项目和计划之间共享代码:今天的主机与 PC,以及未来的主机与 XBOX Game Streaming
  • 信赖我们的开发工具与平台,提供快速、可靠且以开发者为中心的环境
  • 尽快、尽简单地利用新的多平台服务与体验
我们希望帮助你在你想要的平台上、用你已经使用的编程范式开发你的游戏。我们希望帮助你把游戏带到现存的所有游戏平台以及我们正在打造、将来会让明日玩家愉悦的所有平台。 有关 Microsoft 游戏开发工具包 (GDK) 的更多信息,请参阅“什么是 Microsoft 游戏开发工具包?”和“Microsoft 游戏开发工具包 (GDK) 入门”。

目录

为便于本移植指南的说明,我们假定你面向 Gaming.Xbox.XboxOne.x64 和/或 Gaming.Xbox.Scarlett.x64 平台。Microsoft 游戏开发工具包 (GDK) 还包含 Gaming.Desktop.x64 平台。它是标准 x64 Win32 平台的一个变体,本移植指南不涉及。Gaming.Desktop.x64 的主要价值在于:在面向 PC 时,其构建设置、Visual Studio 集成、松散布局行为等方面提供与 Gaming.Xbox.*.x64 类似的体验。或者,你也可以使用“原生”的 x64 平台,并直接为 PC 实现所有设置/打包。

规划移植项目

将现有代码库移植到 Microsoft 游戏开发工具包 (GDK) 时,你通常会从现有的 XBOX One Software Development Kit 项目或经典 Win32 桌面应用程序开始。对许多拥有现有 XBOX One 游戏的开发者而言,只要对 Windows Runtime API 的使用相对隔离,从他们的 Durango 代码库开始通常是更好的选择。经典 Win32 桌面代码库与 Microsoft 游戏开发工具包 (GDK) 编程模型的差距更小,但通常带有需要为主机改造的桌面式 UI 和控制方案。经典 Win32 桌面代码库还往往包含大量桌面式集成,特别是当其作为使用了主机 GDK 不支持的 API 集的游戏编辑工具套件的一部分时。两种起点各有利弊。在某些情况下,你可能会发现从两种类型分别抽取代码库的不同部分更容易。

从 XBOX One Software Development Kit 移植

如果你的代码库已经通过 XBOX One Software Development Kit(也称为 Durango 平台)支持 XBOX One,那么应用程序 API 使用的现代化工作已经完成了大部分。代码也应已针对主机的具体约束做了良好优化,并且很可能大量使用了 XBOX One 特定的扩展。
  • 需要使用 DirectX 12.X。如果你已经在 XBOX One 游戏中使用 DirectX 12.X,除了 Direct3D 使用中的呈现 API,无需其他更改。
如果你现在使用的是 DirectX 11.X,先升级到 DirectX 12.X。这在移动到 Microsoft 游戏开发工具包 (GDK) 之前,用现有的 XBOX One Software Development Kit 构建可能更容易做。详细信息请参阅:从 Direct3D 11 移植到 Direct3D 12 和 Introduction to Direct3D 12 on XBOX One 的 Xfest 演讲 (XBOX Developer Downloads->Conference Material->Xfest 2015 GPU Track Videos),以及 Porting from Direct3D 11 to Direct3D 12 的 Xfest 演讲 (XBOX Developer Downloads->Conference Material->Xfest 2015 GPU Track Videos)。
  • 呈现逻辑必须使用 PresentX API,而不是 DXGI swap chain。
  • Microsoft 游戏开发工具包 (GDK) 游戏 OS 对内存子系统做了若干重要变更。请重新审视你的内存管理器实现。
  • 对于控制器输入,请使用新的 GameInput API,而不是 Windows.Xbox.Input。
  • 由于绝大多数场景不再使用 Windows Runtime API,请将现有的 C++/CX 或 C++/WinRT 代码替换为新的 Win32 风格或 DirectX 风格 COM API。
  • 核心音频功能未变。但可能需要按音频 API 对比中所述做一些 API 更改。支持带 XMA 扩展的 XAudio2、WASAPI 和 ISpatialAudioClient。
  • 在 Visual Studio 中构建时,用 Gaming.Xbox.XboxOne.x64 和/或 Gaming.Xbox.Scarlett.x64 平台配置替换 Durango 平台配置,并升级到 Visual Studio 2019 或 Visual Studio 2022。
为帮助添加新的平台配置,我们提供了一个名为 SolutionUpdater 的示例。此示例工具接受一个现有的 Visual Studio Solution 文件,并自动为该解决方案所引用的所有相关项目文件创建新的平台配置,大幅加快此过程并减少人工出错的可能。详细信息请参阅示例中附带的文档。
如果你的代码库支持通用 Windows 平台 (UWP) 应用模型,其移植路径与从 XBOX One Software Development Kit 移植类似。

从经典 Win32 桌面移植

如果你的代码库只支持经典 Win32 桌面,那么移植过程可能会相当广泛,取决于代码库对已弃用 API 和其他功能的使用情况有多新。要牢记经典 Win32 桌面代码库可能横跨从 Windows 9x/ME 时代开始的非常广泛的 API。以下列表并不能覆盖你可能遇到的所有问题。面向 XBOX 时,你还会遇到从 PC 移植到主机时通常需要考虑的问题:UI、输入模型、固定分辨率显示、内存受限等等。更多信息请参阅 Coming to XBOX from PC - What You Need to Know。
  • 必须使用 x64 原生。更多信息请参阅 64-bit programming for Game Developers。
  • 必须使用 DirectX 12.X。不能使用 DirectX 11、Direct3D 10、Direct3D 9 或更早版本。此外,不支持 OpenGL 和 Vulkan。详细信息请参阅 DirectX11 与 DirectX12 移植指南。
  • 不能使用 DirectX SDK 遗留组件 D3DX9、D3DX10、D3DX11 和 XACT。更多信息请参阅 Microsoft Docs、DirectX SDK 在哪儿 (2021 Edition)?、没有 D3DX 也能活 和 Zombie DirectX SDK。
  • WINAPI_FAMILY_GAMES 是完整 Win32 API 家族的子集。请将自己限制在这些 API 之内。
  • 需要使用 AppX 打包。请更新你的打包与部署流程。
  • 对于控制器输入,请使用新的 GameInput API,而不是 Windows.Gaming.Input 或 DirectInput。
  • 对于音频,使用 XAudio2、WASAPI、ISpatialAudioClient 或兼容的音频中间件。
  • 移除对注册表的使用。
  • 应减少对 WndProc 消息的处理。许多消息,尤其是与窗口位置、大小和 shell 集成有关的消息,不适用于面向 XBOX 的 Microsoft 游戏开发工具包 (GDK)。
  • 如果你使用 Visual Studio 构建,请升级你的代码以与 Visual Studio 2019 或 Visual Studio 2022 兼容。否则,请确保你的构建使用新的预处理器定义,并链接 GXDK\gameKit\lib\amd64 中的库,例如伞形库 xgameplatform.lib。
  • 对于 COM 组件,只支持多线程 apartment (MTA) 线程模型。请注意 COINITBASE_MULTITHREADED 是 Direct3D 应用的典型设置。
  • 只支持一个窗口实例。不支持多个并发窗口实例或对话框。

开发环境

Microsoft 游戏开发工具包 (GDK) 支持的开发环境为 Visual Studio 2019 (16.11 update) 或 Visual Studio 2022。 请安装以下项:
  • 工作负载:使用 C++ 的游戏开发(核心工具集)
  • 工作负载:UWP 开发(打包工具)
  • 工作负载(可选):使用 C++ 的桌面开发(PC 端工具与示例)
使用 Visual Studio 2017 进行 XBOX One Software Development Kit 开发还需要可选组件 Windows 8.1 SDK 与 UCRT SDK。Microsoft 游戏开发工具包 (GDK) 不需要此组件。
如果你仍在使用 Visual Studio 2015 或更早版本,那么你移植工作的第一步是升级到 Visual Studio 2019 或更高版本。

Visual Studio 平台

Microsoft 游戏开发工具包 (GDK) 与 Visual Studio 集成,为面向 XBOX 上 Microsoft GDK 游戏 OS 提供 Gaming.Xbox.XboxOne.x64 与 Gaming.Xbox.Scarlett.x64 平台。它取代了 XBOX One Software Development Kit 的 Durango 平台。

自定义构建方案

对于在 Visual Studio 之外构建代码的场景,位置相关的环境助手已更改。 XBOX One Software Development Kit:
Microsoft 游戏开发工具包 (GDK):
上述示例路径中,build_number 表示已安装到你系统上的构建号(例如 190700)。
Microsoft 游戏开发工具包 (GDK) 中有几个位置需要由自定义构建系统引用。%GameDKLatest%\GXDK\gameKit 包含主机特定扩展的所有头文件和库,以及用于链接 Microsoft 游戏开发工具包 (GDK) 二进制的主平台伞形库。%GameDKLatest%\GRDK\gameKit 同样包含所有非主机专有功能的头文件和库。Microsoft 游戏开发工具包 (GDK) 需要安装 Windows 10 SDK (10.0.19041.0) 或更高版本作为依赖。%GameDKLatest%\GXDK\toolKit 中还有一些用于 PC 端主机工具的附加头文件/库。
自 October 2023 发行版起,Windows 11 SDK (10.0.22000.0) 是最低支持版本。
还有一些应使用的选项和 define。完整详细信息请参阅“Visual C++ 编译器和链接器开关建议”,以及 CMakeExample 示例。

编译器 (cl.exe)

  • /D_GAMING_XBOX 取代 /D_XBOX_ONE /D_TITLE 和 /D_DURANGO。
  • /D_GAMING_XBOX_XBOXONE 仅在 Gaming.Xbox.XboxOne.x64 平台上定义。
  • /D_GAMING_XBOX_SCARLETT 仅在 Gaming.Xbox.Scarlett.x64 平台上定义。
  • /DWINAPI_FAMILY=WINAPI_FAMILY_GAMES 用来控制 API 分区,取代 WINAPI_FAMILY_TV_TITLE API 家族。
  • 你应该定义 /DWIN32_LEAN_AND_MEAN、/D_ATL_NO_DEFAULT_LIBS 和 /D__WRL_NO_DEFAULT_LIB__。
  • 对于 Microsoft 游戏开发工具包 (GDK),你不再使用任何 Windows Runtime 开关,例如 /AI、/FU 或 /ZW。
  • 继续使用 /favor:AMD64、/EHsc 和 /fp:fast。
  • 对于 Gaming.Xbox.XboxOne.x64 平台,继续使用 /arch:AVX。
  • 对于 Gaming.Xbox.Scarlett.x64 平台,使用 /arch:AVX2。
在 VS 2019 Update 3 或更高版本上的 Gaming.Xbox.Scarlett.x64 平台,还需使用 /d2vzeroupper。如果启用了 Whole Program Optimization (WPO) / Link Time Code Generation (LTCG),则需要使用 /d2:-vzeroupper。
在 VS 2022 与 Gaming.Xbox.XboxOne.x64 平台上,还需使用 /d2vzeroupper-。如果启用了 Whole Program Optimization (WPO) / Link Time Code Generation (LTCG),则需要使用 /d2:-vzeroupper-。
  • 链接 xgameplatform.lib、xgameruntime.lib、d3d12_x.lib 或 d3d12_xs.lib、xmem.lib 和 pixevt.lib。不要使用 kernel32.lib、kernelx.lib、onecore.lib 或 WindowsApp.lib。
  • 对于 XGraphics 库,使用 xg_x.lib 或 xg_xs.lib。
  • 不需要使用 /WINMD 或 /WINMDFILE,它们用于 Windows Runtime API。
  • 面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 不使用嵌入式清单,因此请使用 /MANIFEST:NO。
  • 继续使用 /DYNAMICBASE、/NXCOMPAT。
你应考虑使用 /NODEFAULTLIB 来确保没有链接任何不受支持的 Win32 库,包括 advapi32.lib comctl32.lib comsupp.lib dbghelp.lib gdi32.lib gdiplus.lib guardcfw.lib kernel32.lib mmc.lib msimg32.lib msvcole.lib msvcoled.lib mswsock.lib ntstrsafe.lib ole2.lib ole2autd.lib ole2auto.lib ole2d.lib ole2ui.lib ole2uid.lib ole32.lib oleacc.lib oleaut32.lib oledlg.lib oledlgd.lib oldnames.lib runtimeobject.lib shell32.lib shlwapi.lib strsafe.lib urlmon.lib user32.lib userenv.lib wlmole.lib wlmoled.lib onecore.lib。

优化 Windows 头文件使用

Microsoft 游戏开发工具包 (GDK) 使用标准的 <Windows.h> 头文件。除前面提到的 WIN32_LEAN_AND_MEAN 外,定义各种精简式预处理器宏也很有用,可以控制你引入的 Win32 系统头文件的整体数量。

Visual C++ 运行时

在 XBOX One Software Development Kit 中,Visual C++ 运行时的头文件和库属于 XBOX One Software Development Kit 的一部分,而运行时 DLL 位于 Game OS 中。这就要求 XDK 发行版本或 QFE 级别与所使用的 Visual Studio 次要更新版本相匹配。 对于 Microsoft 游戏开发工具包 (GDK),Visual C++ 运行时 DLL 作为你游戏包的一部分包含在其中,与本地构建机器上安装的 Visual Studio 版本相匹配。
  • VCRuntime*.dll 和 msvcp*.dll 是 Visual C++ 编译器运行时和标准 C++ 库 DLL。Game OS 中还包含并使用一个 ucrtbase.dll。
  • 对于调试版本,你的包中将包含 VCRuntime*d.dll、msvcp*d.dll 和 ucrbased.dll。
如果你使用 ERA Migration Library,还需要 vccorlib*.dll,编译器在使用 /ZW 构建时会使用它。
AMP 不支持 XBOX,并已在最新的 Visual C++ 版本中被弃用。

应用启动

Microsoft 游戏开发工具包 (GDK) 项目使用简化的 Win32 桌面式应用启动和消息循环,而不是 Windows Runtime 风格的 CoreWindow 事件。你现有的代码库应有以下入口点之一。

Win32 桌面开发

使用 C++/CX 的 XBOX One Software Development Kit 或 UWP 应用

使用 C++/WinRT 的 XBOX One Software Development Kit 或 UWP 应用

面向 XBOX 的 Microsoft 游戏开发工具包 (GDK)

对于 GDK 游戏,入口点与 Win32 经典桌面相同。

初始化应用

典型的、最基本的 Win32 入口点函数如下所示。
对于面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 游戏,此模式基本相同,但我们可以稍作简化:
  • 最少使用窗口类和样式
  • 使用 UTF-8 而非 UTF-16LE 字符串
  • 初始化 Game Runtime 子系统
对于面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 游戏,只能有一个 Win32 窗口。

Windows 消息循环

由于许多消息不适用,面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 应用可以使用一个非常基本的 Win32 消息循环。
使用 Win32 消息循环是可选的,但如果你正从现有 Win32 代码库迁移,这是一个有用的起点。 下表列出了经典 Win32 桌面游戏中常见的 Win32 消息,以及它们在面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 游戏中的适用情况(或不适用)。

创建 Direct3D 设备

使用 Microsoft 游戏开发工具包 (GDK) 面向 XBOX 构建的游戏使用 Direct3D 12.X API,它作为整体运行时实现,与 XBOX One Software Development Kit 的实现方式一致。 使用 Microsoft 游戏开发工具包 (GDK) 面向 XBOX 构建的游戏不支持标准 Direct3D 12 和 Direct3D 11。为 DirectX 12.X 创建 Direct3D 12 设备时,请使用 D3D12XboxCreateDevice 方法。
之后,命令队列、命令列表和其他项目仍然按标准 Direct3D 12 的方式创建。 要支持 4K 渲染,只需使用更大的 swapchain 宽度和高度,但你应继续为低端主机支持 1080p。判断何时使用 4K、1440p 或 1080p 的推荐方法如下:
有关更多详细信息,请参阅 SimpleDeviceAndSwapChain 示例。

XMem* API

所有使用 XMEM_GRAPHICS 的 XMem* API 调用都要求在使用前已创建 Direct3D 设备。或者,如果你需要在 Direct3D 设备存在之前调用这些 API,可以调用 D3DConfigureVirtualMemory。

CPU/GPU 预留

所有 Microsoft 游戏开发工具包 (GDK) 游戏都获得完整资源(即没有 Kinect GPU 预留)以及第七个 CPU 核心。默认情况下你会获得与以下 XBOX One Software Development Kit 清单设置等效的资源。

XBOX One 与 XBOX Series X|S Direct3D 的差异

Gaming.Xbox.XboxOne.x64 平台的 Direct3D 12.x 整体运行时实现与 XBOX One Software Development Kit 中 Direct3D 12.x 的实现几乎相同。在初次移植到面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 时,此平台通常是最容易开始的地方。
  • Gaming.Xbox.Scarlett.x64 支持最高至 ID3D12Device8 与 ID3D12GraphicsCommandList5 接口或更新版本。
  • Gaming.Xbox.XboxOne.x64 支持最高至 ID3D12Device、ID3D12Device1、ID3D12Device2 和 ID3D12GraphicsCommandList。
移动到 Gaming.Xbox.Scarlett.x64 平台时,Direct3D 12.x 的实现还有一些额外能力和差异。
  • 你需要使用不同版本的 Direct3D 头文件和库(即 d3d12_xs.h、d3dx12_xs.h、xg_xs.h、d3d12_xs.lib 等)。同一个二进制文件中不能混用两种版本的 Direct3D 12.x。
  • 最初实现 Direct3D 12.x 整体运行时时,它是构建在 Direct3D 11.x 整体运行时之上的,因此在使用 Durango 或 Gaming.Xbox.XboxOne.x64 平台构建时会定义许多 Direct3D 11 类型。在 XBOX Series X|S 实现中这些类型已被移除,因此在任何遗留的对 d3d11_x.h 头文件、D3D11_* 定义、CD3D11_* 类或 ID3D11* 接口的引用上你可能会遇到构建问题。移除它们后,仍可以为两个平台构建。
  • ESRAM 不是 XBOX Series X|S 的特性,因此该平台未定义 ESRAM 相关扩展。这也意味着 xgmemory.h(用于利用 ESRAM 的辅助文件)只在 Gaming.Xbox.XboxOne.x64 平台上受支持。
在 XBOX One / XBOX One S 设备上,为获得最佳渲染性能,充分利用 ESRAM 仍然很重要。参见 SimpleESRAM 与 AdvancedESRAM 示例。
  • 有多种 GPU 内存布局差异,特别是 H-tile 和 C-Mask 技术。详情请参阅 CMaskDecode、HiZDecode、HiStencil 和 PrimeHTile 示例。

呈现 (Presentation)

面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 不支持用于呈现的遗留 DXGI swap chain,而是使用 PresentX API。新的 PresentX API 旨在解决 DXGI swap chain 的延迟问题,让开发者对呈现缓冲区拥有更直接的控制。此 API 的设计也考虑了未来的流式应用的扩展。 使用 PresentX 的第一步,是在创建 Direct3D 设备之后为帧事件注册。
不是创建 DXGI swap chain 并请求后备缓冲区资源,而是直接用 D3D12_HEAP_FLAG_ALLOW_DISPLAY 标志创建它们。
在每个渲染帧开始时,先使用 WaitFrameEventX 设置管线令牌。
在帧末尾,使用同样的令牌调用 PresentX。
与 XBOX One Software Development Kit 游戏一样,面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 游戏也不会遇到 DXGI_ERROR_DEVICE_REMOVED 与 DXGI_ERROR_DEVICE_RESET 错误——PC 游戏需要处理它们。 一些其他相关的 DXGI 功能已被移除,前面提到的 ScheduleFrameEventX 函数取代了 XBOX One Software Development Kit 中的 DXGIXSetFrameNotification。 以下是 XBOX One Software Development Kit 中用于帧翻转通知的代码:
面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 游戏的等效代码:
更多详细信息,请参阅“XBOX One 上的帧调度与呈现”,以及 SimpleDeviceAndSwapChain、HDR10 和 SimpleHDR 示例。

进程生命周期管理 (PLM)

使用 Microsoft 游戏开发工具包 (GDK) 面向 XBOX 构建的游戏使用与 XBOX One XDK 应用和 UWP 应用相同的基本进程生命周期管理 (PLM) 模型。应用会以非受限、受限、挂起或终止状态运行;也就是说,终止时不会执行任何代码,进程被直接销毁。 XBOX One Software Development Kit 应用和 UWP 应用通过其 Windows Runtime CoreWindow 接收通知。面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 游戏通过已注册的回调接收通知。请注意,只有挂起和恢复事件,不再有显式的激活阶段。 一种简单的实现方式是通过发送 WM_USER 消息来处理。
随后,消息循环会处理 WM_USER 消息,以确保循环在恢复之前处于暂停状态,并在渲染循环的安全时机执行正确的 GPU 挂起/恢复行为。
更多详细信息请参阅 SimplePLM 示例。

受限与完整资源

受限资源与完整资源之间的通知通过类似的 API 处理。
出于与挂起/恢复情形相同的原因,我们在此使用消息。
更多详细信息请参阅 SimplePLM 示例。

进程终止

对于零售游戏,进程终止的处理方式与较早的 XBOX One Software Development Kit 平台相同。进程被挂起,然后终止。不会处理任何 C++ 析构函数或清理逻辑。即使你调用了 Windows::ApplicationModel::Core::CoreApplication::Exit 也是如此。 在 Microsoft 游戏开发工具包 (GDK) 中,你可以通过 PostQuitMessage 实现像经典 Win32 桌面应用那样的干净退出。这会让你的消息循环退出并执行常规代码清理和进程拆卸。这在开发时有助于发现泄漏和其他难以定位的清理问题。但这种行为很可能会触发旧的 XBOX One Software Development Kit 平台从未执行过的代码路径。

内存管理

有关内存管理的更多信息,请参阅“内存概述”。

内存模型的变化

Microsoft 游戏开发工具包 (GDK) 平台对内存模型相较于最初的 XBOX One Game OS 做了许多变更。大部分工作旨在改善游戏所用内存与系统所用内存之间的隔离。改进后的隔离让游戏和系统之间的内存使用更加可预测,并防止系统调用带来意外用量。 作为此项工作的一部分,我们移动到了最新版本的 Windows 内存管理子系统。虽然许多游戏无需重大修改,但你仍应仔细审视对这些内存 API 的使用。这些标志的含义和行为已发生变化。 如果你在手动分配和映射物理页,请注意映射的某些约束已经变了,并且这些 API 需要遵循不同的模式。
  • 当物理页被多次映射到虚拟地址空间时,所有分配必须共享相同的缓存一致性设置。例如,你不能在同一物理内存上混用 Write Combined 和普通 CPU Read/Write 页设置。
  • 页设置和缓存一致性值现在存在于物理页被映射到的虚拟地址区域中。此区域必须通过调用 XMemVirtualAlloc 并使用 MEM_RESERVE 模式预先保留。旧版本 OS 不需要这一步。
对于所有映射为 GPU 可访问的分配,现在需要显式的 GPU 访问标志。不再基于 CPU 保护设置提供默认值。 请注意识别代码库中所有使用 MEM_LARGE_PAGES 常量的地方。其值和含义已改为与 Windows 中的含义一致。 由于大页从 XBOX One Game OS 中的 4 MB 更改为面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) OS 中的 2 MB,XMemAlloc 的 size 说明符也从 XALLOC_PAGESIZE_4MB 改为 XALLOC_PAGESIZE_2MB。 我们的内存映射也发生了变化,不再划分为 Legacy、Title、Graphics 和 Physical 区域,而是覆盖整个 8-TB 地址空间。

API 的变化

Microsoft 游戏开发工具包 (GDK) 内存 API 以 XMem 前缀开头,多数与现有 XBOX One XDK OS 中的 API 相对应,尽管其行为有所改变。 新增的 API 见下表。

使用 XMemVirtualAlloc 替代 VirtualAlloc

在 Microsoft 游戏开发工具包 (GDK) 中,新的 XMemVirtualAlloc API 取代了所有用于分配 XBOX 图形内存的 VirtualAlloc 用法。请注意前述关于为随后由物理映射支撑的预留指定 GPU 页和缓存一致性要求的规定。 XBOX One Software Development Kit 上的这种预留:
在 Microsoft 游戏开发工具包 (GDK) 中:
或者对于不由已映射物理页支撑、在保留时就提交的分配:
改为:

使用 VirtualFree

由 VirtualAlloc 或 XMemVirtualAlloc 分配的内存仍通过 VirtualFree 释放。没有 XMemVirtualFree API。

XMemAlloc 用法

Attributes 宏现在增加了一个参数。例如:
改为:

XMemAllocatePhysicalPages 与 XMemMapPhysicalPages

由于将页面标志和缓存一致性移到了保留时,分配和映射物理内存的调用得以简化,但仍与 XBOX One Software Development Kit 类似。XMemAllocatePhysicalPages 取代 AllocateTitlePhysicalPages。XMemMapPhysicalPages 取代 MapTitlePhysicalPages。 这段 XBOX One Software Development Kit 代码:
对 Microsoft 游戏开发工具包 (GDK) 游戏改为:

编程模型

有关编程模型的更多信息,请参阅“异步编程模型”主题。

GameRuntime 的同步(阻塞)代码

对于可以合理选择阻塞方式的 API,即使调用可能长时间运行,也提供了所有库功能的阻塞(同步)版本。开发者可以派生线程,并从这些线程调用阻塞函数,通过调度器管理并发,这通常比 C++11 风格的 futures/promises 更容易实现。在某些情况下(例如网络调用),函数运行时长已知是非确定性的,因此只提供异步版本。

GameRuntime 的异步代码

Microsoft 游戏开发工具包 (GDK) 平台包含一个新的用于执行异步任务并通过回调报告结果的模型,取代了 Windows Runtime。使用 GameRuntime API 指定异步工作和回调发生的方式与位置。 以下示例代码包含如何设置 Game Runtime Task Queue 处理系统调用的简单模板示例。此队列既可用于处理系统任务,也可作为回调执行的位置。从概念上讲,回调是响应系统操作运行的 你的 代码。如有必要,可以创建多个 Task Queue 以在不同核心上管理工作,或按调用逐一指定执行回调的队列。 派发排队工作项既可以由你的代码手动泵送(类似于 Windows 消息队列),也可以自动泵送。以下是创建并泵送手动泵送队列的简单示例。
有关更多信息,请参阅 SimplePLM 示例,其中触发了 settings 与用于登录的 TCUI,使用了 XTask 异步队列。 有关异步编程模型的详细信息,请参阅“异步编程模型”和“Async task queue 设计”主题。另参阅 AsynchronousProgramming 示例。

异步 API 调用的通用命名规范

下表展示了 Microsoft 游戏开发工具包 (GDK) 及 Game Runtime 用于命名异步调用的通用模式。

XAsyncBlock 取代 IAsyncOperation 和 IAsyncAction

调用异步函数时,创建一个 XAsyncBlock 结构,它必须在调用期间保持有效,直到调用完成、被取消或失败。 XAsyncBlock 类型包含三个直接相关的参数。 用法示例:
请注意,创建 XAsyncBlock 结构时“清零”非常关键,因此使用 {} 而不是 ()。

时间敏感操作

Microsoft 游戏开发工具包 (GDK) 库让你可以指定当前调用所在线程是否为时间敏感线程。如果你在时间敏感线程中调用 非 时间敏感的函数,可以在运行时报告警告。
要将线程标记为时间敏感,请在该线程上调用 SetTimeSensitiveThread(true)。你也可以在自己的长时间运行函数中调用 VerifyNotTimeSensitiveThread(),以报告来自时间关键线程的不当使用。

HLSL 着色器

XBOX One Software Development Kit 平台使用定制版本的 FXC.EXE HLSL 编译器,支持将 Shader Model 5.1 可编程着色器预编译为 ATI 微码。此外,还预览支持 Shader Model 6 的 DXC.EXE DXIL 编译器。 对于面向 XBOX 的 Microsoft 游戏开发工具包 (GDK),建议通过 DXC.EXE 使用 DXIL 编译器和 Shader Model 6。FXC.EXE 的 Shader Model 5.1 编译器现被视为遗留。新编译器支持旧编译器支持的大多数命令行标志,但一些 XBOX 特定扩展 defines 不适用或不支持。有关 Shader Model 6 和 DXIL 的详细信息,请参阅 GitHub 项目。
Shader Model 6 的 PC 用法:Windows 10 Creators Update 及更高版本支持 Shader Model 6.x DXIL 着色器,许多零售驱动也支持。请直接从供应商处安装最新驱动,而不是依赖 Windows Update WHQL 驱动来获得此功能。Windows 版 DXC.EXE 编译器包含在 Windows 10 April 2018 Update SDK 及更高版本中。在运行时,你可以通过 CheckFeatureSupport 使用 D3D12_FEATURE_SHADER_MODEL 判断 PC 是否支持 Shader Model 6.x,但调用该函数之前请务必初始化 shaderModel.HighestShaderModel!
XBOX One 版本的 DXIL 编译器位于:%GameDKLatest%\GXDK\bin\XboxOne\DXC.exe。 XBOX Series X|S 版本的 DXIL 编译器位于:%GameDKLatest%\GXDK\bin\Scarlett\DXC.exe。

D3DCompile API

对于 Shader Model 6,应使用 dxcompiler_x.lib 或 dxcompiler_xs.lib 库,而不是 d3dcompiler_x.lib。

用户管理

Microsoft 游戏开发工具包 (GDK) 的用户模型相较你在 XBOX One Software Development Kit 中习惯的方式发生了变化。这一部分是为了更好地管理用户的隐私预期,减轻始终追踪系统在后台对游戏不关心的用户所做操作的负担。系统不再让游戏监视登录到主机的全局用户和访客集合,而是按需暴露用户。 要为你的游戏获取一个用户(例如用户在控制器上按下 A 按钮开始游戏会话,且该控制器尚未与某个用户关联时),请调用 XUserAddAsync。此调用将执行两项重要操作:为游戏登录用户,并更新用户输入设备配对。 用户可以同时与任意数量的输入设备配对。但游戏只会知道已通过 XUserAddAsync 登录的用户的关联。如果在游戏外通过系统 Guide 登录用户或更改关联到游戏尚未知晓的用户,那么游戏只会被告知该输入设备已解除配对。但游戏之外的系统仍然知道用于系统使用的配对信息。 游戏可以通过订阅 XUserChangeEvent 监视用户状态或用户关联 信息(例如 Gamertag、Gamer Picture 或特权)的变化(尽管其中一些信息,例如用户登录状态,也可以通过轮询监视)。方法是调用 XUserRegisterForChangeEvent。 大多数游戏应预期需要自行构建用户集合、跟踪何时用户登录到游戏、跟踪输入设备关联,并处理用户登出。 有关这些变化的深入讨论,请参阅“用户与输入设备”,也请参阅 UserManagement 示例。

网络与 XBOX 服务集成

网络传输

面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 通过 CNG 支持 WinSock2 和 BCrypt。如果使用 UDP,请不要为多人游戏套接字绑定硬编码 3074 这样的端口,对于 Microsoft 游戏开发工具包 (GDK) 应使用这个新的扁平 C API:
要在 Microsoft 游戏开发工具包 (GDK) 中检测网络连接性,请使用 IPHelper 而不是 Windows.Networking.Connectivity 命名空间。示例代码请参阅“网络初始化与连接性”。
Secure Sockets (Windows.Xbox.Networking 命名空间) 在 Microsoft 游戏开发工具包 (GDK) 中已被移除。
更多详细信息请参阅“WinSock 网络简介”。

通过 HTTP 的 Web 请求

Microsoft 游戏开发工具包 (GDK) 不再支持 IXMLHTTPRequest2 或 MessageWebSocket / StreamWebSocket(Windows.Networking.Sockets 命名空间)。请改用 WinHTTP。 更多详细信息请参阅“Web 请求”。

XBOX 服务 API

目前使用 Windows Runtime 或 C++ 版本 XSAPI 的开发者需要转到使用扁平 C 版本进行 XBOX 服务集成功能开发:
  • Achievements
  • Presence
  • Profile
  • Social
  • Social Manager
请参阅“XBOX 服务 C API 简介”和 XSAPI 参考。 如果你使用 Game Chat 2,请注意以下几个类已重命名,如下表所示。

后续步骤

完成从 ERA 的初次移植后,你将处于一个非常有利的位置,可以为面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 启用大量特性。如果你的游戏在 XBOX One S / XBOX One X 硬件上运行良好,以下是提升在 XBOX Series X|S 主机上体验的简易方式。 请注意,许多此类特性对遗留 ERA 游戏是自动启用的,但对面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 游戏是可选启用。现在你的游戏是原生 Microsoft 游戏开发工具包 (GDK) 游戏,请务必启用它们!
  • AutoHDR:此特性在系统级别自动将 SDR 游戏转换为 HDR,从而在 HDR10 兼容显示器上增强游戏的视觉质量。它使用 XBOX Series X|S 特定的硬件,因此不会增加 CPU、GPU、内存、带宽或延迟。该视觉增强不会改变原始艺术意图,将亮度扩展到最高 1000 nits,并将颜色扩展到 P3-D65 色彩空间。原生 HDR 实现总是更好——允许完全的艺术控制,但如果你没有资源或时间实现原生 HDR,AutoHDR 是一种简单有效的增强方式。
有关更多详情,请参阅“高动态范围 (HDR) 输出”和 AutoHDR 示例。
  • Aniso Boost:XBOX Series X|S 主机上的一项图像质量改进,是将线性纹理过滤提升为完整各向异性过滤。这是把额外 GPU 算力用于现有游戏的一种快速简便方法。作为面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 游戏,你可以在 XBOX Series X|S 上运行时将采样器状态从 D3D12_FILTER_MIN_MAG_MIP_LINEAR 改为 D3D12_FILTER_ANISOTROPIC:
  • FPS Boost:另一项简单改进是提高在 XBOX Series X|S 主机上的渲染帧率。如果你的游戏在 XBOX One S / XBOX One X 上以 30 fps 运行 (D3D12XBOX_FRAME_INTERVAL_30_HZ),它通常可以在 XBOX Series X|S 上以 60 fps 运行 (D3D12XBOX_FRAME_INTERVAL_60_HZ)。如果它在 XBOX One S/X 上以 60 fps 运行,它很可能可以在 XBOX Series X|S 上以 120 fps 运行。更多信息请参阅“120Hz 支持”和 Simple120Hz 示例。
除帧率提升外,你很可能还可以在 XBOX One X 和 XBOX Series X 上以 4K 渲染,其性能与在 XBOX One S / XBOX Series S 上以 1080p 渲染相同。
  • Quick Resume:只要你的游戏正确实现了进程生命周期管理 (PLM),此特性基本是自动的。更多详细信息请参阅 XBOX 游戏生命周期。

技巧和窍门

Microsoft Game Config 打包文件

Microsoft 游戏开发工具包 (GDK) 在 Visual Studio 构建工具链中不再使用 Package.appxmanifest 文件生成 AppxManifest.xml。取而代之,开发时所有应用包设置都存放在 MicrosoftGameConfig 文件中。
Executable Name 元素必须与包布局中 EXE 的名称匹配。
注意可以使用 Visual Studio 创建新项目。选择 File、New Project,然后从 Microsoft 游戏开发工具包 (GDK) 选择 Direct3D 12 XBOX Game 模板。然后可以将模板生成的 MicrosoftGame.config 添加到你的项目中。
可选地,可以通过添加 <ShellVisuals> 部分把各种需要出现在包中的 UI 和 Store 相关资源加入。
请注意 XBOX One Software Development Kit 中有一个 WideLogo 元素,现在被引用为 Square480x480Logo 属性。
对于 XBOX 服务集成,你还需要提供 Title ID。
如上所述,你不再需要通过清单元素获取第 7 核心和扩展 GPU 资源可用性,但可以通过清单控制标题内存。
上面的 appxmanifest 元素已被一个默认值为 “Standard” 的标题内存控制元素取代。
XBOX One Software Development Kit 的一些清单扩展也可以移到 .config 文件中。有关所有允许选项的完整定义,请参阅 MicrosoftGameConfig 文件。

获取设备类型

XBOX One Software Development Kit 中的 GetConsoleType 方法在 Microsoft 游戏开发工具包 (GDK) 中不可用。请改用 GameRuntime API XSystemGetDeviceType。

GDK 中 xdk.h 与 _XDK_VER 的替代方案

在 XBOX One Software Development Kit 中,xdk.h 头文件提供了与 XDK 构建号、QFE 级别等相关的多个构建符号。 对于 Gaming.*.x64 平台,你可以使用 grdk.h:
  • _GRDK_VER 是用于构建二进制文件的 Gaming GDK 版本编码 (HIWORD.LOWORD)。例如 0x4A610479 是构建号 19041.1145。
  • _GRDK_VER_STRING 对此构建为 “April 2020 GRDK”。
  • _GRDK_VER_STRING_W 是 _GRDK_VER_STRING 的 UTF16-LE 宽字符串等价物。
  • _GRDK_VER_STRING_COMPACT_W 对此构建为一个包含 “April 2020” 的 UTF16-LE 宽字符串。
对于 Gaming.Xbox.*.x64 平台,你还可以使用 gxdk.h:
  • _GXDK_VER 是用于构建二进制文件的 Gaming GDK 版本编码 (HIWORD.LOWORD)。例如 0x4A610479 是构建号 19041.1145。
  • _GXDK_VER_STRING 对此构建为 “April 2020 GXDK”。
  • _GXDK_VER_STRING_W 是 _GXDK_VER_STRING 的 UTF16-LE 宽字符串等价物。
  • _GXDK_VER_STRING_COMPACT_W 对此构建为一个包含 “April 2020” 的 UTF16-LE 宽字符串。

获取默认音频渲染端点 ID

Windows Runtime API Windows.Media.Devices 和 Windows.Devices.Enumeration 在面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 中不使用。要获取默认渲染器,请使用以下代码。

MapVirtualKey

MapVirtualKey 和 MapVirtualKeyEx 方法在面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 中不支持。它们最常用于在键盘处理代码中检测左右 VK_SHIFT 键。

MultiByteToWideChar 与 WideCharToMultiByte

在宽字符字符串 (UTF-16 LE) 与窄字符字符串之间转换时,Win32 开发者通常使用 MultiByteToWideChar 和 WideCharToMultiByte。对于现代代码库,我们建议使用 CP_UTF8,而不是特定的代码页或 CP_ACP。 以下代码在 Windows 7 Service Pack 1 及更高版本上有效。
有时会直接使用 437 和 1252。XBOX One Software Development Kit 和面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 都不支持 437。1252 在 XBOX One XDK 上有效,但在面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 上不支持。对于面向 XBOX 的 Microsoft 游戏开发工具包 (GDK),CP_ACP 被视为 CP_UTF8 的别名。在现代 Windows 10 和 Microsoft 游戏开发工具包 (GDK) 中,通常可以通过查找并全部替换将所有 CP_ACP 实例替换为 CP_UTF8。为简化此类移植,其他 CP_UTF8 相关参数的验证已被移除。 C++11 添加了 <codecvt> 头作为字符串转换问题的更可移植方案,但它已在 C++17 中被弃用。建议继续使用平台字符串函数。

本地化与全球化 API

在 ERA 中,Windows 除了简单的代码页选择、代码点转换(多字节转宽字符)以及系统/用户区域设置报告以外的内置本地化支持大都缺失。对于 Microsoft 游戏开发工具包 (GDK),此本地化功能已完整支持,包括 GetCurrencyFormatEx、GetNumberFormatEx、日期和时间格式枚举等特性。

XMA2 音频说明

如果你缺少 SHAPE_XMA_INPUT_BUFFER_ALIGNMENT 的定义,你必须显式添加对 shapexmacontext.h 头文件的引用。
在 XBOX One Software Development Kit 中,此头文件由其他一些音频头文件隐式包含。

UI 消息对话框支持

为帮助改进对游戏内崩溃和早期初始化故障的调试,XGameUiShowMessageDialogAsync 已加入 TCUI API 集合。在调用 XGameRuntimeInitialize 后的任何时刻都可以使用此 API,甚至在 D3D 初始化之前。该 API 在系统分区中渲染,并合成到游戏输出之上。即使游戏循环停止或尚未渲染,它也能工作。这对报告导致崩溃的错误信息,或在错误点阻塞时提示调试器附加都非常有用。它主要作为开发时诊断工具。 以下示例展示了阻塞式错误对话框,提示开发者附加进行调查。

扩展库

在使用 Windows Runtime API 的 XBOX One Software Development Kit 中,添加诸如 XSAPI 或 Game Chat 等扩展库需要使用 Visual Studio 的 “References…” 对话框。对于 Microsoft 游戏开发工具包 (GDK),此机制不再使用。可以通过 Visual Studio 项目属性添加。这会编辑 vcxproj 中 Globals 部分下的属性元素:
如果该元素不存在,默认仅包含 XSAPI。

二进制兼容性与组件复用

Microsoft 游戏开发工具包 (GDK) 的指导原则之一是最大化开发者在桌面 Windows 与 XBOX 主机游戏之间复用工作的能力。这方面尚未讨论过的一点是:桌面 Windows 与面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) OS 之间的二进制兼容性也做了改进工作。 与 XBOX One Software Development Kit 游戏不同,面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 可以复用最初为 x64 桌面 Windows 构建的多种组件。这对原型开发、工具或其他非性能关键场景来说是节省时间的宝贵特性。 Microsoft 游戏开发工具包 (GDK) 没有工具用于判断一个桌面 Windows 组件是否可复用,其可复用性取决于该组件使用了哪些操作系统 API。 面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) OS 支持的 API 可以通过在随 Microsoft 游戏开发工具包 (GDK) 发布的库上运行 dumpbin.exe /exports 获得。虽然一些特定领域的 API 位于各自的库中(例如 D3D12XboxCreateDevice 在 d3d12_x.lib 或 d3d12_xs.lib 中),但绝大多数遗留 Win32 API 都汇集在一个名为 xgameplatform.lib 的库中。以下命令在 Visual Studio Developer Command Prompt 中运行时,会展示主要支持的 Win32 API 池(除位于其他导入库中的部分外)。 dumpbin.exe /exports "c:\Program Files (x86)\Microsoft GDK\build_number\GXDK\gameKit\lib\amd64\xgameplatform.lib"
上述示例路径中,build_number 表示已安装到你系统上的构建号(例如 190700)。
最初为桌面 Windows 构建的静态库,如果仅使用许可列表中的 API,通常可以直接链接到面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) 二进制中。但这并非普遍成立,因为行为差异(例如单窗口限制)可能会导致运行时故障——如果该组件不是设计用来处理这类差异。 导入列表完全落在受支持 API 范围内的动态链接库 (DLL) 通常也能原样加载和工作。面向 XBOX 的 Microsoft 游戏开发工具包 (GDK) OS 包含转发逻辑,可将这一组 API 正确重定向到其实现位置(如果与桌面 Windows 不同)。 尽管能够在主机上复用桌面 Windows 组件可以在许多场景中节省时间,但在发布游戏的性能关键路径中并不建议这样做。多数面向桌面 Windows 构建的组件不会用最优的标志构建以在 Microsoft 游戏开发工具包 (GDK) 上执行。最值得注意的是,桌面组件面向更广泛的 CPU 范围,因此这些组件可能未启用 AVX 优化。复用桌面 DLL 还可能导致比为 Microsoft 游戏开发工具包 (GDK) 重新构建更大的整体代码体积。

编码风格与最佳实践

Code Generation for XBOX One - Best Practices (XBOX Developer Downloads->XBOX One->All XBOX One XDK CHMs) 中的指南适用于 Microsoft 游戏开发工具包 (GDK)。主要的编译器设置差异是这些项目不需要使用 C++/CX (/ZW) 或 C++/WinRT,因为大多数游戏 API 采用 Win32 或 DirectX 风格的 COM 样式。以下是一些一般性建议:
  • 利用 C++14,以及(可选地)C++17 语言一致性。请注意,Microsoft 游戏开发工具包 (GDK) 的 API 设计假定使用 C++11 或更好的编译器。
  • 生成 x64 原生浮点代码始终使用 SSE/SSE2。XBOX One 支持 /arch:AVX 以及 F16C。
  • 在 x64 原生代码中,C++ 异常处理 (/EHsc) 几乎没有开销。但运行时抛出异常并不是性能场景,因此不应用它来控制流程。
  • 强烈推荐使用类似 对象拥有资源 (RAII) 和 Resource Acquisition Is Initialization 中所述的异常安全编码技术,使用 std::unique_ptr、Microsoft::WRL::ComPtr 及其他智能指针类。
  • 优先使用标准可移植类型,如 size_t、ptrdiff_t、int8_t、uint8_t、int16_t、uint16_t、int32_t、uint32_t、int64_t、uint64_t、intptr_t 和 uintptr_t。
  • 为最小化内部填充,将指针集中在结构体和类中。
  • 相较于遗留 C 风格强制转换,优先使用 C++ 强制转换,例如 const_cast<>、static_cast<>、reinterpret_cast<> 和 dynamic_cast<>。
  • 尽可能使用内建函数 (intrinsics)。x64 原生代码不支持内联汇编。

编译器与链接器开关

使用以下开关:
  • 通用优化用 /O1 /Oi,热点模块用 /O2
  • /fp:fast
  • XBOX One 系列设备用 /arch:AVX;XBOX Series X|S 用 /arch:AVX2。
  • /favor:AMD
  • Whole Program Optimization 与 Profile-guided Optimization
  • 链接器开关 /OPT:REF,ICF
由于历史原因,/Ox 几乎与 /O2 相同,但既缺 /GF(消除重复字符串)也缺 /Gy(启用函数级链接)。优先使用 /O2 而不是 /Ox。如果使用 /Ox,请务必显式启用至少 /Gy,这对于启用链接器优化很重要。 自 XBOX One Software Development Kit 发布以来,Visual C++ 中还新增了许多编译器开关,务必了解一下:/Zc:inline、/Zc:throwingNew、/Zc:__cplusplus、/volatile:iso、/permissive-、/Zc:twoPhase-、以及 /Debug:FASTLINK。

条件代码

对于路径分叉的条件代码,请记住以下约定。 如果你的代码库已支持 XBOX One Software Development Kit,一个不错的起点是:
  1. 在代码库中搜索所有 _XBOX_ONE 的实例
  2. 将 #if defined(_XBOX_ONE) && defined(_TITLE)(其中代码在使用 DirectX 12.X 扩展)等改成:
    #if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)

全面 UTF-8

在 Windows 平台的漫长历史中,最初的 ANSI 函数早已被弃用,取而代之的是宽字符 Unicode 方案,即 CreateFileW 而不是 CreateFileA。这解决了处理各种代码页的问题,并将所有可本地化字符串简化为 wchar_t* (UTF-16 LE,小端)。UTF-8 Everywhere 宣言 认为,从内存占用和可移植性来看,char* 的 UTF-8 多字节编码是更好的方案。 对于面向 XBOX 平台的 Microsoft 游戏开发工具包 (GDK),默认代码页设为 CP_UTF8,因此 Win32 平台 API 的任何 ANSI 版本都使用 UTF-8。你可以继续使用带 UTF-16 LE 的宽字符 API,也可以选择使用 UTF-8。
Windows 完整的 UTF-8 支持是相当近期加入的,因此尚未被广泛使用。目前用户还需要主动启用,因此为了可移植性,最好将底层 Win32 API 用宽字符 API 保留可能是较优选择。
我们建议:
  • 在你的 API 中优先使用 UTF-8,只有在调用 Win32 宽字符 API 时才转换为 UTF-16 LE。不要使用 std::wstring 和 wchar_t*,而是使用 UTF-8 的 std::string 和 char*。
  • 对于窄字符串字面量,使用 C++ 前缀 u8 以确保是 UTF-8,而不是不加前缀或使用 L。
  • 保留已有的 UNICODE 和 _UNICODE 构建预处理器 defines(在 Visual Studio 中是 <CharSet> 属性)作为一种安全措施,但不要依赖这些宏,而应始终显式调用 W() 或 A() 版本。
  • 避免使用 TCHAR、TEXT()、LPTSTR 以及其他遗留文本类型和宏。更多信息请参阅 Microsoft 游戏开发工具包 (GDK) 中的 UTF-8 支持。

命名规范:性能和行为提示

面向 XBOX 平台的 Microsoft 游戏开发工具包 (GDK) API 的设计目的是让函数名能对被调用函数的性能做出隐含说明。 包含 Get 或 Set 短语的函数应当是低开销且可预测的,其性能大致与用 memcpy 复制结果的 C++ 属性包装函数相当。如果函数使用 Query 而非 Get,则暗示它是一个长时间运行的操作,可能会阻塞直到完成。 对于执行计算而非简单查询的函数,除非文档另有说明,我们通常假定其性能与检查其输入参数和所执行操作后的预期大致相符。 以 Async 结尾的函数是异步操作,可能需要非常长或不确定的时间才能完成。在大多数情况下,我们为可能耗时较长的函数同时提供阻塞和异步版本。你可以自行决定哪种适合你的代码库。在某些情况下(如网络 API),我们可能完全省略阻塞版本,因为提供它没有意义。 如果一个函数的名称以 Show 开头且以 Async 结尾,那么此函数会显示 UI 元素,其返回通常需要用户交互。在某些情况下,系统可以取消 UI 操作。

另请参阅

  • 什么是 Microsoft 游戏开发工具包?
  • Microsoft 游戏开发工具包 (GDK) 入门
最后修改于 2026年10月5日