快速像素绘图c++ windows 形式
Fast pixel drawing c++ windows forms
我正在尝试为原始 space 入侵者街机制作一个 C++ 模拟器。一切正常,但速度很慢。在我的项目中对几个功能进行计时后,我发现最大的消耗是我的绘制屏幕功能。它需要 +100 毫秒,但我需要 16 毫秒/帧,例如60赫兹。这是我的功能:
unsigned char *fb = &state->memory[0x2400];
Bitmap ^ bmp = gcnew Bitmap(512, 448);
for (int j = 1; j < 224; j++)
{
for (int i = 0; i < 256; i+=8)
{
unsigned char pix = fb[(j * 256 / 8) + i / 8];
for (int p = 0; p < 8; p++)
{
if (0 != (pix & (1 << p)))
{
bmp->SetPixel(i + p, j, Color::White);
}
else
{
bmp->SetPixel(i + p, j, Color::Black);
}
}
}
}
bmp->RotateFlip(RotateFlipType::Rotate270FlipNone);
this->pictureBox1->Image = bmp;
fb 是我的帧缓冲区,一个字节数组,每个字节 8 个像素,1 代表白色,0 代表黑色。
上网发现"slow part"是SetPixel方法,但找不到更好的方法。
感谢 Loathings 的评论,我解决了这个问题。我不是重新绘制每个像素,而是先将图像清除为黑色,然后只绘制白色像素。必须使用缓冲区来防止闪烁
unsigned char *fb = &state->memory[0x2400];
Bitmap ^ bmp = gcnew Bitmap(512, 448);
Image ^buffer = this->pictureBox1->Image;
Graphics ^g = Graphics::FromImage(buffer);
for (int j = 1; j < 224; j++)
{
for (int i = 0; i < 256; i += 8)
{
unsigned char pix = fb[(j * 256 / 8) + i / 8];
for (int p = 0; p < 8; p++)
{
if (0 != (pix & (1 << p)))
{
bmp->SetPixel(i + p, j, Color::White);
}
}
}
}
bmp->RotateFlip(RotateFlipType::Rotate270FlipNone);
g->Clear(Color::Black);
buffer = bmp;
this->pictureBox1->Image = buffer;
并且在初始化时我添加了下一个代码以防止抛出 nullexception,
Bitmap ^def = gcnew Bitmap(20, 20);
this->pictureBox1->Image = def;
更新:尽管此方法适用于我的项目,但考虑到屏幕将主要由黑色像素组成。 GetPixel 和 SetPixel 很慢,不应该与性能敏感的程序一起使用。 LockBits 将是必经之路。我没有实现这个,因为我只通过清除图形界面就得到了我需要的性能
我正在尝试为原始 space 入侵者街机制作一个 C++ 模拟器。一切正常,但速度很慢。在我的项目中对几个功能进行计时后,我发现最大的消耗是我的绘制屏幕功能。它需要 +100 毫秒,但我需要 16 毫秒/帧,例如60赫兹。这是我的功能:
unsigned char *fb = &state->memory[0x2400];
Bitmap ^ bmp = gcnew Bitmap(512, 448);
for (int j = 1; j < 224; j++)
{
for (int i = 0; i < 256; i+=8)
{
unsigned char pix = fb[(j * 256 / 8) + i / 8];
for (int p = 0; p < 8; p++)
{
if (0 != (pix & (1 << p)))
{
bmp->SetPixel(i + p, j, Color::White);
}
else
{
bmp->SetPixel(i + p, j, Color::Black);
}
}
}
}
bmp->RotateFlip(RotateFlipType::Rotate270FlipNone);
this->pictureBox1->Image = bmp;
fb 是我的帧缓冲区,一个字节数组,每个字节 8 个像素,1 代表白色,0 代表黑色。
上网发现"slow part"是SetPixel方法,但找不到更好的方法。
感谢 Loathings 的评论,我解决了这个问题。我不是重新绘制每个像素,而是先将图像清除为黑色,然后只绘制白色像素。必须使用缓冲区来防止闪烁
unsigned char *fb = &state->memory[0x2400];
Bitmap ^ bmp = gcnew Bitmap(512, 448);
Image ^buffer = this->pictureBox1->Image;
Graphics ^g = Graphics::FromImage(buffer);
for (int j = 1; j < 224; j++)
{
for (int i = 0; i < 256; i += 8)
{
unsigned char pix = fb[(j * 256 / 8) + i / 8];
for (int p = 0; p < 8; p++)
{
if (0 != (pix & (1 << p)))
{
bmp->SetPixel(i + p, j, Color::White);
}
}
}
}
bmp->RotateFlip(RotateFlipType::Rotate270FlipNone);
g->Clear(Color::Black);
buffer = bmp;
this->pictureBox1->Image = buffer;
并且在初始化时我添加了下一个代码以防止抛出 nullexception,
Bitmap ^def = gcnew Bitmap(20, 20);
this->pictureBox1->Image = def;
更新:尽管此方法适用于我的项目,但考虑到屏幕将主要由黑色像素组成。 GetPixel 和 SetPixel 很慢,不应该与性能敏感的程序一起使用。 LockBits 将是必经之路。我没有实现这个,因为我只通过清除图形界面就得到了我需要的性能