5

DXGI 上的 MSDN 页面提供了有关如何处理不同于桌面分辨率的全屏分辨率的说明。它说在调用IDXGISwapChain::ResizeTargets()之前先调用IDXGISwapChain::SetFullscreenState()以防止闪烁等。

它没有说明如何处理 Alt-Enter,它IDXGISwapChain::SetFullscreenState()在程序有机会自己调用IDXGISwapChain::ResizeTargets(). 如果对消息调用后一种方法,则会发送WM_SIZEWM_SIZE一条消息,可能导致无限循环。当按下 alt-enter 或 alt-tab 时,如何确保在前者之前调用后者,并且模式切换通常会无痛地发生?

4

2 回答 2

7

这将是非常棘手的......应该如何处理的正确方法是IDXGIFactory::MakeWindowAssociation,据我所知,没有人能够成功使用。无论如何,您可能都想尝试一下。

“正确”的答案是手动处理 Alt+Enter。所以,禁用 Alt+EnterMakeWindowAssociation并弄脏你的手。首先,不需要捕获WM_SIZE. 相反,请听WM_ENTERSIZEMOVEWM_CAPTURECHANGED和。这将使您不必处理并仍然获得所有相关的窗口大小调整事件。(执行此操作时,请同时阅读此问题:WM_ENTERSIZEMOVE / WM_EXITSIZEMOVE - 使用菜单时,并不总是配对WM_WINDOWPOSCHANGEDWM_EXITSIZEMOVEWM_SIZE

好的,假设一切顺利,对于 Alt+Enter,您必须执行以下操作:使用将交换链设置为全屏IDXGISwapChain::SetFullscreenState,然后调整交换链 ( IDXGISwapChain::ResizeBuffers) 的大小。默认情况下,在调整大小之前,您将获得一个尽可能接近当前窗口分辨率的交换链。您正确执行此操作的方法是首先枚举全屏分辨率,然后在全屏时强制使用您想要的分辨率。这听起来很难看,但它似乎是解决问题的最可靠的方法。

一般来说,真正的独占全屏模式不值得麻烦,因为当有人按 Alt+Tab 时你总是会闪烁(如果发生模式切换,你无法避免它,因为屏幕本身必须重新调整。)更好的解决方案是使用全屏无边框窗口。您只需创建一个没有任何装饰的窗口类,使其全屏显示,将其放置为覆盖整个屏幕并完成它。那么你就完全不用担心 Alt+Enter 和 Alt+Tab 了。它还允许人们继续在第二个屏幕上工作而不会闪烁。性能方面,这还不错(大多数新游戏都支持“无边框全屏”。)

可能有一个灵丹妙药可以正确解决所有这些问题,但我还没有看到它。如果有更清洁/更好的解决方案,我真的很想听到它。“无边框全屏”似乎是当前标准,但 IIRC、Unity 5 仅允许 Direct3D 11 的“无边框全屏”。

于 2014-08-18T18:05:32.997 回答
2

我只想添加关于这个问题的更新——我编写了一个小型窗口库,我相信它可以很好地处理 DXGI——没有调试消息,没有错误消息,并且一切都按预期运行,至少在我的 Windows 环境中是这样。这个问题的完整解决方案过于复杂,无法在一个答案中解释,因为它需要大量精确放置的方法调用(事实证明,DXGI 真的非常严格),但如果有人的话,我的代码在github上想看看它。具体来说,此文件此文件是您要查看的文件-后者是前者的聚合对象。

请注意,我已禁用ALT+ENTER支持F11,但功能完全相同。

顺便说一句,如果您想使用该库,我将其作为免费软件发布,并将很快提供文档。

于 2015-07-06T16:06:15.543 回答