web-dev-qa-db-ja.com

SetPixel()よりも高速なRGB値の生の配列から直接画面にピクセルを表示するにはどうすればよいですか?

マンデルブロ集合ズーマー、ライフゲームシミュレーターなどのc ++で、ピクセルをフレームごとに直接設定することで「アニメーション」を作成するのが好きです。 SetPixel()コマンドを使用すると、これは非常に簡単になりますが、残念ながら非常に遅くなります。配列Rの内容で画面全体をペイントしたい場合、各フレームに使用するセットアップの種類は次のとおりです。

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

私のマシンでは、SetPixel()が100万回以上呼び出されているという明らかな理由により、実行に5秒近くかかります。最良のシナリオでは、これを100倍速く実行し、スムーズな20fpsのアニメーションを取得できます。

何らかの方法でRをビットマップファイルに変換してから、BitBltを使用して1つのクリーンなコマンドでフレームを表示するのが良い方法だと聞きましたが、セットアップにこれを実装する方法がわからないので、助けていただければ幸いです。

関連する場合は、Windows 7で実行しており、IDEとしてCode :: Blocksを使用しています。

12
Can_of_awe

Remyのアドバイスに従って、私はピクセル配列を表示するこの方法に行き着きました(例としていくつかのコードが必要な人のために):

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
9
Himjune