在多个ID2D1RenderTarget

时间:2016-06-16 19:58:27

标签: c++ direct2d

我正在开发一个显示文档页面的应用程序(当它完成时,它将看起来像下面的截图)。
主窗口有2个子窗口,每个窗口都有自己的ID2D1RenderTarget一个用于显示缩略图,一个用于主视图。加载文档时,使用缩略图视图的渲染目标为每个页面创建ID2D1Bitmap。然后使用相同渲染目标的CreateSharedBitmap函数将该位图转换为共享位图。可以在创建它的同一渲染目标上绘制此共享位图 问题是当我尝试使用相同的共享位图在主视图的渲染目标上绘制时,不打印任何内容(甚至不打印其他对象),EndDraw返回-2003238891。 如果我使用主视图的渲染目标来创建位图,它会在主视图上正确绘制而不在缩略图视图上绘制( EndDraw 会返回相同的错误代码)点。

任何人都知道如何克服这个问题?

谢谢 萨姆

Screenshot of what the application should look like when it is finished

2 个答案:

答案 0 :(得分:0)

错误是D2DERR_WRONG_RESOURCE_DOMAIN 0x88990015"使用的资源是由不同资源域中的渲染目标创建的。"

描述应该非常准确:您使用不兼容的资源将操作排队作为参数,但由于执行是异步的,因此只有EndDraw中的失败。

  

Possible Causes

     

当应用程序尝试混合来自不同资源域的资源的绘图操作时,会出现此消息。例如,设备上下文,画笔和位图是特定于设备的。在执行ID2D1DeviceContext :: DrawBitmap等操作时,参数位图应与设备上下文属于同一资源域。在此示例中,确保这一点的方法是使用该设备上下文的CreateBitmap成员函数创建位图,而不是使用其他设备上下文创建位图。

     

可能的修复

     

当应该一起使用资源组时,请确保它们是从同一ID2D1Device创建的。直接从ID2D1Factory创建的非目标资源,例如状态块和几何,并且被视为与设备无关,并且没有此限制。

另见:

答案 1 :(得分:0)

HRESULT hr,hr 是一个长整数。

如果(失败(小时))...

WCHAR 字符串[20]; swprintf(string, 20, "%x", hr); MessageBox(NULL, string, NULL, MB_OK);

这应该有助于作为解码 hresult 错误的第一步。

共享位图没有被很好地记录下来,但这是我发现的一个优点。

当你从 WIC 位图创建共享位图时,你基本上可以通过使用 render_tgt->DrawBitmap(...) 来显示 wic 位图,而无需先将像素复制到位图。附带说明一下,WIC 位图和 wic_lock 接口允许您直接寻址像素。

到目前为止,我还没有看到任何反向工作并从位图或共享位图或内存创建渲染目标的方法。即使 CreateBitmapFromMemory 方法只是将数据复制到 d2d 位图,对 d2d 位图的任何更新都不会影响创建它的内存。要创建共享位图,您的渲染目标必须是软件类型。 Direct 3D 不支持 Direct 2D 软件渲染目标。不要放弃。可能有一些大师可以弄清楚 QueryInterface 是否会从共享的 d2d 位图中解锁一些神奇的隐藏有用功能。

软件使用: 在“子”上创建 WIC 位图 从 WIC 位图创建 D2D 渲染目标 每次需要显示位图时,从主窗口创建一个共享位图,然后立即释放它。 注意:位图属性必须在渲染目标和 wic 位图和共享位图之间兼容
注意:当 wic 锁或共享位图处于活动状态时,您不能使用 wic-d2d-render-target。

这样,WIC 位图就是您的锚点。这将是使用共享内存的一种解决方法。

维护硬件使用: child -> 将位图位复制到内存 main -> 将内存复制到主窗口创建的位图中。 无论哪种方式,位图属性(例如 bppp、顺序或字节等)必须在子窗口和主窗口的渲染目标之间兼容

HRESULT XMAIN::Create_HWnd_Tgt(ID2D1HwndRenderTarget **hwnd_tgt, HWND hwnd, bool makebmp)
{
if (hwnd == NULL) { return E_POINTER; }
if (hwnd_tgt == NULL) { return E_POINTER; }

if (demo.d2d.factory == NULL) { return E_FAIL; }

HRESULT hr = S_OK;

RECT rc = { 0 };

SafeRelease(hwnd_tgt);

GetClientRect(hwnd, &rc);

D2D1_RENDER_TARGET_PROPERTIES rt_props = D2D1::RenderTargetProperties();

D2D1_SIZE_U size = D2D1::SizeU((rc.right - rc.left), (rc.bottom - rc.top));

//This is required when using a wic shared bitmap
rt_props.type = D2D1_RENDER_TARGET_TYPE_SOFTWARE;

rt_props.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM;
rt_props.pixelFormat.alphaMode = D2D1_ALPHA_MODE_IGNORE;
rt_props.dpiX = 0;
rt_props.dpiY = 0;
rt_props.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
rt_props.minLevel = D2D1_FEATURE_LEVEL_9;//D2D1_FEATURE_LEVEL_DEFAULT;

// Create a Direct2D render target.

hr = demo.d2d.factory->CreateHwndRenderTarget(
    rt_props,
    D2D1::HwndRenderTargetProperties(hwnd, size),
    hwnd_tgt
);

if ((*hwnd_tgt) == NULL) {}

return hr;
}