Вопрос

У меня есть указатель на буфер Colorref, что-то вроде: COLORREF* buf = new COLORREF[x*y];

Подпрограмма заполняет этот буфер с цветной информацией. Каждый Colorref представляет собой один пиксель.

Теперь я хочу нарисовать этот буфер в контекст устройства. Мой текущий подход работает, но довольно медленно (== ~ 200 мс на рисунок, в зависимости от размера изображения):

for (size_t i = 0; i < pixelpos; ++i) 
{
    // Get X and Y coordinates from 1-dimensional buffer.
    size_t y = i / wnd_size.cx;
    size_t x = i % wnd_size.cx;
    ::SetPixelV(hDC, x, y, buf[i]);
}

Есть ли способ сделать это быстрее; Все сразу, а не один пиксель за другим?
Я не очень знаком с GDI. Я слышал о многих API APIS, таких как ProsessibitMap (), Bitblt (), HBitMap, CImage и все это, но понятия не имею, как это применить. Кажется, все довольно сложно ...
MFC также приветствуется.

Есть идеи?

Заранее спасибо.

(Фон: Подпрограмма, которую я упомянул выше, является ядром OpenCL - GPU рассчитывает изображение Mandelbrot и сохраняет его в буфере Colorref.)

РЕДАКТИРОВАТЬ:
Спасибо всем за ваши предложения. Ответы (и ссылки) дали мне некоторое представление о программировании графики Windows. Выступление сейчас приемлемо (полуаревно, прокрутка в Mandelbrot Works :)
Я оказался следующим решением (MFC):

...
CDC dcMemory;
dcMemory.CreateCompatibleDC(pDC);

CBitmap mandelbrotBmp;
mandelbrotBmp.CreateBitmap(clientRect.Width(), clientRect.Height(), 1, 32, buf);

CBitmap* oldBmp = dcMemory.SelectObject(&mandelbrotBmp);
pDC->BitBlt(0, 0, clientRect.Width(), clientRect.Height(), &dcMemory, 0, 0, SRCCOPY);

dcMemory.SelectObject(oldBmp);
mandelbrotBmp.DeleteObject();

Таким образом, в основном CBitMap :: CreateBitMap () сохранил меня от использования RAW API (что я до сих пор не понимаю). Пример в документации CDC :: CreateCompatibleDC. Также было полезно.
Мой Мандельброт теперь синий - используя setpixelv () Это было красным. Но я думаю, что имеет отношение к CBitMap :: Createbitmap () Интерпретация моего буфера, не очень важно.

Я мог бы попробовать предложение OpenGL, потому что это было бы гораздо более логичным выбором, и я хотел бы попробовать OpenCL под Linux в любом случае.

Это было полезно?

Решение

В этих обстоятельствах я бы, вероятно, использовал раздел Dib (который вы создаете с CreateDIBSection). Раздел DIB - это растровое изображение, которое позволяет получить доступ к содержимому непосредственно как массив, но все же использовать его со всеми обычными функциями GDI.

Я думаю, что это даст вам лучшие результаты чего-либо на основе GDI. Если вам нужна лучше, то @kornel в основном правильно - вам нужно переключиться на то, что имеет более непосредственную поддержку аппаратного ускорения (DirectX или OpenGL - хотя IMO, OpenGL - гораздо лучший выбор для работы, чем DirectX).

Учитывая, что вы в настоящее время выполняете расчет в OpenCL и нанесение вывода в цветовом буфере, OpenGL будет В самом деле очевидный выбор. В частности, вы можете заложить OpenCL вносить выходные данные в текстуре OpenGL, то у вас OpenGL нарисуйте квадроцикл, используя эту текстуру. В качестве альтернативы, поскольку в любом случае вы просто помещаете вывод на экран, вы могли бы просто сделать расчет в шейдере фрагмента OpenGL (или, конечно же, DirectX Pixel Shader), поэтому вы не будете помещать вывод в память на экране Также вы можете скопировать результат на экран. Если память служит, оранжевая книга имеет шейдер Mandelbrot как один из его примеров.

Другие советы

Да, конечно, это медленно. Вы делаете круговую поездку через драйвер ядра и видео устройства для каждого отдельного пикселя. Вы делаете это быстро, рисуя в память сначала, затем обновите экран в одном падении. Требуется, скажем, созданиеBITMAP, CreateCompatibleDC () и Bitblt ().

Это не хорошее время и место для обширного учебника по графическим программированию. Он хорошо покрывается любым вводным текстом на программировании GDI и / или Windows API. Все, что вам нужно знать, вы можете найти в Windows Windows Petzzold Windows.

Поскольку у вас уже есть массив пикселей, вы можете напрямую использовать BitBLT, чтобы перенести его в DC окна. Смотрите эту ссылку для частичного примера:http://msdn.microsoft.com/en-us/library/aaa928058.aspx.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top