2014-09-23 14 views
8

Ich mache gerne "Animationen" in C++ wie ein MandelBrot Set Zoomer, Game of Life Simulator usw., indem Sie Pixel Pixel für Bild direkt auf den Bildschirm setzen. Der Befehl SetPixel() macht dies unglaublich einfach, obwohl es leider auch sehr langsam ist. Hier ist die Art von Set-up I für jeden Rahmen zu verwenden, wenn ich den ganzen Bildschirm mit dem Inhalt des Feldes R malen wollte:Wie werden Pixel auf dem Bildschirm direkt aus einem RAW-Array von RGB-Werten schneller als SetPixel() angezeigt?

#include <windows.h> 
using namespace std; 
int main() 
{ 
    int xres = 1366; 
    int yres = 768; 
    char *R = new char [xres*yres*3]; 

    /* 
    R is a char array containing the RGB value of each pixel sequentially 
    Arithmetic operations done to each element of R here 
    */ 

    HWND window; HDC dc; window = GetActiveWindow(); dc = GetDC(window); 

    for (int j=0 ; j<yres ; j++) 
     for (int i=0 ; i<xres ; i++) 
      SetPixel(dc,i,j,RGB(R[j*xres+3*i],R[j*xres+3*i+1],R[j*xres+3*i+2])); 

    delete [] R; 
    return 0; 
} 

Auf meinem Rechner das dauert fast 5 Sekunden auszuführen, für die offensichtliche Grund dafür, dass SetPixel() über eine Million Mal aufgerufen wird. Im besten Fall könnte ich 100x schneller laufen und eine glatte 20fps-Animation erhalten.

Ich höre, dass die Umwandlung R in eine Bitmap-Datei in irgendeiner Weise und dann mit BitBlt, um den Rahmen in einem sauberen Befehl anzuzeigen ist der Weg zu gehen, aber ich habe keine Ahnung, wie dies für meine Einrichtung zu implementieren und würde es sehr zu schätzen wissen irgendeine Hilfe.

Wenn es relevant ist, ich auf Windows 7 laufen und Code :: Blocks als meine IDE verwenden.

+0

Ihre Vermutung ist richtig: die Interaktion zwischen Windows und Einstellung einzelner Pixel ist der Engpass, und die bevorzugte Möglichkeit besteht darin, eine In-Memory-Bitmap zu erstellen. Es sollte nicht schwer sein, ein Tutorial dafür zu finden. Sobald Sie es implementieren, können Sie * durch die Geschwindigkeitserhöhung * erstaunt * sein. (Eine andere Option könnte sein, zu SDL zu wechseln, das ebenfalls beschleunigt werden kann, aber den Windows-spezifischen Teil minimiert.) – usr2564301

+0

Verwenden Sie 'CreateDIBitmap()', um ein Bitmap aus von Ihnen bereitgestellten Pixeldaten zu erstellen. Die resultierende Bitmap ist mit dem Fenster HDC kompatibel, auf dem Sie zeichnen möchten. Sie können 'CreateCompatibleDC()' und 'SelectObject()' verwenden, um die Bitmap für das Zeichnen vorzubereiten, und dann 'BitBlt()', um tatsächlich das Zeichen zu zeichnen Bitmap auf das Fenster. –

+1

Siehe auch CreateDIBSection –

Antwort

7

Nach Remy Ratschläge endete ich mit diesem Weg Pixelanordnung zu zeigen (für Jungs, die einen Code als Beispiel benötigt):

COLORREF *arr = (COLORREF*) calloc(512*512, sizeof(COLORREF)); 
/* Filling array here */ 
/* ... */ 

// Creating temp bitmap 
HBITMAP map = CreateBitmap(512 // width. 512 in my case 
          512, // height 
          1, // Color Planes, unfortanutelly don't know what is it actually. Let it be 1 
          8*4, // Size of memory for one pixel in bits (in win32 4 bytes = 4*8 bits) 
          (void*) arr); // pointer to array 
// Temp HDC to copy picture 
HDC src = CreateCompatibleDC(hdc); // hdc - Device context for window, I've got earlier with GetDC(hWnd) or GetDC(NULL); 
SelectObject(src, map); // Inserting picture into our temp HDC 
// Copy image from temp HDC to window 
BitBlt(hdc, // Destination 
     10, // x and 
     10, // y - upper-left corner of place, where we'd like to copy 
     512, // width of the region 
     512, // height 
     src, // source 
     0, // x and 
     0, // y of upper left corner of part of the source, from where we'd like to copy 
     SRCCOPY); // Defined DWORD to juct copy pixels. Watch more on msdn; 

DeleteDC(src); // Deleting temp HDC 
+1

https://www.gamedev.net/topic/563156-what-is-a-color-plane/ –

+1

Vergessen Sie auch nicht 'DeleteObject (map)' vor 'DeleteDC (src) 'Am Ende. Siehe [hier] (https://stackoverflow.com/questions/25829796/repeated-calls-to-createcompatibilitybitmap-eventually-failure-with-getlasterror). – pmaxim98

Verwandte Themen