草庐IT

windows - 快速像素绘图 C++ Windows 窗体

coder 2024-06-21 原文

我正在尝试为原始的太空入侵者街机制作一个 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 方法,但我找不到更好的方法来做到这一点。

最佳答案

感谢 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 将是必经之路。我没有实现这个,因为我只通过清除图形界面就获得了我需要的性能

关于windows - 快速像素绘图 C++ Windows 窗体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32168407/

有关windows - 快速像素绘图 C++ Windows 窗体的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby-on-rails - 如何在 Rails Controller Action 上触发 Facebook 像素 - 2

    我有一个ruby​​onrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素

  4. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

  5. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  6. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  9. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  10. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

随机推荐