如何比SetPixel()更快地直接从RGB值的原始数组在屏幕上显示像素? [英] How to display pixels on screen directly from a raw array of RGB values faster than SetPixel()?

查看:114
本文介绍了如何比SetPixel()更快地直接从RGB值的原始数组在屏幕上显示像素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过将像素直接逐帧设置到屏幕上,我喜欢用c ++制作动画",例如MandelBrot Set缩放器,Game of Life模拟器等. SetPixel()命令使此操作变得异常简单,尽管不幸的是它的速度也很慢.如果要使用数组R的内容在整个屏幕上绘制,这是我在每帧中使用的一种设置:

I enjoy making "animations" in c++ such as a MandelBrot Set zoomer, Game of Life simulator etc. by setting pixels directly to the screen frame-by-frame. The SetPixel() command makes this incredibly easy, although unfortunately it's also painfully slow. Here is the sort of set-up I use for each frame, if I wanted to paint the entire screen with the contents of the array 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动画.

On my machine this takes almost 5 seconds to execute for the obvious reason that SetPixel() is being called over a million times. Best case scenario I could get this to run 100x faster and get a smooth 20fps animation.

我听说可以通过某种方式将R转换为位图文件,然后使用BitBlt在一个干净的命令中显示帧,但是我不知道如何在我的设置中实现此功能,对此我将不胜感激帮助.

I hear that converting R into a bitmap file in some way and then using BitBlt to display the frame in one clean command is the way to go, but I have no idea how to implement this for my setup and would greatly appreciate any help.

如果相关,那么我正在Windows 7上运行,并使用Code :: Blocks作为我的IDE.

If it is relevant, I am running on Windows 7 and using Code::Blocks as my IDE.

推荐答案

按照雷米的建议,我最终以这种方式显示像素阵列(对于需要一些代码的人来说):

Following Remy's advices I ended up with this way of showing pixel array (for guys, who needs some code as an example):

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

这篇关于如何比SetPixel()更快地直接从RGB值的原始数组在屏幕上显示像素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆