【问题标题】:Fast pixel drawing c++ windows forms快速像素绘图 c++ windows 窗体
【发布时间】:2015-08-23 15:37:19
【问题描述】:

我正在尝试为原始的太空侵略者街机制作一个 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 表示黑色。

浏览互联网我发现“缓慢的部分”是 SetPixel 方法,但我找不到更好的方法来做到这一点。

【问题讨论】:

  • 您可以尝试的一个简单方法是g.Clear(Color::Black);,其中g 是图像中的Graphics 对象。然后您可以消除SetPixel(..., Color::Black);,这可能足以获得您需要的性能。
  • 值得一试,谢谢;
  • 这个链接可能会有所帮助:stackoverflow.com/questions/1563038/…
  • 很高兴在下一个项目中使用它。我正在尝试您的第一个解决方案,效果很好,只有清除功能会使屏幕闪烁,现在正在处理中

标签: windows winforms c++-cli drawing pixel


【解决方案1】:

感谢 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;

在初始化时,我添加了下一个代码以防止抛出空异常,

        Bitmap ^def = gcnew Bitmap(20, 20);
        this->pictureBox1->Image = def;

更新:虽然这种方法适用于我的项目,但考虑到屏幕主要由黑色像素组成。 GetPixel 和 SetPixel 很慢,不应该与性能敏感的程序一起使用。 LockBits 将是要走的路。我没有实现这一点,因为我只需清除图形界面即可获得所需的性能

【讨论】:

  • 您仍然有SetPixel 瓶颈,但它工作得更好,因为屏幕大部分是黑色的。你真的应该改用LockBits
  • 是的,我知道,对于这个项目,“清晰”的解决方案工作得很好。我现在开始使用更复杂的模拟器,使用 lockbits 解决方案
猜你喜欢
  • 1970-01-01
  • 2021-01-23
  • 2012-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-20
  • 2010-10-16
  • 2015-04-22
相关资源
最近更新 更多