Pregunta

Tengo un puntero a un buffer COLORREF, algo así como: COLORREF* buf = new COLORREF[x*y];

Una subrutina llena este tampón con el color en la información. Cada COLORREF representa un píxel.

.

Ahora quiero llamar su buffer para un contexto de dispositivo Mis obras enfoque actual, pero es bastante lento (== ~ 200 ms por cada dibujo, dependiendo del tamaño de la imagen):

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]);
}

¿Hay una manera de hacerlo más rápido; todos a la vez, no un píxel tras otro?
No estoy muy familiarizado con el IDG. He oído acerca mucho al de APIs como CreateDIBitmap (), BitBlt (), HBITMAP, CImage y todas esas cosas, pero no tienen idea de cómo aplicarlo. Parece todo bastante complicado ...
MFC es también agradable.

¿Alguna idea?

Gracias de antemano.

(Antecedentes:. La subrutina he mencionado anteriormente es un kernel OpenCL - la GPU calcula una imagen Mandelbrot y cajas fuertes en el buffer COLORREF)

EDIT:
Gracias a todos por sus sugerencias. Las respuestas (y enlaces) me dio una idea de la programación de gráficos de Windows. El rendimiento es ahora aceptable (semi-tiempo real de desplazamiento en el Mandelbrot funciona :)
Terminé con la siguiente solución (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();

Así que, básicamente CBitmap :: CreateBitmap () me salvó de uso de la API prima (que todavía no entienden completamente). El ejemplo en la documentación de CDC :: CreateCompatibleDC también fue útil.
Mi Mandelbrot es ahora azul - usando SetPixelV () fue rojo. Pero supongo que eso tiene algo que ver con CBitmap :: CreateBitmap () la interpretación de mi memoria intermedia, no es realmente importante.

probaría la sugerencia de OpenGL, ya que habría sido la elección más lógica y quería probar OpenCL bajo Linux de todos modos.

¿Fue útil?

Solución

Bajo las circunstancias, probablemente use una sección DIB (que se crea con la CreateDIBSection ). Una sección de DIB es un mapa de bits que le permite acceder a los contenidos directamente como una matriz, pero todavía lo utilizan con todas las funciones GDI habituales.

creo que te dará el mejor rendimiento de cualquier cosa basada en GDI. Si necesita mejor, entonces @Kornel es básicamente correcto - se necesita para cambiar a algo que tiene un apoyo más directo para la aceleración de hardware (DirectX o OpenGL - a pesar de la OMI, OpenGL es una mucho mejor opción para el trabajo de DirectX).

Teniendo en cuenta que actualmente está haciendo el cálculo en OpenCL y depositando la salida en un buffer de color, OpenGL sería el realmente opción obvia. En particular, puede tener OpenCL depositar el producto en una textura de OpenGL, entonces usted tiene OpenGL dibujar un quad utilizando esa textura. Como alternativa, ya que sólo estás poniendo la salida en la pantalla de todos modos, sólo podía hacer el cálculo en un fragmento de sombreado OpenGL (o, por supuesto, un pixel shader DirectX), por lo que no pondría la salida en la memoria fuera de la pantalla sólo para que pueda copiar el resultado en la pantalla. Si falla la memoria, el libro de Orange tiene un shader de Mandelbrot como uno de sus ejemplos.

Otros consejos

Sí, claro, que es lento. Usted está haciendo una ida y vuelta a través del controlador del núcleo y el vídeo de dispositivo para cada píxel individual. Lo haces rápido mediante la elaboración de la memoria en primer lugar, a continuación, actualice la pantalla de un solo golpe. Para eso se necesita, por ejemplo, CreateDIBitmap, CreateCompatibleDC () y BitBlt ().

Esto no es un buen momento y lugar para un extenso tutorial sobre programación gráfica. Es bien cubierta por ningún texto de introducción a la GDI y / o programación API de Windows. Todo lo que necesita saber que se puede encontrar en la programación seminal de Petzold de Windows.

Como usted ya tiene una matriz de píxeles, se puede utilizar directamente BitBlt para transferirlo a la CC de la ventana. Vea este enlace para un ejemplo parcial: http://msdn.microsoft.com/en-us/library/aa928058. aspx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top