窗口模式:游戏开发者的爱恨情仇
窗口模式:不止是 Windowed Mode 这么简单
作为一名独立游戏开发者,我对“窗口模式”这四个字真是又爱又恨。爱的是它方便调试,恨的是它带来的各种奇葩问题。说到“窗口模式”的英文,可别只知道 Windowed Mode。还有 Window Mode,以及现在越来越流行的 Borderless Windowed Mode(无边框窗口模式)。
- Windowed Mode / Window Mode: 就是最传统的窗口模式,游戏画面在一个有边框的窗口里显示,可以自由调整大小和位置。
- Borderless Windowed Mode: 也叫 Fullscreen Windowed Mode,看起来像全屏,但实际上仍然是一个窗口,只是去掉了边框,并最大化填充整个屏幕。这种模式的英文表达方式很多,比如某些引擎里可能直接叫做“伪全屏”。
不同游戏引擎和操作系统对这些模式的叫法和实现方式可能略有不同。比如,Unity 中可以通过 Screen.SetResolution 函数来切换不同的全屏模式,而 Unreal Engine 则提供了 FSystemResolution::RequestResolutionChange 函数。在 Windows 系统下,这几种模式的底层实现都会涉及到 DirectX 或 OpenGL,以及桌面窗口管理器 (DWM)。
坑在哪里?
最大的坑在于不同显卡驱动和操作系统对这几种模式的支持程度参差不齐。有些老游戏可能根本不支持窗口模式,或者在窗口模式下出现各种显示错误,比如画面撕裂、颜色失真等等。还有些游戏在无边框窗口模式下性能表现极差,帧数暴跌,让人怀疑人生。
性能大比拼:窗口模式 vs. 全屏 vs. 无边框
说到性能,这三种模式各有优劣,不能一概而论。
- 全屏模式(Exclusive Fullscreen): 在理论上,全屏模式性能最好。因为在这种模式下,游戏拥有对显卡的完全控制权,可以绕过 DWM 的 compositing 过程,减少额外的渲染开销。DirectX 会直接将画面输出到显示器上。但是,全屏模式的缺点是 Alt+Tab 切换时需要重新初始化显卡,导致切换速度慢,甚至可能卡死或崩溃。
- 窗口模式(Windowed Mode): 窗口模式的性能相对较差。因为在这种模式下,游戏画面需要经过 DWM 的 compositing 处理,才能最终显示在屏幕上。DWM 会将所有窗口的内容合并成最终的画面,这会带来额外的性能开销。而且,窗口模式下显卡驱动可能会启用一些额外的优化,导致性能下降。
- 无边框窗口模式(Borderless Windowed Mode): 无边框窗口模式的性能介于全屏模式和窗口模式之间。它本质上仍然是一个窗口,需要经过 DWM 的 compositing 处理,但由于它看起来像全屏,所以可以避免一些窗口模式下的额外优化。同时,无边框窗口模式的 Alt+Tab 切换速度非常快,因为不需要重新初始化显卡。
举个例子,我之前开发的一款 2D 游戏,在全屏模式下帧数可以稳定在 60fps,但在窗口模式下帧数会下降到 40fps 左右。后来我改用无边框窗口模式,帧数又回到了 60fps,而且 Alt+Tab 切换体验也得到了很大的提升。
底层原理:显卡驱动、DirectX/OpenGL、Compositor
要理解这三种模式的性能差异,需要了解一些底层原理。简单来说,就是显卡驱动、DirectX/OpenGL 和 Compositor 之间的关系。游戏通过 DirectX/OpenGL 等图形 API 将渲染指令发送给显卡驱动,显卡驱动再将这些指令转换成具体的硬件操作。在全屏模式下,游戏可以直接控制显卡,绕过 Compositor。而在窗口模式和无边框窗口模式下,游戏画面需要经过 Compositor 的处理,才能最终显示在屏幕上。
Compositor 的作用是将所有窗口的内容合并成最终的画面。这个过程需要消耗一定的 CPU 和 GPU 资源。不同的 Compositor(比如 Windows 的 DWM)的效率也不同,这也会影响到游戏的性能。
Alt+Tab 切换:别让玩家崩溃
Alt+Tab 切换是游戏开发中一个非常重要的细节。如果玩家在 Alt+Tab 切换到桌面后,游戏卡死或者崩溃,那体验简直是灾难性的。
- 全屏模式的劣势: 全屏模式在 Alt+Tab 切换时需要重新初始化显卡,这会导致切换速度慢,甚至可能卡死或崩溃。尤其是一些老游戏,由于没有针对 Alt+Tab 切换进行优化,更容易出现问题。
- 窗口模式的优势: 窗口模式和无边框窗口模式在 Alt+Tab 切换时不需要重新初始化显卡,所以切换速度非常快,而且不容易出现卡死或崩溃的情况。
如何优化 Alt+Tab 体验?
作为开发者,我们可以采取一些措施来优化 Alt+Tab 体验:
- 使用无边框窗口模式: 如果游戏对性能要求不高,可以优先考虑使用无边框窗口模式。这种模式在 Alt+Tab 切换体验和性能之间取得了较好的平衡。
- 处理 WM_ACTIVATE 事件: 在 Windows 平台上,游戏可以通过处理
WM_ACTIVATE事件来检测窗口是否获得了焦点。当窗口失去焦点时,可以暂停游戏逻辑,避免在后台占用 CPU 资源。当窗口重新获得焦点时,可以恢复游戏逻辑。 - 使用异步加载: 在 Alt+Tab 切换过程中,可以异步加载一些资源,避免阻塞主线程,导致游戏卡顿。
多显示器支持:窗口模式的妙用
在多显示器环境下,窗口模式可以发挥更大的作用。
- 扩展视野: 窗口模式可以方便地将游戏窗口拖动到不同的显示器上,从而扩展视野。有些游戏甚至支持在不同的显示器上显示不同的游戏内容,比如在主显示器上显示游戏画面,在副显示器上显示地图或者聊天窗口。
- 直播和录制: 窗口模式可以方便地进行直播和录制。可以将游戏窗口单独捕获,避免捕获到其他不必要的窗口。
如何实现多显示器支持?
在游戏引擎中,可以使用 API 来获取显示器的信息,比如数量、分辨率、位置等等。然后,可以根据这些信息来调整游戏窗口的大小和位置,实现多显示器支持。
兼容性问题:老游戏的救星
有些老游戏可能不支持窗口模式,或者在窗口模式下出现显示错误。这时,我们可以使用一些工具和技巧来解决这些兼容性问题。
- Dxwnd: Dxwnd 是一款强大的窗口化工具,可以将全屏游戏强制运行在窗口模式下。它还可以修复一些显示错误,比如画面撕裂、颜色失真等等。
- DDrawCompat: DDrawCompat 是一款 DirectDraw 兼容性库,可以解决一些老游戏在 Windows 10 下运行出现的问题。
- 手动修改配置文件: 有些游戏允许通过修改配置文件来设置窗口模式。可以尝试修改配置文件中的相关参数,看看是否能够启用窗口模式。
开发者视角:如何正确实现窗口模式
作为开发者,我们需要在游戏引擎中正确实现窗口模式,并为用户提供灵活的窗口模式设置选项。
- 选择合适的 API: 在不同的游戏引擎中,有不同的 API 可以用来设置窗口模式。需要根据具体情况选择合适的 API。
- 处理窗口事件: 游戏需要正确处理窗口事件,比如窗口大小改变、窗口失去焦点等等。这些事件会影响到游戏的渲染和逻辑。
- 提供灵活的设置选项: 游戏应该为用户提供灵活的窗口模式设置选项,比如全屏模式、窗口模式、无边框窗口模式等等。用户可以根据自己的需求选择合适的模式。
- 测试和优化: 在不同的硬件和操作系统上进行充分的测试和优化,确保游戏在各种情况下都能正常运行。
总结
窗口模式看似简单,实则涉及到很多底层技术和细节。作为游戏开发者,我们需要深入了解窗口模式的原理,并掌握一些实用的开发技巧,才能为玩家提供更好的游戏体验。希望这篇文章能帮助你更好地理解窗口模式,并在游戏开发中避开那些令人头秃的坑。记住,2026 年的游戏,不能再犯 2006 年的错误了!