【发布时间】:2011-05-06 22:04:17
【问题描述】:
这是this question 的后续行动。我目前正在编写一个简单的游戏,并且正在寻找在 Win32 窗口中(重复)显示 RGB 数据数组的最快方法,而不会出现闪烁或其他伪影。
在上一个问题的答案中推荐了几种不同的方法,但对于哪种方法最快没有达成共识。所以,我拼凑了一个测试程序。该代码只是尽可能快地在屏幕上重复显示一个帧缓冲区。
这些是我获得的结果,对于在 32 位视频模式下运行的 32 位数据 - 它们可能会让一些人感到惊讶:
- Direct3D (1): 500 fps
- Direct3D (2): 650 fps
- DirectDraw (3): 1100 fps
- DirectDraw (4): 800 fps
- GDI (SetDIBitsToDevice): 2000 fps
鉴于这些数字:
- 为什么很多人坚持认为 GDI 对这个操作来说太慢了?
- 是否有任何理由更喜欢 DirectDraw 或 Direct3D 而不是 SetDIBitsToDevice?
以下是每个 Direct* 代码路径调用的简要摘要。如果有人知道使用 DirectDraw/Direct3D 的更有效方法,请发表评论。
1. CreateTexture(D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT);
LockRect(); memcpy(); UnlockRect(); DrawPrimitive()
2. CreateTexture(0, D3DPOOL_SYSTEMMEM); CreateTexture(0, D3DPOOL_DEFAULT);
LockRect(); memcpy(); UnlockRect(); UpdateTexture(); DrawPrimitive()
3. CreateSurface(); SetSurfaceDesc(lpSurface = &frameBuffer[0]);
memcpy(); primarySurface->Blt();
4. CreateSurface();
Lock(); memcpy(); Unlock(); primarySurface->Blt();
【问题讨论】:
-
我不是这个领域的专家,但我肯定会在几种不同类型的图形硬件上运行这个实验,然后再得出任何结论。
-
你是如何合成 RGB 数据的?除非您需要硬件加速来合成图像,否则我不希望 DirectX 更快。它需要以一种或另一种方式发送到视频硬件才能显示,即使是通过 GDI。使用 directx 方法,您将添加创建表面或纹理的额外工作。 GDI 一定会变慢是不合理的。
-
GDI 做得很好并且已经优化了 20 多年的一件事是移动位。现在似乎有某种传统的“智慧”,任何有 20 年历史的 API 都必须以某种方式过时。
-
大家好!保罗,你最终选择了什么,为什么?我正在实时显示和更新表示来自进程的原始内存的大量 RGB 数据数组,而 Direct2D 似乎不适合这种操作,因为我的帧速率非常低。
-
FWIW,你的 DirectX 测试循环都有一个巨大的缺陷,这可能解释了性能问题。了解 DirectX 已针对 SETTING STUFF UP ONCE 进行了优化,然后在多个帧上重用,只更改需要更改的内容。正确的用法是 CreateSurface 和 CreateTexture ONCE,然后在框架上重新使用这些实体。也就是说,这些调用不应该在你的计时循环中。
标签: winapi directx gdi directdraw