【问题标题】:What's the fastest way to repeatedly fill a window with RGB data from an array?用数组中的 RGB 数据重复填充窗口的最快方法是什么?
【发布时间】:2011-05-06 10:52:52
【问题描述】:

我目前正在编写一个简单的游戏。我的图形代码每帧运行一次(大约每秒 30 次),并将 RGB 数据写入具有 640 * 480 = 307200 个条目的数组。

我创建了一个 Win32 窗口,其客户区的大小正好为 640 x 480 像素。在原本为空的窗口中显示我的 RGB 数据的最快方法是什么?

窗口需要每帧更新,所以我需要避免闪烁。我应该为此使用 GDI 吗?或者是否有更快的方法使用不同的库——比如 DirectDraw?

编辑:

感谢所有回复。首先,让我排除 Direct2D 作为选项 - 我需要支持 Windows XP。其次,我有 3D 背景,所以 Yann Ramin 和 Ben Voigtto 建议的方法 - 使用 Direct3D/OpenGL 和单个纹理四边形 - 是我过去一直这样做的方法。

但是,我很想知道 2D API 是否会是更好的解决方案。由于没有明确的答案,我整理了一个测试程序。该代码只是尽可能快地在屏幕上重复显示一个帧缓冲区。

我已将我的结果作为this follow-up question 的一部分发布。

【问题讨论】:

    标签: winapi gdi rgb directdraw


    【解决方案1】:

    您可以使用 GDI 做的最好的事情是使用 SetDIBitsToDevice 直接将 RGB 数据从您的阵列复制到窗口。当然,如果您需要完全消除闪烁,DirectX 是不二之选。

    【讨论】:

    • 我不认为SetDIBits实际上直接绘制到窗口,我认为你需要使用BitBlt之后。
    • @Ben Voigt:糟糕,我的意思是SetDIBitsToDevice
    【解决方案2】:

    GDI 绝对不是要走的路。

    最好的跨windows版本方式是使用Direct3D,简单的更新一个全屏四边形的纹理。

    Direct2D 是一个新的 API(Win Vista with Service pack 及以上),如果您不需要支持 XP,它是首选机制。 Direct2d 以加速的方式处理字体和其他系统级任务。

    【讨论】:

    • “GDI 绝对不是要走的路”——我很想知道你为什么这么说。根据我在stackoverflow.com/questions/4128441 的结果,GDI 是最快的方法——它也是最容易编写的。
    【解决方案3】:

    使用 DirectDraw。我有一个全屏的生命游戏,当我使用 GDI 时,它在像素绘图上遇到了瓶颈,而在我切换到 DirectDraw 之后,我开始轻松地输出 60 fps。

    【讨论】:

    • DirectDraw 已弃用。虽然 API 仍然存在,但它没有收到任何爱。
    • 有趣 - 在我的测试中 (stackoverflow.com/questions/4128441),DirectDraw 比 GDI 慢。您是否使用不同的方法来挖掘一个或两个 API?
    • 请注意,我提到的不是位 bliting,而是 setpixel 调用。我很惊讶看到 2K fps。你确定电话不会以某种方式短路吗?
    • 再看一遍,我觉得有些电话确实可能短路了……
    【解决方案4】:

    GDI 函数SetDIBitsToDevice 可以正常工作。

    按照 theatrus 的建议对四边形进行纹理处理也可以,但它不必是全屏的,而 OpenGL 是迄今为止最便携的选项,要实现这一点,请参阅 glTexSubImage2D

    更直接的方式是glDrawPixels

    不过,理想情况下,您的图形代码会使用 GPU 加速渲染直接到 GPU 内存中,这样您就不必担心将位从系统内存移动到 GPU。

    【讨论】:

      猜你喜欢
      • 2011-05-06
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      相关资源
      最近更新 更多