如何直接从RGB原始数组中显示像素,比SetPixel()更快?

时间:2014-09-23 22:32:42

标签: c++ windows animation bitmap pixel

我喜欢在c ++中制作“动画”,例如MandelBrot Set缩放器,Game of Life模拟器等,通过逐帧将像素直接设置到屏幕上。 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;
}

在我的机器上执行这几乎需要5秒钟,这显然是因为SetPixel()被调用超过一百万次。最好的情况我可以让它运行速度提高100倍并获得平滑的20fps动画。

我听说以某种方式将R转换为位图文件,然后使用BitBlt在一个干净的命令中显示框架是要走的路,但我不知道如何为我的设置实现这个,并且非常感谢任何帮助

如果它是相关的,我在Windows 7上运行并使用Code :: Blocks作为我的IDE。

1 个答案:

答案 0 :(得分:9)

按照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