我正在学习如何使用Direct2D和DirectWrite。我编写了一个示例应用程序,它使用这些库直接在主(顶级)窗口中呈现内容。它工作正常。
现在我正在尝试在另一个应用程序中重写子窗口的绘制代码。原始代码使用GDI并且工作正常。但当我将其转换为使用Direct2D时,根本没有任何内容(子窗口显示为黑色)。
我已将绘画代码简化为客户区的简单填充。
LRESULT PlotWnd::OnPaint(UINT, WPARAM, LPARAM, BOOL &) {
ATL::CComPtr<ID2D1Factory> pD2DFactory;
HRESULT hr = ::D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory);
assert(SUCCEEDED(hr));
ATL::CComPtr<ID2D1HwndRenderTarget> pRT;
RECT rc;
GetClientRect(&rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
hr = pD2DFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(/* D2D1_RENDER_TARGET_TYPE_SOFTWARE */),
D2D1::HwndRenderTargetProperties(m_hWnd, size), &pRT);
assert(SUCCEEDED(hr));
pRT->BeginDraw();
pRT->Clear(D2D1::ColorF(D2D1::ColorF::Beige));
hr = pRT->EndDraw();
assert(SUCCEEDED(hr));
ValidateRect(nullptr);
return 0;
}
所有Direct2D调用都以S_OK
成功,所以我对在哪里寻找问题感到茫然。在这一点上,我在工作实验和这个程序之间可以看到的唯一显着差异是,在这一个中,我只在一个子窗口中使用Direct2D。
所以我的问题是:在子窗口中使用Direct2D时是否存在我遗漏的问题?有关进一步调试的提示吗?
更新:我已删除静态以避免混淆。我正在使用每种颜料完全设置并拆除Direct2D。只有一个油漆调用,具有实际大小。
如果我切换到软件渲染(在渲染目标属性中使用D2D1_RENDER_TARGET_TYPE_SOFTWARE
),问题就会消失 - 我按预期得到米色填充。
这让我怀疑我的图形驱动程序已经过时了。但我现在已经更新了我的图形驱动程序,它仍然以同样的方式失败。当软件渲染按预期工作时,还有什么可能导致硬件渲染失败?
更新2 :我仍在尝试重现这是一个小型,自包含的示例。与此同时,我注意到只需启动Spy ++就会有时导致窗口实际渲染到屏幕上(一次)。
答案 0 :(得分:2)
嗯,对于初学者,你应该在应用程序启动时创建工厂,并使用窗口(HWND)创建渲染目标。这些不应该是“临时”对象,只有在您的OnPaint(WM_PAINT)正在执行时才会存在。
答案 1 :(得分:0)
除了Rick建议将HWNDRenderTarget转换为永久对象之外,我建议调用BeginPaint()
- EndPaint()
(或者创建一个自动执行的CPaintDC
对象),即使你没有不要使用PAINTSTRUCT
。请参阅MainWindow::OnPaint
here。
如果这没有帮助,您可以随时启用Direct2D Debug Layer以获取更多调试信息。
答案 2 :(得分:0)
除了使用软件渲染之外,我还没有其他解决方案。我相当肯定它是一个图形驱动程序错误,特别是竞争条件。
证据:
反证据:
我将此作为&#34;回答&#34;因为其他一些人已经看到类似的症状,并问我是否找到了答案。我仍然愿意阅读其他想法,并会提出好的答案。