DirectX 应用程序中 Alt-Tab 支持的最佳实践?
在编写 DirectX 应用程序时,显然希望支持用户通过 Alt-Tab 以快速且无错误的方式暂停应用程序。 确保这一点的最佳实践是什么? 需要解决的问题包括:
- 检测应用程序何时被 alt-tab 退出以及何时返回的最佳方法。
- 当用户使用 alt-tabs 时会丢失哪些 DirectX 资源,以及解决此问题的最佳方法。
- 为了支持 alt-tab,在应用程序架构中要做的主要事情和要避免的事情。
- 主要 DirectX 版本之间的任何显着差异均适用于上述内容。
有趣的技巧和陷阱也值得一听。
When writing DirectX applications, obviously it's desirable to support the user suspending the application via Alt-Tab in a way that's fast and error-free. What is the best set of practices for ensuring this? Things that need to be addressed include:
- The best methods of detecting when your application has been alt-tabbed out of and when it has been returned to.
- What DirectX resources are lost when the user alt-tabs, and the best ways to cope with this.
- Major things to do and things to avoid in application architecture for purposes of alt-tab support.
- Any significant differences between major DirectX versions as they apply to the above.
Interesting tricks and gotchas are also good to hear about.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我假设您使用 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]
当应用程序从全屏模式失去焦点时,图形设备就会丢失。 Microsoft 提供了一篇有关如何处理此问题的文章:http:// msdn.microsoft.com/en-us/library/bb174717(VS.85).aspx 本文还有丢失设备教程:http://www.codesampler.com/dx9src/dx9src_6.htm
DirectInput 也可能出现设备丢失错误状态,以下是相关链接:< a href="http://www.toymaker.info/Games/html/directinput.html" rel="noreferrer">http://www.toymaker.info/Games/html/directinput.html< /p>
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
I will assume you are using C++ for the purposes of my answers, but if you can afford to use C#, XNA (http://creators.xna.com/) is an excellent game platform that handles all of these issues for you.
1]
This article is helpful for windows events in the window procedure to detect when a window loses or gains focus, you could handle this on your main window: http://www.functionx.com/win32/Lesson05.htm. Also, check out the WM_ACTIVATEAPP message here: http://msdn.microsoft.com/en-us/library/ms632614(VS.85).aspx
2]
The graphics device is lost when the application loses focus from full screen mode. Microsoft offers an article on how to handle this: http://msdn.microsoft.com/en-us/library/bb174717(VS.85).aspx This article also has a lost device tutorial: http://www.codesampler.com/dx9src/dx9src_6.htm
DirectInput can also have a device lost error state, here is a link about that: http://www.toymaker.info/Games/html/directinput.html
DirectSound can also have a device lost error state, this article has code that handles that: http://www.eastcoastgames.com/directx/chapter2.html
3]
I would make sure to never disable Alt-Tab. You probably want minimal CPU load while the application is not active because the user probably Alt-Tabbed because they want to do something else, so you could completely pause the application, or reduce the frames rendered per second. If the application is minimzed, you of course don't need to render anything either. After thinking about a network game, my best solution is that you should still reduce the frames rendered per second as well as the amount of network packets handled, possibly even throwing away many of the packets that come in until the game is re-activated.
4]
Honestly I would just stick to DirectX 9.0c (or DirectX 10 if you want to limit your target operating system to Vista and newer) if at all possible :)
Finally, the DirectX sdk has numerous tutorials and samples: http://www.microsoft.com/downloads/details.aspx?FamilyID=24a541d6-0486-4453-8641-1eee9e21b282&displaylang=en
我们通过根本不使用全屏 DirectX 设备来解决这个问题 - 相反,我们使用带有最顶部标志的全屏窗口来隐藏任务栏。 如果您按 Alt-Tab 键退出该窗口,则可以删除该标志并最小化窗口。 纹理资源通过窗口保持活动状态。
但是,此方法无法处理由于“锁定屏幕”、Ctrl+Alt+Delete、远程桌面连接、用户切换或类似情况而发生的设备丢失事件。 但这些不需要非常快速或高效地处理(至少在我们的应用程序中是这样)
We solved it by not using a fullscreen DirectX device at all - instead we used a full-screen window with the top-most flag to make it hide the task bar. If you Alt-Tab out of that, you can remove the flag and minimize the window. The texture resources are kept alive by the window.
However, this approach doesn't handle the device lost event happening due to 'lock screen', Ctrl+Alt+Delete, remote desktop connections, user switching or similar. But those don't need to be handled extremely fast or efficiently (at least that was the case in our application)
所有重要的 D3D 应用程序都应该能够处理丢失的设备,因为这种情况可能因多种原因而发生。
在 Vista 下的 DX10 中,有一个新的“超时检测和恢复”功能,根据我的经验,重置图形设备很常见,这会导致应用程序丢失设备。 随着驱动程序的成熟,这似乎正在改善,但无论如何你都需要处理它。
All serious D3D apps should be able to handle lost devices as this is something that can happen for a variety of reasons.
In DX10 under Vista there is a new "Timeout Detection and Recovery" feature that makes it common in my experience for graphics devices to be reset which would cause a lost device for your app. This seems to be improving as drivers mature but you need to handle it anyway.
在 DX8 和 9(和 10?)中,如果您使用 D3DPOOL_MANAGED 创建资源(主要是顶点和索引缓冲区和纹理),它们将在丢失的设备上持续存在,并且不需要重新加载。 这是因为它们存储在系统内存中,DX 运行时会自动复制到视频内存中。 然而,复制会带来性能成本,对于快速变化的顶点数据不建议这样做。 当然,您首先要进行分析以确定是否存在速度问题:-)
In DX8 and 9 (and 10?) if you create your resources (vertex and index buffers and textures mainly) using D3DPOOL_MANAGED they will persist across lost devices and will not need reloading. This is because they are stored in system memory and the DX runtime copies to video memory automatically. However there is a performance cost due to the copying and this is not recommended for rapidly changing vertex data. Of course you would profile first to determine if there is a speed issue :-)