在DirectX 11中更改分辨率
问题描述:
如何更改DirectX 11中的屏幕分辨率?有没有一个简单的方法来做到这一点,或者我必须完全重新创建交换链,并创建一个新的backbuffer和rendertargetview?在DirectX 11中更改分辨率
答
DXGI自动处理调整“前端缓冲区”的大小,即显示给用户的交换链部分。但是,应用程序负责调整“后台缓冲区”的大小。当你这样做时,你还应该重新创建所有'依赖于窗口大小'的资源。
的基本逻辑很简单:
// 1. Clear the existing references to the backbuffer
ID3D11RenderTargetView* nullViews [] = { nullptr };
m_d3dContext->OMSetRenderTargets(ARRAYSIZE(nullViews), nullViews, nullptr);
m_renderTargetView.Reset(); // Microsoft::WRL::ComPtr here does a Release();
m_depthStencilView.Reset();
m_d3dContext->Flush();
// 2. Resize the existing swapchain
hr = m_swapChain->ResizeBuffers(2, backBufferWidth, backBufferHeight, backBufferFormat, 0);
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
// You have to destroy the device, swapchain, and all resources and
// recreate them to recover from this case. The device was hardware reset,
// physically removed, or the driver was updated and/or restarted
之后,步骤,其余都是你做了什么,当你第一次创建swapchain
// 3. Get the new backbuffer texture to use as a render target
hr = m_swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), &backBuffer);
hr = m_d3dDevice->CreateRenderTargetView(backBuffer.Get(), nullptr, &m_renderTargetView);
// 4. Create a depth/stencil buffer and create the depth stencil view
CD3D11_TEXTURE2D_DESC depthStencilDesc(depthBufferFormat, backBufferWidth, backBufferHeight, 1, 1, D3D11_BIND_DEPTH_STENCIL);
hr = m_d3dDevice->CreateTexture2D(&depthStencilDesc, nullptr, &depthStencil);
CD3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc(D3D11_DSV_DIMENSION_TEXTURE2D);
hr = m_d3dDevice->CreateDepthStencilView(depthStencil.Get(), &depthStencilViewDesc, &m_depthStencilView));
// 5. Reset the rendering viewport to the new size
CD3D11_VIEWPORT viewPort(0.0f, 0.0f, static_cast<float>(backBufferWidth), static_cast<float>(backBufferHeight));
m_d3dContext->RSSetViewports(1, &viewPort);
// 6. Reset your camera's aspect ratio based on backBufferWidth/backBufferHeight
// 7. Set your render target view/depth stencil view for rendering
m_d3dContext->OMSetRenderTargets(1, m_renderTargetView.GetAddressOf(), m_depthStencilView.Get());
对于Win32桌面应用程序中,绝招正好知道要做这个过程。
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
static bool s_in_sizemove = false;
static bool s_minimized = false;
switch (message)
{
...
case WM_SIZE:
if (wParam == SIZE_MINIMIZED)
{
if (!s_minimized)
{
s_minimized = true;
// Your app should probably suspend
}
}
else if (s_minimized)
{
s_minimized = false;
// Your app should resume
}
else if (!s_in_sizemove)
// HERE is where you'd trigger a resize based on MINIMIZE/MAXIMIZE/RESTORE
break;
case WM_ENTERSIZEMOVE:
s_in_sizemove = true;
break;
case WM_EXITSIZEMOVE:
s_in_sizemove = false;
// HERE is where you'd trigger a resize based on the user resizing the window
break;
case WM_GETMINMAXINFO:
{
// You should set a minimize window size that is reasonable for your app. Here I use 320x200
auto info = reinterpret_cast<MINMAXINFO*>(lParam);
info->ptMinTrackSize.x = 320;
info->ptMinTrackSize.y = 200;
}
break;
}
...
return DefWindowProc(hWnd, message, wParam, lParam);
}
对于Windows Store应用程序/ Windows的手机应用程序,该VS模板有用于创建设备,另一个用于创建设备相关的资源,独特的功能,另一个用于创建窗口大小依赖的资源。最后一个被调用来调整大小。
全屏模式有点棘手,但基本上是一样的想法。如果您的应用程序不支持全屏,你应该确保禁用默认ALT +通过调用这个ENTER行为,当你第一次创建swapchain和设置HWND协会:
dxgiFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);
的Windows Store应用程序/ Windows手机应用程序不允许真正的“全屏”模式分辨率更改,因此这种情况不适用于它们。
你说的是调整窗口大小或你说的是建立一个全屏幕与特定的屏幕分辨率呈现? – 2014-12-04 20:07:27
我正在谈论调整窗口大小 – Anti049 2014-12-05 20:27:11