【发布时间】:2014-11-18 06:55:02
【问题描述】:
我喜欢在 C++ 中制作“动画”,例如 MandelBrot Set zoomer、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。
【问题讨论】:
-
您的预感是正确的:Windows 和设置单个像素之间的交互是瓶颈,首选方法是创建内存位图。找到这方面的教程应该不难。一旦你实施它,你可能会对速度的提高惊讶。 (另一种选择可能是切换到 SDL,它也可以以相同的方式加速,但最小化 Windows 特定部分。)
-
使用
CreateDIBitmap()根据您提供的像素数据创建位图。生成的位图将与您要在其上绘制的窗口 HDC 兼容,因此您可以使用CreateCompatibleDC()和SelectObject()准备要绘制的位图,然后使用BitBlt()将位图实际绘制到窗口上。 -
另见 CreateDIBSection
标签: c++ windows animation bitmap pixel