Heisenbug
Heisenbug

Reputation: 39164

Swapping render buffers after resizing window causes problems

I'm trying to handle window resize message WM_SIZE. When I receive it:

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);
}

I use new height and width parameters to recreate render target viewport and resize the buffers:

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);

}

Despite that, the first frame rendered after the resize event cause an error:

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 popup error is:

ApplicationName.exe has triggered an exception

. No other info, nor catchable exceptions. From some research on the web I guess it could be related to some not released resource or heap corruction.

Any hint? What am I doing wrong?


Edit: I was missing the console output. Here's the message confirming that's an heap corruction problem:

HEAP: Free Heap block 44aa468 modified at 44aa4e8 after it was freed application.exe has triggered a breakpoint.

The documentation I followed is from this MSDN article.

Upvotes: 1

Views: 815

Answers (2)

Tarta Rikker
Tarta Rikker

Reputation: 91

Do not implement the Resizing code in WindowProc()

instead of this, implement it in the Rendering code :

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); 
}

Upvotes: 0

Sly_TheKing
Sly_TheKing

Reputation: 528

don't return 1, use this return DefWindowProc(blah..) in your WM_SIZE message. After you've done your resize instructions, windows needs to handle it itself

Upvotes: 1

Related Questions