调整窗口大小后交换渲染缓冲区会导致问题

时间:2015-03-06 15:34:01

标签: c++ winapi directx directx-11

我正在尝试处理窗口大小调整消息WM_SIZE。 当我收到它时:

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_SIZE:
    {
        int nWidth = LOWORD(lParam);
        int nHeight = HIWORD(lParam);
        renderer->Resize(nWidth, nHeight);
        return 1;
        break;
    }
    case WM_DESTROY:
    {
        PostQuitMessage(0);
        return 0;
    } break;
    }

    return DefWindowProc(hWnd, message, wParam, lParam);
}

我使用新的高度和宽度参数来重新创建渲染目标视口并调整缓冲区的大小:

void Renderer::Resize(int w, int h)
{
    m_devContext->OMSetRenderTargets(0, 0, 0);

    m_renderTargetView->Release();

    HRESULT hr;
    hr = m_swapchain->ResizeBuffers(1, w, h, DXGI_FORMAT_UNKNOWN, 0);

    ID3D11Texture2D* pBuffer;
    hr = m_swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D),
        (void**)&pBuffer);

    hr = m_device->CreateRenderTargetView(pBuffer, NULL,
        &m_renderTargetView);

    pBuffer->Release();

    m_devContext->OMSetRenderTargets(1, &m_renderTargetView, NULL);

    // Set up the viewport.
    D3D11_VIEWPORT vp;
    vp.Width = w;
    vp.Height = h;
    m_devContext->RSSetViewports(1, &vp);

}

尽管如此,在resize事件之后呈现的第一帧会导致错误:

void Renderer::Render() const
{

    m_devContext->ClearRenderTargetView(m_renderTargetView, m_clearCol);
    HRESULT ret = m_swapchain->Present(0, 0); //triggered exception here, only the first frame after resize
}

Visual Studio弹出错误是:

  

ApplicationName.exe已触发异常

。没有其他信息,也没有可捕捉的例外。从网上的一些研究中我猜它可能与一些未发布的资源或堆腐蚀有关。

任何提示?我究竟做错了什么?


编辑:我错过了控制台输出。这是确认这是一个堆腐蚀问题的消息:

  

HEAP:自由堆块44aa468在释放后在44aa4e8处被修改   application.exe已触发断点。

我遵循的文档来自MSDN article

2 个答案:

答案 0 :(得分:0)

不要返回1,在WM_SIZE消息中使用此return DefWindowProc(blah..)。在您完成调整大小指令后,Windows需要自行处理

答案 1 :(得分:0)

请勿在 WindowProc()

中实施调整大小代码

而不是这个,在渲染代码中实现它:

void Renderer::Render() const
{
    if (Resizingoccur) // In WindowProc() When the Resizing happen change the value of Resizingoccur to be true
        {
            Resize(nWidth, nHeight);
            Resizingoccur = false;
        }

    m_devContext->ClearRenderTargetView(m_renderTargetView, m_clearCol);
    HRESULT ret = m_swapchain->Present(0, 0); 
}