Как работать с пикселями, используя Direct2D - PullRequest
6 голосов
/ 26 января 2012

Может ли кто-нибудь привести пример эффективного способа работы с пикселями с использованием Direct2D?

Например, как я могу поменять все зеленые пиксели (RGB = 0x00FF00) на красные пиксели (RGB = 0xFF0000) на цели рендеринга? Каков стандартный подход? Можно ли для этого использовать ID2D1HwndRenderTarget? Здесь я предполагаю использовать какое-то аппаратное ускорение. Должен ли я создать другой объект для прямых пиксельных манипуляций?

Используя DirectDraw, я бы использовал BltFast метод на IDirectDrawSurface7 с логической операцией. Есть ли что-то похожее с Direct2D?

Другая задача состоит в том, чтобы динамически генерировать сложные изображения, где каждое местоположение точки и цвет являются результатом математической функции. Для примера давайте все упростим и нарисуем Y = X ^ 2. Как это сделать с Direct2D? В конечном счете мне нужно будет нарисовать сложные функции, но если бы кто-нибудь мог дать мне простой пример для Y = X ^ 2.

Ответы [ 3 ]

12 голосов
/ 22 февраля 2012

Во-первых, это помогает думать о ID2D1Bitmap как о «растровом изображении устройства». Он может находиться или не находиться в локальной памяти, адресуемой ЦП, и не дает вам удобного (или, по крайней мере, быстрого) способа чтения / записи пикселей со стороны ЦП шины. Так что подход с этой точки зрения, вероятно, неправильный подход.

Я думаю, что вам нужно обычное растровое изображение WIC, IWICBitmap, которое вы можете создать с помощью IWICImagingFactory :: CreateBitmap (). Оттуда вы можете вызвать Lock (), чтобы добраться до буфера, а затем читать / писать с помощью указателей и делать все, что вы хотите. Затем, когда вам нужно нарисовать его на экране с Direct2D, используйте ID2D1RenderTarget :: CreateBitmap (), чтобы создать новое растровое изображение устройства, или ID2D1Bitmap :: CopyFromMemory (), чтобы обновить растровое изображение существующего устройства. Вы также можете выполнить рендеринг в IWICBitmap, используя ID2D1Factory :: CreateWicBitmapRenderTarget () (без аппаратного ускорения).

Вы не получите аппаратное ускорение для этих типов операций. Обновленный Direct2D в Win8 (который также должен быть доступен для Win7 в конечном итоге) имеет некоторые изящные вещи для этого, но выглядит довольно сложно.

8 голосов
/ 06 марта 2014

В ответе Рика рассказывается о методах, которые вы можете использовать, если вам не важно потерять аппаратное ускорение. Я сосредотачиваюсь на том, как добиться этого, используя значительное ускорение графического процессора.

Чтобы ускорить работу вашего оборудования рендеринга и добиться максимальной производительности, вы захотите переключиться с ID2DHwndRenderTarget на использование более новых интерфейсов ID2DDevice и ID2DDeviceContext. Честно говоря, это не добавляет намного больше логики вашему коду, а преимущества производительности значительны. Он также работает в Windows 7 с обновлением платформы. Подводя итог процесса:

  1. Создание фабрики DXGI при создании фабрики D2D.
  2. Создание устройства D3D11 и устройства D2D для сопоставления.
  3. Создайте цепочку обмена, используя фабрику DXGI и устройство D3D.
  4. Попросите в цепочке подкачки задний буфер и оберните его в растровое изображение D2D.
  5. Рендеринг как и раньше, между вызовами BeginDraw () и EndDraw (). Не забудьте отсоединить задний буфер и уничтожить растровое изображение D2D, оборачивая его!
  6. Вызовите Present () в цепочке обмена, чтобы увидеть результаты.
  7. Повторите с 4.

Как только вы это сделаете, вы разблокировали несколько возможных решений. Вероятно, самый простой и эффективный способ решения вашей точной проблемы (замена цветовых каналов) - это использовать эффект цветовой матрицы в качестве одного из других упомянутых ответов. Важно понимать, что вам нужно использовать более новый интерфейс ID2DDeviceContext, а не ID2DHwndRenderTarget, чтобы получить это, однако. Есть много других эффектов, которые могут выполнять более сложные операции, если вы того пожелаете. Вот некоторые из наиболее полезных для простой манипуляции с пикселями:

Для общего решения проблемы манипулирования пикселями напрямую, без снижения аппаратного ускорения или тонны копирования, есть два варианта. Первый - написать пиксельный шейдер и обернуть его полностью настраиваемым D2D-эффектом. Это больше работы, чем просто получение пиксельного буфера на процессоре и выполнение старомодного битового затирания, но делать все это на GPU значительно быстрее. Инфраструктура эффектов D2D также упрощает повторное использование вашего эффекта для других целей, объединение его с другими эффектами и т. Д.

В тех случаях, когда вам абсолютно необходимо манипулировать пикселями процессора, но при этом все еще требуется значительная степень ускорения, вы можете управлять своими собственными отображаемыми текстурами D3D11. Например, вы можете использовать промежуточные текстуры, если хотите асинхронно манипулировать ресурсами текстуры из ЦП. Существует другой ответ , который более подробно описан. См. ID3D11Texture2D для получения дополнительной информации.

0 голосов
/ 28 августа 2013

Конкретную проблему замены всех зеленых пикселей на красные можно решить с помощью ID2D1Effect в Windows 8 и обновлении платформы для Windows 7.

В частности, Эффект цветовой матрицы.

...