2014-09-23 18 views
8

Mi piace creare "animazioni" in C++ come uno zoomer MandelBrot Set, un simulatore di Game of Life ecc. Impostando i pixel direttamente sullo schermo fotogramma per fotogramma. Il comando SetPixel() lo rende incredibilmente facile, anche se sfortunatamente è anche dolorosamente lento. Ecco il tipo di set-up che uso per ogni frame, se voluto dipingere l'intero schermo con il contenuto della matrice R:Come visualizzare i pixel sullo schermo direttamente da una matrice raw di valori RGB più veloce di SetPixel()?

#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; 
} 

Sulla mia macchina questo avviene quasi 5 secondi per eseguire l'evidente motivo per cui SetPixel() viene chiamato oltre un milione di volte. Il caso migliore è che posso farlo funzionare 100 volte più velocemente e ottenere un'animazione di 20 fps uniforme.

Ho sentito che convertire R in un file bitmap in qualche modo e poi usare BitBlt per visualizzare il frame in un comando clean è la strada da percorrere, ma non ho idea di come implementarlo per il mio setup e apprezzerei molto qualsiasi aiuto.

Se è rilevante, sono in esecuzione su Windows 7 e utilizzo di Code :: Blocks come IDE.

+0

tua intuizione è corretta: l'interazione tra Windows e impostazione singoli pixel è il collo di bottiglia, e il modo preferito è creare una bitmap in memoria. Non dovrebbe essere difficile trovare un tutorial per questo. Una volta implementato, potresti essere * stupito * dall'aumento della velocità. (Un'altra opzione potrebbe essere quella di passare a SDL, che può anche essere accelerato allo stesso modo ma riduce al minimo la parte specifica di Windows.) – usr2564301

+0

Usa 'CreateDIBitmap()' per creare una bitmap dai dati dei pixel che fornisci. La bitmap risultante sarà compatibile con la finestra HDC che si desidera disegnare, quindi è possibile utilizzare 'CreateCompatibleDC()' e 'SelectObject()' per preparare la bitmap per il disegno, e quindi 'BitBlt()' per disegnare effettivamente il bitmap bitmap sulla finestra. –

+1

Vedere anche CreateDIBSection –

risposta

7

Seguendo i consigli di Remy ho finito con questo modo di mostrare matrice di pixel (per i ragazzi, che ha bisogno di qualche codice come esempio):

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

Inoltre, non dimenticare di chiamare 'DeleteObject (map)' prima di 'DeleteDC (src) 'alla fine. Vedi [qui] (https://stackoverflow.com/questions/25829796/repeated-calls-to-createcompatiblebitmap-eventually-failure-with-getlasterror). – pmaxim98