IDXGISwapChain :: ResizeBuffers在从全屏切换到窗口时触发断点

时间:2014-07-13 05:54:56

标签: c++ visual-studio directx direct3d dxgi

每当我的Direct3D 11应用程序从全屏模式切换到窗口模式时,IDXGISwapChain :: ResizeBuffers都会触发断点。在Visual Studio的控制台中,消息"严重错误0xc0000374"打印,没有其他信息。显然这意味着发生了堆损坏。好吧。我无法获得有关其发生原因的更多信息,因为窗口令人讨厌地模糊了我的视线并阻止我控制视觉工作室窗口。

我遵循this MSDN page提出的建议。我的意思是我复制并粘贴了代码。

这是我的设置代码(忽略缺少错误检查):

DXGI_SWAP_CHAIN_DESC swap_chain_desc = { 0 };
swap_chain_desc.BufferCount = 2;
swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swap_chain_desc.OutputWindow = window::get();
swap_chain_desc.SampleDesc.Count = 1;
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swap_chain_desc.Windowed = TRUE;
swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

if (fullscreen == 1) {
    swap_chain_desc.BufferDesc.Width = window::desktop_width();
    swap_chain_desc.BufferDesc.Height = window::desktop_height();
} else {
    swap_chain_desc.BufferDesc.Width = window::width();
    swap_chain_desc.BufferDesc.Height = window::height();
}

HRESULT hr = D3D11CreateDeviceAndSwapChain (
    NULL,
    D3D_DRIVER_TYPE_HARDWARE,
    NULL,
    NULL,
    NULL,
    NULL,
    D3D11_SDK_VERSION,
    &swap_chain_desc,
    &m_swap_chain,
    &m_device,
    NULL,
    &m_context
);

ID3D11Texture2D* back_buffer;
hr = m_swap_chain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&back_buffer);

hr = m_device->CreateRenderTargetView(back_buffer, NULL, &m_view);

back_buffer->Release();

m_context->OMSetRenderTargets(1, &m_view, NULL);

D3D11_VIEWPORT viewport = { 0 };
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;

if (fullscreen == 1) {
    viewport.Width = window::desktop_width();
    viewport.Height = window::desktop_height();
} else {
    viewport.Width = window::width();
    viewport.Height = window::height();
}

m_context->RSSetViewports(1, &viewport);

if (fullscreen == 1) {
    m_swap_chain->SetFullscreenState(TRUE, NULL);
}

那里有什么可能导致这个问题吗?在PeekMessage循环之后,渲染代码只是一个ClearRenderTargetView和Present,没什么重要的。

1 个答案:

答案 0 :(得分:0)

通过在设置交换链的全屏状态之前显示窗口来解决此问题。在调用UpdateWindow(hwnd)ShowWindow(hwnd, SW_SHOW)时,可以调用WS_VISIBLECreateWindow()或将窗口样式设置为CreateWindowEx(),最好在执行任何与DirectX相关的操作之前。