Рисовать на HDC с выделенной пользователем памятью - PullRequest
2 голосов
/ 30 октября 2010

У меня есть объект IViewObject без окон.

Я хочу вызвать функцию Draw для рендеринга в память Opengl PBO (в качестве альтернативы OleDraw проще).

Прямо сейчас я сначала создаю HBITMAP, используя CreateDIBSection (который выделяет свою собственную память), а затем копирую его в мою память PBO. Тем не менее, я хотел бы избежать этой дополнительной копии. Я полагаю, что это должно быть возможно теоретически, поскольку отображенные PBOs живут в памяти с блокировкой страницы.

Это то, что я сегодня делаю упрощенно:

hdc = CreateCompatibleDC(nullptr); // Get current DC
HBITMAP bitmap = CreateDIBSection(... hdc, &bitmap_data_...); // Create Bitmap
SelectObject(hdc, bitmap);
m_spViewObject->Draw(... hdc ...); // IViewObject->Draw to bitmap
memcpy(pbo_ptr, bitmap_data_, size);

У меня вопрос: возможно ли использовать функцию Draw для рисования в памяти, которую я указал (в данном случае PBO) вместо памяти, выделенной API-интерфейсом win32 (CreateDIBSection)?

Один из способов может быть, если возможно создать независимое от устройства растровое изображение из указанной пользователем памяти? Однако я не нашел ни одной функции, которая делает это.

1 Ответ

4 голосов
/ 30 октября 2010

То, что вы пытаетесь сделать, очень логично, ИМХО. Однако, к сожалению, AFAIK, нет обычного способа сделать это.

В соответствии с разделами WinAPI DIB либо выделяйте собственную память, либо работайте с сопоставлением файлов. OTOH OpenGL управляет своей памятью по-своему. Существует возможность создать DIB из любого блока памяти, но это только для видеодрайверов, недоступных для приложений пользовательского режима.

На самом деле существует очень сложная возможность избежать этой дополнительной копии. Вы можете создать виртуальный видеодрайвер (не путать с зеркальным видеодрайвером), получить его HDC. Затем, по своему «обычному» способу, сообщите ему, где он должен рисовать (через Escape). И затем вы можете передать это HDC тому, что вы хотите сделать, ваш виртуальный видеодрайвер будет рисовать прямо в памяти, которую вы хотите.

Кроме того, для выполнения реального рисования вы сможете использовать функции ОС. Оберните свою память GDI-распознаваемым растровым изображением (EngCreateBitmap) и используйте его в операционной системе (EngXXXX), чтобы вам пришлось реализовывать только минимальную функциональность в вашем драйвере.

Однако, в любом случае, это разработка драйверов. Я считаю, что копирование блока памяти происходит достаточно быстро (по сравнению с реальным рисунком), поэтому вы можете оставить свой код как есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...