Domanda

Ho un puntatore a un buffer COLORREF, qualcosa di simile: COLORREF* buf = new COLORREF[x*y];

Una subroutine riempie il buffer di colore-informazione. Ogni COLORREF rappresenta un pixel.

.

Ora voglio disegnare questo buffer per un contesto di periferica I miei attuali lavori approccio, ma è piuttosto lento (== ~ 200 ms per il disegno, a seconda delle dimensioni dell'immagine):

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

C'è un modo per fare questo più veloce; tutto in una volta, non un pixel dopo l'altro?
Io non sono molto familiare con la GDI. Ho sentito parlare al sacco di API come CreateDIBitmap (), BitBlt (), HBITMAP, CImage e tutta quella roba, ma non hanno alcuna idea di come applicarla. Sembra tutto abbastanza complicato ...
MFC è anche il benvenuto.

Tutte le idee?

Grazie in anticipo.

(Background:. La subroutine che ho citato sopra è un kernel OpenCL - la GPU calcola un'immagine di Mandelbrot e cassette di sicurezza nel buffer COLORREF)

Modifica
Grazie a tutti per i vostri suggerimenti. Le risposte (e collegamenti) mi ha dato una certa comprensione nella programmazione grafica di Windows. La performance è ora accettabile (semi-tempo reale a scorrimento nella Mandelbrot funziona :)
Ho finito con la soluzione seguente (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();

Quindi, in pratica CBitmap :: CreateBitmap () mi ha salvato da utilizzando l'API grezzo (che io ancora non pienamente capito). L'esempio nella documentazione di CDC :: CreateCompatibleDC era anche disponibile.
Il mio Mandelbrot è ora blu - usando SetPixelV () era rosso. Ma credo che abbia qualcosa a che fare con CBitmap :: CreateBitmap () interpretazione del mio tampone, non è veramente importante.

potrei provare il suggerimento OpenGL perché sarebbe stata la scelta più logica e ho voluto provare OpenCL sotto Linux in ogni caso.

È stato utile?

Soluzione

Date le circostanze, probabilmente sarei utilizzare una sezione DIB (che si crea con CreateDIBSection ). Una sezione DIB è un bitmap che consente di accedere ai contenuti direttamente come matrice, ma utilizzano ancora con tutte le normali funzioni GDI.

Credo che ti darà le migliori prestazioni di tutto ciò sulla base di GDI. Se avete bisogno di meglio, allora @Kornel è fondamentalmente corretto - è necessario passare a qualcosa che ha il supporto più diretto per l'accelerazione hardware (DirectX o OpenGL - anche se IMO, OpenGL è un molto meglio scelta per il lavoro di DirectX).

Dato che si sta facendo il calcolo in OpenCL e depositando l'output in un buffer di colore, OpenGL sarebbe il davvero scelta più ovvia. In particolare, si può avere OpenCL depositare l'output in una texture OpenGL, allora hai OpenGL disegnare un quad utilizzando tale consistenza. In alternativa, dal momento che si sta solo mettendo l'output sullo schermo in ogni caso, si può solo fare il calcolo in un frammento di shader OpenGL (o, naturalmente, un pixel shader DirectX), in modo da non mettere l'uscita nella memoria off-screen solo così è possibile copiare il risultato sullo schermo. Se la memoria non serve, il libro di Orange ha uno shader Mandelbrot come uno dei suoi esempi.

Altri suggerimenti

Sì, certo, che è lento. Si stanno facendo un round-viaggio attraverso il driver del kernel e video del dispositivo per ogni singolo pixel. Si rendono veloce disegnando a memoria, poi aggiornare lo schermo in un colpo solo. Questo richiede, per esempio, CreateDIBitmap, CreateCompatibleDC () e BitBlt ().

Questo non è un buon momento e il luogo per un ampio tutorial sulla grafica di programmazione. E 'ben coperto da qualsiasi testo introduttivo sulla GDI e / o la programmazione API di Windows. Tutto il necessario sapere che si può trovare in programmazione seminale di Petzold di Windows.

Dal momento che si dispone già di una matrice di pixel, è possibile utilizzare direttamente BitBlt per trasferirla a CC della finestra. Vedere questo link per un parziale esempio: http://msdn.microsoft.com/en-us/library/aa928058. aspx

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top