为什么比图像图形更快地绘制OnPaint图形?

时间:2010-04-05 19:53:48

标签: c# performance gdi+ drawing

我正在寻找一种方法来加速我的游戏引擎的绘制,这是目前的重要瓶颈,并且正在导致减速。我快要把它转换成XNA,但我只是注意到了一些东西。

说我有一张我已加载的小图片。

    Image img = Image.FromFile("mypict.png");

我们想要在屏幕上绘制一个图片框。所以我们有一个处理程序。

    pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);

我希望我们加载的图像在图片框上平铺(毕竟这是游戏)。为什么这个代码:

    void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        for (int y = 0; y < 16; y++)
            for (int x = 0; x < 16; x++)
                e.Graphics.DrawImage(image, x * 16, y * 16, 16, 16);
    }

比这段代码快25倍:

    Image buff = new Bitmap(256, 256, PixelFormat.Format32bppPArgb); // actually a form member
    void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        using (Graphics g = Graphics.FromImage(buff))
        {
            for (int y = 0; y < 16; y++)
                for (int x = 0; x < 16; x++)
                    g.DrawImage(image, x * 16, y * 16, 16, 16);
        }
        e.Graphics.DrawImage(buff, 0, 0, 256, 256);
    }

为了消除显而易见的,我已经尝试评论出最后的e.Graphics.DrawImage(这意味着我没有看到任何东西,但它摆脱了第一个例子中没有的调用)。在第一个例子中,我还在使用块(不必要地),但它仍然是非常快。我已设置g的属性以匹配e.Graphics - InterpolationModeCompositingQuality等等,但我没有做任何事情来弥补这一令人难以置信的性能差距。我发现两个Graphics对象之间没有任何区别。是什么给了什么?

我使用System.Diagnostics.Stopwatch进行的测试表明,第一个代码段以大约7100 fps的速度运行,而第二个代码段的运行速度为280 fps。我的参考图像为VS2010ImageLibrary\Objects\png_format\WinVista\SecurityLock.png,为48x48像素,我将其修改为72 dpi而不是96 dpi,但这些图像也没有区别。

3 个答案:

答案 0 :(得分:1)

当您绘制到屏幕时,操作系统可以利用图形适配器中的特殊硬件来执行简单的操作,例如复制图像。

答案 1 :(得分:1)

我两个都要大约5毫秒。对于GDI +完成的软件渲染,7100 fps的方式太快了。视频驱动程序众所周知地欺骗赢得基准,他们可以检测到不必执行BitBlt,因为图像没有改变。尝试将随机值传递给e.Graphics.TranslateTransform以消除作弊。

答案 2 :(得分:0)

您确定差异不是来自使用块,即设置try-finally块并从图像缓冲区创建Graphics实例。

我很容易将后者看作是一项昂贵的操作,不像paint事件,你只需要引用已经创建的图形实例。