2013-02-14 3 views
1

Я борюсь за решение этой проблемы; используя D3D11.1 и стандартное окно рабочего стола Win32, я получаю ошибки в памяти при изменении размера моего окна, но только при изменении размера вручную в течение нескольких секунд. Максимизация работает отлично, а изменение размеров очень быстро отлично работает. Как будто что-то постоянно выделяется во время ручного изменения размера, но я не могу понять, что это такое.D3D11.1 Запуск памяти при изменении размера окна?

LRESULT CALLBACK ProcessWindow(HWND hWnd, uint32 nMessage, WPARAM wParam, LPARAM lParam) 
{ 
switch(nMessage) 
{ 
case WM_SIZE: 
    OnResize(); 
    return DefWindowProc(hWnd, nMessage, wParam, lParam); 
} 

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



void OnResize() 
{ 
    ResizeSwapChain(); 
    ResetRenderTargets(); 
    ResetDepthStencil(); 
} 



void ResizeSwapChain() 
{ 
if(m_pD3DSwapChain) 
{ 
    m_D3DDepthStencilView.ReleaseAndGetAddressOf(); 
    m_pD3DRenderTarget.ReleaseAndGetAddressOf(); 

    //THE SWAP CHAIN ALREADY EXISTS, RESIZE IT 
    DXErrorOnFail(m_pD3DSwapChain->ResizeBuffers(nBufferCount, 0, 0, SwapChainFormat, 0)); 
} 
} 



bool ResetRenderTargets() 
{ 
ComPtr<ID3D11Texture2D> B; 
DXErrorOnFail(m_pD3DSwapChain->GetBuffer(0, IID_PPV_ARGS(&B))); 

DXErrorOnFail(m_pD3DDevice->CreateRenderTargetView(B.Get(), nullptr, &m_pD3DRenderTarget)); 

B.ReleaseAndGetAddressOf(); 

if(!m_pD3DRenderTarget) 
{ 
    return false; 
} 

return true; 
} 



bool ResetDepthStencil() 
{ 
D3D11_TEXTURE2D_DESC BBD; 

ComPtr<ID3D11Texture2D> B; 
DXErrorOnFail(m_pD3DSwapChain->GetBuffer(0, IID_PPV_ARGS(&B))); 

B->GetDesc(&BBD); 

D3D11_TEXTURE2D_DESC DSD; //DEPTH STENCIL DESC 
memset(&DSD, 0, sizeof(D3D11_TEXTURE2D_DESC)); 

DSD.Width    = BBD.Width; 
DSD.Height    = BBD.Height; 
DSD.MipLevels   = 1; 
DSD.ArraySize   = 1; 
DSD.Format    = DXGI_FORMAT_D24_UNORM_S8_UINT; 
DSD.SampleDesc.Count = 1; 
DSD.SampleDesc.Quality = 0; 
DSD.Usage    = D3D11_USAGE_DEFAULT; 
DSD.BindFlags   = D3D11_BIND_DEPTH_STENCIL; 
DSD.CPUAccessFlags  = 0; 
DSD.MiscFlags   = 0; 

ComPtr<ID3D11Texture2D> DS; 
DXErrorOnFail(m_pD3DDevice->CreateTexture2D(&DSD, nullptr, &DS)); 

D3D11_DEPTH_STENCIL_VIEW_DESC DVD; 
memset(&DVD, 0, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC)); 

DVD.Format    = DSD.Format; 
DVD.ViewDimension  = D3D11_DSV_DIMENSION_TEXTURE2D; 
DVD.Flags    = 0; 
DVD.Texture2D.MipSlice = 0; 

DXErrorOnFail(m_pD3DDevice->CreateDepthStencilView(DS.Get(), &DVD, &m_D3DDepthStencilView)); 

B.ReleaseAndGetAddressOf(); 
DS.ReleaseAndGetAddressOf(); 

if(!m_D3DDepthStencilView) 
{ 
    return false; 
} 

return true; 
} 


bool ResetViewports() 
{ 
D3D11_TEXTURE2D_DESC BBD; //BACK BUFFER DESC 
memset(&BBD, 0, sizeof(D3D11_TEXTURE2D_DESC)); 

ComPtr<ID3D11Texture2D> B; 
DXErrorOnFail(m_pD3DSwapChain->GetBuffer(0, IID_PPV_ARGS(&B))); 

B->GetDesc(&BBD); 

D3D11_VIEWPORT V; 
V.TopLeftX = 0.0f; 
V.TopLeftY = 0.0f; 
V.Width = static_cast<float32>(BBD.Width); 
V.Height = static_cast<float32>(BBD.Height); 
V.MinDepth = D3D11_MIN_DEPTH; 
V.MaxDepth = D3D11_MAX_DEPTH; 

m_pD3DDeviceContext->RSSetViewports(1, &V); 

return true; 
} 

Я по-настоящему ценю любую помощь в этом, спасибо.

ответ

0

Перераспределение при изменении размера не является хорошей идеей для нескольких причин:

  • Ты собираешься уничтожить и воссоздать Ресурсы ЛО (и в данном случае это простой пример, подумайте о сложном приложение с большим количеством промежуточных текстур).
  • DX не уничтожает ресурсы сразу же, когда вы вызываете ReleaseAndGetAddressOf, он будет делать это при следующем сбросе буфера, так как при изменении размера вы, вероятно, не будете визуализировать, контекст не будет очищен.

Одним из более чистых решений является использование событий Begin/EndResize. WM_ENTERSIZEMOVE WM_EXITSIZEMOVE

Установите флаг на введите сообщение, и применить изменения на выходе.