Как изменить размер окна в приложении DirectX 11 для настольных ПК
Я пишу шейдерную программу DirectX 11, основанную на учебнике в этой ссылке msdn:
https://msdn.microsoft.com/en-us/library/windows/desktop/jj552952.aspx
Когда я запускаю его, он на весь экран. Изменение размера цепочки подкачки не приводит к изменению размера окна, как ожидалось. Есть ли способ изменить размер окна? Я просто хочу создать окно фиксированного размера, и если оно охватывает весь экран, я хочу, чтобы оно было полностью полноэкранным.
Я могу получить HWND из цепочки подкачки с помощью метода IDXGISwapChain1::GetHwnd. Будет ли эта ручка полезна для изменения размера окна?
Соответствующий код можно найти здесь:
https://code.msdn.microsoft.com/windowsdesktop/Direct3D-Tutorial-Win32-829979ef
1 ответ
Обратите внимание на шаблон приложения Win32 для Direct3D Win32 Game VS 2013, который обрабатывает изменение размера окна, хотя и не поддерживает полноэкранные переходы в эксклюзивном режиме.
Основной способ изменения размера окна для Direct3D 11 в настольных приложениях Win32 - обновить процедуру окна для обработки WM_SIZE
, но вам нужно справиться с рядом случаев.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static bool s_in_sizemove = false;
static bool s_minimized = false;
switch (message)
{
...
case WM_SIZE:
if (wParam == SIZE_MINIMIZED)
{
// The window was minimized (you should probably suspend the application)
if (!s_minimized)
{
s_minimized = true;
}
}
else if (s_minimized)
{
// The window was minimized and is now restored (resume from suspend)
s_minimized = false;
}
else if ( !s_in_sizemove )
{
// Here is where you handle the swapchain resize for maximize or unmaximize
}
break;
case WM_ENTERSIZEMOVE:
// We want to avoid trying to resizing the swapchain as the user does the 'rubber band' resize
s_in_sizemove = true;
break;
case WM_EXITSIZEMOVE:
s_in_sizemove = false;
// Here is the other place where you handle the swapchain resize after the user stops using the 'rubber-band'
break;
case WM_GETMINMAXINFO:
{
// We want to prevent the window from being set too tiny
auto info = reinterpret_cast<MINMAXINFO*>(lParam);
info->ptMinTrackSize.x = 320;
info->ptMinTrackSize.y = 200;
}
break;
...
Чтобы изменить размер swapchain Direct3D:
- Вызов
ID3D11DeviceContext::OMSetRenderTargets
с нулями для отмены привязки цели рендеринга и любого буфера глубины / трафарета. - Освободите представление цели рендеринга и представление глубины / трафарета, а также любые другие ссылки на исходный задний буфер или буфер глубины / трафарета.
- Вызов
D3D11DeviceContext::Flush
чтобы эти изменения закончились - Вызов
IDXGISwapChain::ResizeBuffers
изменить размер буфера до нового размера. Обязательно отвечайте наDXGI_ERROR_DEVICE_REMOVED
а такжеDXGI_ERROR_DEVICE_RESET
неудачи. - Повторите ту же настройку, что и вначале, для нового размера: создайте представление цели рендеринга для нового заднего буфера, создайте новое представление глубины трафарета для буфера глубины / трафарета, соответствующего новому размеру буфера буфера (необязательно), и выполните сброс размер области просмотра.
Поскольку эта процедура делает некоторые предположения о приложении, она была опущена в учебнике по Win32 для простоты. Этот случай обрабатывается для шаблона Direct3D Win32 Game, а также шаблона приложения DirectX для Магазина Windows и шаблона приложения DirectX для телефона Windows.
Для приложений Магазина Windows или приложений для телефона Windows не существует такого понятия, как "полноэкранный эксклюзивный режим", поэтому эти шаблоны не реализуют его. Для учебного руководства по Win32 и шаблона Direct3D Win32 Game, я использую следующее, чтобы убедиться, что мне не нужно с этим справляться:
dxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
Я надеюсь вернуться к тому, как расширить шаблон Direct3D Win32 Game для поддержки полноэкранного эксклюзивного режима, но я еще не дошел до него.