DirectX 应用程序中 Alt-Tab 支持的最佳实践?
Posted
技术标签:
【中文标题】DirectX 应用程序中 Alt-Tab 支持的最佳实践?【英文标题】:Best practices for Alt-Tab support in a DirectX app? 【发布时间】:2009-06-09 20:22:36 【问题描述】:在编写 DirectX 应用程序时,显然需要支持用户通过 Alt-Tab 以一种快速且无错误的方式暂停应用程序强>。确保这一点的最佳实践是什么?需要解决的问题包括:
-
检测应用程序何时被 alt-tabbed 退出以及何时返回的最佳方法。
当用户使用 alt-tab 时会丢失哪些 DirectX 资源,以及解决此问题的最佳方法。
为了支持 alt-tab 的目的,在应用程序架构中要做的主要事情和要避免的事情。
适用于上述内容的主要 DirectX 版本之间的任何显着差异。
有趣的技巧和陷阱也值得一听。
【问题讨论】:
下面发布的代码示例链接看起来已经足够了,所以我将添加以下内容:我们发现测试这种情况的一种简单方法是在窗口模式下运行应用程序并锁定Windows 桌面。这样,您可以在本地调试器下运行时轻松测试丢失设备的情况。 不知道你为什么选择 Valve。半条命是我最早使用 alt-tab 没有问题的游戏之一。如果有问题,可能是因为 DirectX 本身(HL 在我的设置中使用了 OpenGL) SpliFF,对我来说这是第一款出现 Alt Tab 问题的游戏,至少我记得。 :) SpliFF:TF2 因 alt-tab 问题而臭名昭著。我不确定它们是否已修复,但一个常见的问题是当您按 alt-tab 键回到游戏时玩家会消失(这需要 ages - 另一个问题)。例如,你看不到他们,但他们可以看到并杀死你。我不知道这是否是由于图像缓冲区被清除并且没有在应有的时候重新加载,但它带来了一些有趣的遭遇。 我曾经遇到过 TF2 Alt+Tab 的问题,但是将“-window -noborder”设置为启动参数完全解决了它。当我等待重生时,我正在浏览或做其他事情,而且我从来没有遇到过图形损坏的问题。 【参考方案1】:我假设您使用 C++ 来回答我的问题,但如果您负担得起使用 C#,XNA (http://creators.xna.com/) 是一个出色的游戏平台,可以为您处理所有这些问题。
1]
本文有助于窗口过程中的窗口事件检测窗口何时失去或获得焦点,您可以在主窗口上处理此问题:http://www.functionx.com/win32/Lesson05.htm。另外,请在此处查看 WM_ACTIVATEAPP 消息:http://msdn.microsoft.com/en-us/library/ms632614(VS.85).aspx
2]
当应用程序从全屏模式失去焦点时,图形设备会丢失。微软提供了一篇关于如何处理这个问题的文章:http://msdn.microsoft.com/en-us/library/bb174717(VS.85).aspx这篇文章还有一个丢失设备的教程:http://www.codesampler.com/dx9src/dx9src_6.htm
DirectInput 也可能有设备丢失错误状态,这里有一个链接:http://www.toymaker.info/Games/html/directinput.html
DirectSound 也可能有设备丢失错误状态,本文有处理该错误状态的代码:http://www.eastcoastgames.com/directx/chapter2.html
3]
我会确保永远不要禁用 Alt-Tab。您可能希望在应用程序不活动时最小化 CPU 负载,因为用户可能是 Alt-Tabbed,因为他们想做其他事情,因此您可以完全暂停应用程序,或减少每秒渲染的帧数。如果应用程序被最小化,你当然也不需要渲染任何东西。在考虑过网络游戏之后,我最好的解决方案是您仍然应该减少每秒渲染的帧数以及处理的网络数据包的数量,甚至可能丢弃许多进入游戏的数据包,直到重新激活游戏。
4]
老实说,如果可能的话,我会坚持使用 DirectX 9.0c(或 DirectX 10,如果您想将目标操作系统限制为 Vista 和更新版本):)
最后,DirectX sdk 有大量的教程和示例:http://www.microsoft.com/downloads/details.aspx?FamilyID=24a541d6-0486-4453-8641-1eee9e21b282&displaylang=en
【讨论】:
你的答案看起来很扎实;谢谢!我相信我会在等待期结束时提出这个问题,因为我相信这是一个缺乏连贯资源的重要话题。如果您倾向于对您的答案进行任何进一步的编辑,我建议您总结各个链接的要点;如果寻找这个主题的人可以在答案中获得尽可能多的相关信息,那就太好了。 (当然,链接容易受到链接腐烂。) 那么您是自己开发游戏还是参与开发游戏的团队? 为“游戏”读取“DirectX 游戏”,目前都没有。很久以前,我做了足够多的工作,就代码而言是单独的,以了解所涉及的一些问题。 (哦,伙计们,你可以使用 DX 表面来做很多工作。只是,你知道,如果用户 alt-tabs 他们神秘地消失了。哎呀!)在我的未来可能会有更多这样的事情,我在当前 DX 版本的问题上有点可怕的反复试验,然后我突然想到:嘿,这就是 innit 的 SO。【参考方案2】:我们完全不使用全屏 DirectX 设备解决了这个问题 - 而是使用带有最顶部标志的全屏窗口来隐藏任务栏。如果您使用 Alt-Tab 退出,您可以删除标志并最小化窗口。纹理资源由窗口保持活动状态。
但是,此方法无法处理由于“锁定屏幕”、Ctrl+Alt+Delete、远程桌面连接、用户切换或类似情况而发生的设备丢失事件。但是这些不需要非常快速或高效地处理(至少我们的应用程序是这样)
【讨论】:
【参考方案3】:所有严肃的 D3D 应用都应该能够处理丢失的设备,因为这可能由于多种原因而发生。
在 Vista 下的 DX10 中,有一个新的“超时检测和恢复”功能,根据我的经验,重置图形设备很常见,这会导致您的应用程序丢失设备。随着驱动程序的成熟,这似乎正在改善,但无论如何您都需要处理它。
【讨论】:
最好的“丢失设备”,是由驱动程序升级引起的 ;-) 咯咯咯咯但是认真的。能够处理上下文切换并能够重置状态是在多任务环境中构建强大应用程序的重要部分。【参考方案4】:在 DX8 和 9(和 10?)中,如果您使用 D3DPOOL_MANAGED 创建资源(主要是顶点和索引缓冲区和纹理),它们将在丢失的设备上持续存在,并且不需要重新加载。这是因为它们存储在系统内存中,并且 DX 运行时会自动复制到视频内存。但是,由于复制会产生性能成本,因此不建议将其用于快速更改的顶点数据。当然你会先分析以确定是否存在速度问题:-)
【讨论】:
以上是关于DirectX 应用程序中 Alt-Tab 支持的最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章
显卡上总说的directx 11 和游戏总说支持这个 到底啥意思 啥显卡支持directx呢 请详细讲讲 高分
消除在 Java GUI 中使用 Alt-F4 和 Alt-TAB 的可能性 [重复]