Нарисуйте один ID2D1Bitmap в нескольких ID2D1RenderTarget

Я работаю над приложением, которое отображает страницы документа (когда оно будет готово, оно будет выглядеть как на скриншоте ниже).
Главное окно имеет 2 подокна, каждое со своим ID2D1RenderTarget один для отображения миниатюр и один для основного вида. Когда документ загружается, ID2D1Bitmap создается для каждой страницы с использованием цели рендеринга в виде эскизов. Затем это растровое изображение преобразуется в общее растровое изображение с помощью функции CreateSharedBitmap той же цели рендеринга. Это общее растровое изображение может быть нарисовано на той же цели рендера, которая его создала.
Проблема в том, что когда я пытаюсь использовать тот же общий растровый рисунок для рисования на цели рендеринга основного представления, ничего не печатается (даже другие объекты) и EndDraw возвращает -2003238891.
Если я использую цель рендеринга основного представления для создания растрового изображения, оно отображается правильно в основном представлении, а не в представлении миниатюр (EndDraw возвращает тот же код ошибки).

Кто-нибудь знает, как я могу преодолеть эту проблему?

Спасибо Сэм

Скриншот того, как должно выглядеть приложение после его завершения

2 ответа

HRESULT час, час — длинное целое число.

если (НЕУДАЧА(час))...

строка WCHAR[20]; swprintf(строка, 20, "%x", час); MessageBox(NULL, строка, NULL, MB_OK);

Это должно помочь в качестве первого шага для декодирования ошибок hresult.

Общее растровое изображение не очень хорошо задокументировано, но вот одно преимущество, которое я обнаружил.

Когда вы создаете общее растровое изображение из растрового изображения WIC, вы можете в основном отображать растровое изображение wic с помощью render_tgt->DrawBitmap(...) без необходимости сначала копировать пиксели в растровое изображение. Кстати, растровое изображение WIC и интерфейс wic_lock позволяют напрямую обращаться к пикселям.

До сих пор я не видел никакого способа работать в обратном направлении и создавать цель рендеринга из растрового изображения, общего растрового изображения или памяти. Даже метод CreateBitmapFromMemory просто копирует данные в растровое изображение d2d, и любые обновления растрового изображения d2d не влияют на память, из которой оно было создано. Для создания общего растрового изображения ваша цель рендеринга должна быть типа программного обеспечения. Direct 3D не поддерживает программные цели рендеринга Direct 2D. Не сдавайся. Возможно, найдется какой-нибудь гуру, который сможет выяснить, сможет ли QueryInterface разблокировать некоторые волшебные скрытые полезные функции из общего растрового изображения d2d.

Использование программного обеспечения: Создайте растровое изображение WIC на «дочернем» устройстве. Создайте цель D2D Render из растрового изображения WIC. Создавайте совместно используемое растровое изображение из главного окна каждый раз, когда вам нужно отобразить растровое изображение, а затем немедленно отпустите его. Примечания. Свойства растрового изображения должны быть совместимы между целями рендеринга и растровым изображением wic и общим растровым
изображением.

Таким образом, растровое изображение WIC является вашим якорем. Это было бы обходным путем для использования общей памяти.

Поддерживать использование оборудования: дочерний элемент -> копировать биты растрового изображения в память 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;
}

Ошибка D2DERR_WRONG_RESOURCE_DOMAIN0x88990015 "Используемый ресурс был создан целью рендеринга в другом домене ресурсов".

Описание должно быть довольно точным: вы поставили в очередь операцию с несовместимым ресурсом в качестве аргумента, однако, поскольку выполнение асинхронно, вы только в EndDraw,

Возможные причины

Это сообщение появляется, когда приложение пытается выполнить операцию рисования, которая смешивает ресурсы из разных доменов ресурсов. Например, контексты устройства, кисти и растровые изображения зависят от устройства. При выполнении операции, такой как ID2D1DeviceContext::DrawBitmap, битовая карта аргумента должна принадлежать тому же домену ресурса, что и контекст устройства. В этом примере способ обеспечить это - создать растровое изображение, используя функцию-член CreateBitmap этого контекста устройства, а не функцию какого-либо другого контекста устройства.

Возможные исправления

Когда группы ресурсов должны использоваться вместе, убедитесь, что они созданы из одного ID2D1Device. Нецелевые ресурсы, созданные непосредственно из ID2D1Factory, такие как блоки состояний и геометрии, считаются независимыми от устройства и не имеют этого ограничения.

Смотрите также:

Другие вопросы по тегам