2010-02-17 2 views
2

Я хотел бы использовать OpenGL для рисования непосредственно в .NET System :: Drawing :: Bitmap (C++/CLI). Похоже, что он должен работать так:Использование OpenGL для прямого рисования .NET Bitmap

char buf[48]; 
ZeroMemory(&buf, sizeof(buf)); 
System::Drawing::Bitmap bmp(
    4, 
    4, 
    12, 
    Imaging::PixelFormat::Format24bppRgb, 
    (System::IntPtr)buf); 
Graphics^ g = Graphics::FromImage(%bmp); 
HDC local_hdc = (HDC)((void*)g->GetHdc()); 
HGLRC local_hrc = wglCreateContext(local_hdc); 
if(!wglMakeCurrent(local_hdc, local_hrc)) 
    ShowError(); 

//Draw something with OpenGL ... 

g->ReleaseHdc((IntPtr)((void*)local_hdc)); 

//Do something with the bitmap ... 

Но wglMakeCurrent терпит неудачу с «Формат пикселей недействителен».

«Конечно!» Я думаю. «Мне просто нужно установить формат пикселей растрового изображения таким образом, чтобы OpenGL мог его отображать!»

К сожалению, если я использую вышеуказанный конструктор Bitmap, я ограничусь перечислением консервированных пиксельных форматов, а не структурой, содержащей кучу атрибутов, с которыми я могу ИЛИ вместе. И я не думаю, что можно установить формат пикселей после факта.

В любом случае, этот способ делать вещи был бы красивее, чем использование множества вызовов Win32 для создания независимого от устройства растрового изображения, но консервированные пиксельные форматы, похоже, ничего не скрывают, и я просто терпит неудачу. Можете ли вы добиться успеха?

ответ

3

Вы, вероятно, не хотите рисовать прямо в свой буфер, вы потеряете все аппаратное ускорение, которое является преимуществом OpenGL для начала. Вместо этого:

  • Настройка контекста OpenGL, как обычно, с использованием видеопамяти.
  • Втянуть в него, полностью ускорился.
  • Создать растровое изображение.
  • Call Bitmap :: LockBits, чтобы получить указатель на необработанную память пикселей.
  • Используйте glCopyImage для чтения результатов из видео-RAM в растровое изображение.

PixelFormat перешел на LockBits, а glCopyImage в последние два шага должен совпадать, конечно.

+0

А, но я хочу рисовать прямо в свой растровый буфер! Это потому, что я пытаюсь получить растровое изображение, готовое отправить на принтер. Это означает, что мне нужно только один раз рисовать, так что скорость не является большой проблемой, и если я могу рисовать непосредственно в буфер, я не дублирую по-настоящему большое растровое изображение в памяти. –

+1

Метод, который я предложил, не будет использовать дополнительную системную ОЗУ, только видеопамять. Насколько велика эта растровая карта? Я предполагаю, что если вы пытаетесь отобразить 8.5 "x11" при 1200 dpi (это 400 Мбайт), это может не соответствовать видеопамяти, но ... Я не знаю, поддерживает ли OpenGL поверхность рендеринга, которая является большой. Почему вы хотите OpenGL для этого? 3-D рендеринг? Много текстурированных квадрациклов? Повторное использование существующих процедур рендеринга, которые уже необходимы для отображения экрана? –

+0

Хм, извините, что это подвешивает, например, когда-либо. Изображение, вероятно, будет таким большим и большим для больших размеров бумаги. Я хочу использовать OpenGL для этого, потому что я использую OpenGL для визуализации представления на экране, и распечатка должна соответствовать экрану как можно точнее ... только с более высоким разрешением. Поэтому в основном, что я хочу сделать, это когда пользователь говорит «print», я хочу рисовать один раз, непосредственно в буфер растрового образа .NET (по крайней мере, в моем .NET-клиенте), который затем может быть легко отправлен на принтер. –

Смежные вопросы