Frage

Ich habe einen Zeiger auf einen COLORREF Puffer, so etwas wie: COLORREF* buf = new COLORREF[x*y];

Ein Unterprogramm füllt diesen Puffer mit Farbinformationen. Jeder COLORREF repräsentiert ein Pixel.

.

Jetzt habe ich diesen Puffer zu einem Gerätekontext zeichnen möge Mein aktueller Ansatz funktioniert, aber ist ziemlich langsam (== ~ 200 ms pro Zeichnung, abhängig von der Größe des Bildes):

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

Gibt es eine Möglichkeit, dies schneller zu tun; alle auf einmal, nicht ein Pixel nach dem anderen?
Ich bin nicht wirklich vertraut mit der GDI. Ich hörte von al viele APIs wie CreateDIBitmap (), BitBlt (), HBITMAP, CImage und all das Zeug, aber keine Ahnung, wie sie anzuwenden. Es scheint alles ziemlich kompliziert ...
MFC ist auch willkommen.

Irgendwelche Ideen?

Vielen Dank im Voraus.

(Hintergrund:. Das Unterprogramm die ich oben erwähnt ist ein OpenCL-Kernel - die GPU berechnet eine Mandelbrot Bild und Safe in dem COLORREF Puffer)

EDIT:
Vielen Dank für Ihre Anregungen. Die Antworten (und Links) gab mir einen Einblick in die Windows-Grafikprogrammierung. Die Leistung ist jetzt akzeptabel (semi-Echtzeit-Scrolling in das Mandelbrot funktioniert :)
Ich landete mit der folgenden Lösung (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();

Also im Grunde CBitmap :: Create () rettete mich aus der rohen API (die ich noch nicht ganz verstanden). Das Beispiel in der Dokumentation von CDC :: CreateCompatibleDC war auch hilfreich.
Mein Mandelbrot ist jetzt blau - mit SetPixelV () es rot wurde. Aber ich denke, dass etwas mit CBitmap :: Create () Interpretieren meinen Puffers zu tun, nicht wirklich wichtig.

Ich könnte den OpenGL-Vorschlag versuchen, weil es die viel mehr logische Wahl gewesen wäre, und ich wollte sowieso OpenCL unter Linux versuchen.

War es hilfreich?

Lösung

Unter diesen Umständen würde ich wahrscheinlich einen DIB-Abschnitt verwenden (die Sie erstellen mit CreateDIBSection ). Ein DIB-Abschnitt ist eine Bitmap, die Sie die Inhalte direkt als Array zugreifen kann, aber es immer noch mit allen üblichen GDI-Funktionen verwenden.

Ich denke, dass Sie die beste Leistung von irgendetwas auf GDI basiert geb. Wenn Sie besser, dann @Kornel ist grundsätzlich richtig - Sie wechseln zu etwas benötigen, die für die Hardwarebeschleunigung (DirectX oder OpenGL mehr direkte Unterstützung hat - obwohl IMO, OpenGL ist eine viel bessere Wahl für den Job als DirectX).

Da Sie gerade die Berechnung in OpenCL tun, und die Ausgabe in einem Farbpuffer Ablagern würde OpenGL sein die wirklich offensichtliche Wahl. Insbesondere können Sie OpenCL die Ausgabe in einer OpenGL-Textur deponieren, dann haben Sie OpenGL Quad zeichnen diese Textur verwenden. Alternativ sind, da Sie nur die Ausgabe auf dem Bildschirm sowieso setzen, könnten Sie einfach die Berechnung in einem Shader-OpenGL-Fragmente tun (oder, natürlich, ein DirectX Pixel Shader), so würden Sie nicht die Ausgabe in dem Speicher stellen off-screen nur so können Sie das Ergebnis auf dem Bildschirm kopieren. Wenn der Speicher dient, das Orange Book hat einen Mandelbrot-Shader als eines seiner Beispiele.

Andere Tipps

Ja, sicher, das ist langsam. Sie machen eine Rundfahrt durch den Kernel und Videogerätetreiber für jedes einzelne Pixel. Sie machen es schnell, indem man zuerst den Speicher zeichnen, dann den Bildschirm auf einen Schlag aktualisieren. Das dauert etwa CreateDIBitmap, CreateCompatibleDC () und BitBlt ().

Dies ist keine gute Zeit und Platz für ein umfangreiches Tutorial über Grafikprogrammierung. Es ist gut mit jedem Einführungstext auf GDI und / oder Windows-API-Programmierung abgedeckt. Alles, was Sie wissen müssen Sie in Petzolds Samen Programming Windows finden können.

Da Sie bereits eine Reihe von Pixeln haben, können Sie direkt BitBlt verwenden es die DC, um das Fenster zu übertragen. Siehe diesen Link für einen Teil Beispiel: http://msdn.microsoft.com/en-us/library/aa928058. aspx

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top