Страница MSDN на DXGI дает инструкции о том, как обрабатывать полноэкранные разрешения, отличные от разрешения рабочего стола. Это говорит, чтобы позвонить IDXGISwapChain::ResizeTargets()
перед звонком IDXGISwapChain::SetFullscreenState()
для предотвращения мерцания, между прочим.
Там не сказано, как обрабатывать Alt-Enter, который вызывает IDXGISwapChain::SetFullscreenState()
до того, как программе дается возможность сделать свой собственный вызов IDXGISwapChain::ResizeTargets()
, Если последний метод вызывается на WM_SIZE
сообщение, другое WM_SIZE
сообщение будет отправлено, возможно, вызывая бесконечный цикл. Как я могу убедиться, что последний будет вызываться раньше первого при нажатии alt-enter или alt-tab, и что переключение режимов происходит безболезненно в целом?
Это будет действительно сложно … правильный способ, как это должно быть обработано IDXGIFactory::MakeWindowAssociation
, который, насколько я знаю, никому не удалось успешно использовать. Вы можете попробовать это в любом случае.
«Правильный» ответ — вручную обработать Alt + Enter. Итак, отключите Alt + Enter, используя MakeWindowAssociation
и грязные руки Во-первых, нет необходимости захватывать WM_SIZE
, Вместо этого слушайте WM_ENTERSIZEMOVE
, WM_CAPTURECHANGED
, WM_WINDOWPOSCHANGED
а также WM_EXITSIZEMOVE
, Это избавит вас от необходимости иметь дело с WM_SIZE
и по-прежнему получать все соответствующие события изменения размера окна. (При этом прочитайте и этот вопрос: WM_ENTERSIZEMOVE / WM_EXITSIZEMOVE — при использовании меню не всегда сопряжено)
Итак, при условии, что все прошло нормально, для Alt + Enter вы должны сделать следующее: Вы устанавливаете цепочку обмена на полный экран, используя IDXGISwapChain::SetFullscreenState
а затем измените размер вашей цепочки обмена (IDXGISwapChain::ResizeBuffers
). По умолчанию перед изменением размера вы получите цепочку подкачки, максимально приближенную к текущему разрешению вашего окна. Правильный способ сделать это — сначала перечислить разрешения на весь экран, а при переходе на полноэкранный режим указать требуемое разрешение. Это звучит некрасиво, но, похоже, это самый надежный способ решения проблемы.
В общем, настоящий, эксклюзивный полноэкранный режим не стоит хлопот, так как вы всегда будете мерцать, когда кто-нибудь нажимает Alt + Tab (вы не можете избежать этого, если произойдет переключение режима, так как сам экран придется перенастроить.) A гораздо лучшее решение — использовать полноэкранное окно без полей. Вы просто создаете класс окна без какого-либо оформления, делаете его полноэкранным, размещаете его так, чтобы он покрывал весь экран, и покончите с этим. Тогда вам не нужно беспокоиться о Alt + Enter и Alt + Tab. Это также позволяет людям продолжать работать на втором экране без мерцания. С точки зрения производительности, это довольно хорошо (большинство новых игр поддерживают это как «полноэкранный режим без полей».)
Там может быть серебряная пуля, которая решает все это правильно, но я еще не видел это. Если есть более чистое / приятное решение, мне было бы очень интересно его услышать. «Полноэкранный режим без полей», по-видимому, является текущим стандартом, хотя в IIRC Unity 5 будет разрешен только «полноэкранный режим без полей» для Direct3D 11.
Я просто хочу добавить обновление по этой проблеме — я написал небольшую библиотеку окон, которая, на мой взгляд, довольно хорошо обрабатывает DXGI — никаких отладочных сообщений, никаких сообщений об ошибках, и все ведет себя как задумано, по крайней мере, в моей среде Windows. Полное решение этой проблемы слишком сложно объяснить в одном ответе, так как требует много точно размещенных вызовов методов (как оказалось, DXGI действительно, очень жесткий), но мой код включен GitHub если кто-то хочет взглянуть на это. В частности, этот файл а также этот файл это те, на которые вы хотите посмотреть — последний является совокупным объектом первого.
Обратите внимание, что я отключил ALT+ВОЙТИ в пользу F11, но функциональность точно такая же.
Кстати, если вы хотите использовать эту библиотеку, я выпускаю ее как бесплатное программное обеспечение и скоро предоставлю документацию.