Я пытаюсь создать приложение Direct3D 10/11 с поддержкой полноэкранного режима. Для этого я должен предоставить пользователю список доступных видеорежимов. Кроме того, было бы здорово выбрать текущие настройки рабочего стола в качестве режима видео по умолчанию, чтобы свести к минимуму изменение видеорежима.Что делает режим масштабирования DXGI_MODE_SCALING_UNSPECIFIED в списке режимов, возвращаемых из IDXGIOutput.GetDisplayModeList?
Это было очень просто сделать это в Direct3D 9. Например, вот мой список режима, поставляемый Direct3D 9:
Current mode: 1920x1080x60Hz 32bit X8R8G8B8
Available modes:
Front buffer format 32bit X8R8G8B8: 35
1: 1920x1080x60Hz
2: 640x480x60Hz
3: 640x480x72Hz
4: 640x480x75Hz
5: 720x480x56Hz
6: 720x480x60Hz
7: 720x480x72Hz
8: 720x480x75Hz
9: 720x576x56Hz
10: 720x576x60Hz
11: 720x576x72Hz
12: 720x576x75Hz
13: 800x600x56Hz
14: 800x600x60Hz
15: 800x600x72Hz
16: 800x600x75Hz
17: 1024x768x60Hz
18: 1024x768x70Hz
19: 1024x768x75Hz
20: 1152x864x75Hz
21: 1280x720x60Hz
22: 1280x768x60Hz
23: 1280x800x60Hz
24: 1280x960x60Hz
25: 1280x1024x60Hz
26: 1280x1024x75Hz
27: 1360x768x60Hz
28: 1366x768x60Hz
29: 1600x900x59Hz
30: 1600x900x60Hz
31: 1600x1024x59Hz
32: 1600x1024x60Hz
33: 1680x1050x59Hz
34: 1680x1050x60Hz
35: 1440x900x60Hz
Но делать то же самое с помощью простого DXGI немного сложнее. Что меня больше смущает, это факт, что метод IDXGIOutpit.GetDisplayModeList возвращает до 3 копий одного и того же видеорежима. Разница находится в режиме при условии масштабирования:
DXGI_MODE_SCALING_UNSPECIFIED = 0
DXGI_MODE_SCALING_CENTERED = 1
DXGI_MODE_SCALING_STRETCHED = 2
Вот оно:
List of modes for format 32bit R8G8B8A8 UNorm:
640x480x60Hz Progressive Unspecified
640x480x72Hz Progressive Unspecified
640x480x75Hz Progressive Unspecified
720x480x56Hz Progressive Unspecified
720x480x56Hz Progressive Centered
720x480x56Hz Progressive Stretched
720x480x60Hz Progressive Unspecified
720x480x60Hz Progressive Centered
720x480x60Hz Progressive Stretched
720x480x72Hz Progressive Unspecified
720x480x72Hz Progressive Centered
720x480x72Hz Progressive Stretched
720x480x75Hz Progressive Unspecified
720x480x75Hz Progressive Centered
720x480x75Hz Progressive Stretched
720x576x56Hz Progressive Unspecified
720x576x56Hz Progressive Centered
720x576x56Hz Progressive Stretched
720x576x60Hz Progressive Unspecified
720x576x60Hz Progressive Centered
720x576x60Hz Progressive Stretched
720x576x72Hz Progressive Unspecified
720x576x72Hz Progressive Centered
720x576x72Hz Progressive Stretched
720x576x75Hz Progressive Unspecified
720x576x75Hz Progressive Centered
720x576x75Hz Progressive Stretched
800x600x56Hz Progressive Unspecified
800x600x60Hz Progressive Unspecified
800x600x72Hz Progressive Unspecified
800x600x75Hz Progressive Unspecified
1024x768x60Hz Progressive Unspecified
1024x768x70Hz Progressive Unspecified
1024x768x75Hz Progressive Unspecified
1152x864x75Hz Progressive Unspecified
1280x720x60Hz Progressive Unspecified
1280x768x59Hz Progressive Unspecified
1280x768x59Hz Progressive Centered
1280x768x59Hz Progressive Stretched
1280x800x59Hz Progressive Unspecified
1280x960x60Hz Progressive Unspecified
1280x1024x60Hz Progressive Unspecified
1280x1024x75Hz Progressive Unspecified
1360x768x59Hz Progressive Unspecified
1360x768x59Hz Progressive Centered
1360x768x59Hz Progressive Stretched
1366x768x59Hz Progressive Unspecified
1366x768x59Hz Progressive Centered
1366x768x59Hz Progressive Stretched
1440x900x59Hz Progressive Unspecified
1600x900x59Hz Progressive Unspecified
1600x900x59Hz Progressive Centered
1600x900x59Hz Progressive Stretched
1600x1024x59Hz Progressive Unspecified
1600x1024x59Hz Progressive Centered
1600x1024x59Hz Progressive Stretched
1680x1050x59Hz Progressive Unspecified
1920x1080x60Hz Progressive Unspecified
Сначала я подумал, что DXGI_MODE_SCALING_STRETCHED = этот режим требует растяжения (назад буфер меньше, то передняя один, разрешение может быть не физическое), DXGI_MODE_SCALING_CENTERED = в этом режиме изображение может не занимать весь экран (задний буфер меньше, затем передний, но физическое разрешение сохраняется), DXGI_MODE_SCALING_UNSPECIFIED = «обычный режим» (размеры спина и переднего буфера совпадают, но физическое разрешение не гарантируется). То есть Я должен показывать только те режимы, которые имеют Scaling = DXGI_MODE_SCALING_UNSPECIFIED.
Но затем я попытался определить текущий режим. Согласно MSDN, при использовании метода IDXGIOutput.FindClosestMatchingMode, если вы не укажете один из параметров, этот метод тяготеет к текущим настройкам рабочего стола, приоритетным параметрам, которые заданы и используют какой-то приоритет (ScanlineOrdering> Scaling> Format> Resolution> RefreshRate), чтобы выбрать другие. Поэтому я создал устройство (чтобы иметь возможность указать формат как DXGI_FORMAT_UNKNOWN) и передал полностью неопределенный режим этому методу (включая Scaling = DXGI_MODE_SCALING_UNSPECIFIED).
Вот результат:
Suggested mode: 32bit B8G8R8A8 UNorm 1600x1024x59Hz Progressive Stretched
Suggested mode 1.1: 32bit B8G8R8A8 UNorm 1600x1024x59Hz Progressive Stretched Mono
Как вы можете видеть, это не соответствует текущему режиму рабочего стола, который 1920x1080x60Hz. Я попытался изменить текущий режим рабочего стола на другой и обнаружил, что IDXGIOutput.FindClosestMatchingMode имеет тенденцию выбирать ближайший доступный режим с параметрами, близкими к параметрам рабочего стола, но с Scaling = DXGI_MODE_SCALING_STRETCHED, просто игнорируя Scaling = DXGI_MODE_SCALING_UNSPECIFIED, указанный мной.
Current mode: 32bit B8G8R8A8 UNorm 1024x768x75Hz Progressive Unspecified
Suggested mode: 32bit B8G8R8A8 UNorm 1280x768x59Hz Progressive Stretched
Suggested mode 1.1: 32bit B8G8R8A8 UNorm 1280x768x59Hz Progressive Stretched Mono
Это этилированный меня к ошеломляющему выводу, что DXGI_MODE_SCALING_UNSPECIFIED трактуется как недействительное значение для параметра Scaling по крайней мере, для IDXGIFactory.CreateSwapChain метод (иначе почему IDXGIOutput.FindClosestMatchingMode, который используется для выбора режима, который будет поставляться в IDXGIFactory.CreateSwapChain в большинстве случаев отказывается выбирать 1920x1080x60Hz?).
Я предполагаю, что IDXGIFactory.CreateSwapChain даже называет IDXGIOutput.FindClosestMatchingMode внутренне определить, что «физический» режим использования. Но тогда ... Что это значит?Я не могу предоставлять режимы, которые не имеют Scaling = DXGI_MODE_SCALING_CENTERED или DXGI_MODE_SCALING_STRETCHED для пользователя, потому что эти режимы не являются «физическими», т. Е. IDXGIFactory.CreateSwapChain выберет другой режим в любом случае?
Но тогда почему DXGI_MODE_SCALING_UNSPECIFIED возвращается в список доступных режимов? Если параметр Scaling используется только при вызове метода IDXGIFactory.CreateSwapChain, чтобы указать, хочу ли я центрировать изображение или масштабировать его, если поставляемый режим не соответствует «физическому», и он не используется при вызове IDXGISwapChain.ResizeTarget, cuz этот метод требует только «физических» режимов, тогда почему параметры масштабирования смешиваются в одном списке, возвращаемом IDXGIOutpit.GetDisplayModeList?
Какие режимы я должен показывать пользователю? Только те, у которых есть Scaling <> DXGI_MODE_SCALING_UNSPECIFIED? Или я должен делать противоположное? И как определить текущий режим через сам DXGI, вместо использования устаревшего Win API?
Может ли кто-нибудь объяснить это мне? Потому что в MSDN ничего не разъясняется.