【发布时间】:2015-03-06 15:34:01
【问题描述】:
我正在尝试处理窗口大小调整消息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: Free Heap block 44aa468 在被释放后修改为 44aa4e8 application.exe 已触发断点。
我遵循的文档来自MSDN article。
【问题讨论】:
-
你在使用first-chance exceptions吗?这些通常是良性的。
-
@MooseBoys: 不..似乎我在某处搞砸了堆..仍然不知道在哪里,但这与调整窗口大小有关。
-
在黑暗中射击:检查
pBuffer的引用计数(打印Release()调用的结果)?如果这是问题所在,我不知道为什么;需要对 DirectX一无所知的人来回答。 -
你在
m_swapchain->ResizeBuffer()通话后检查过小时吗?是S_OK吗? -
同样在每个
hr = somefunction()之后放入代码if(FAILED(hr)){return 1;}在directx 中不检查directx 函数的返回值是错误的方法,代码可能在任何地方都失败,你不知道在哪里
标签: c++ winapi directx directx-11