0

我有一个使用原生 Delphi 代码在 TPaintBox 画布上创建 3D 运动的应用程序。在旧代码中,我将 3D 图像渲染为 Timer 事件上的临时 TBitmap。在 TPaintBox OnPaint() 事件中,我将 BitBlt() 临时 TBitmap TPaintBox 的画布。这种方法效果很好,但动作很生涩。

因为我对运动的平滑度不满意,所以我决定尝试“渲染”到一个非常大的工作区位图,然后将其下采样到 TPaintBox 画布。为了进行重新采样,我使用了我在这里读到的 Graphics32 库:

在 Delphi 中很好地缩放图像?

我更改了我的代码以渲染为一个大的 TBitmap32 (1100w x 1100h),然后当我对其进行下采样时,我使用带有 TLanczosKernel 内核的 Graphics TKernelResampler 对象对另一个大小与TPaintBox Canvas 并调用 TPaintBox 的 Refresh 方法。在 TPaintBox OnPaint 事件中,我 BitBlt() 将 TBitmap32 下采样到 TPaintBox 画布。

这可行,但问题是我只在拥有 TPaintBox 的表单需要重绘时才看到重绘,尽管我在完成渲染后立即在 TPaintBox 上调用了 Refresh 方法,但旧代码没有这个问题正如我所说的那样。作为有效性测试,我在大型高分辨率 TBitmap32 对象和用于预渲染的较小 TBitmap32 对象上调用了 SaveToFile()。位图显示,在 Timer 事件之间,帧的内容确实没有改变,所以这不是一个奇怪的重绘相关问题,至少 TPaintBox 组件没有。

如果我通过移动表单或用另一个表单覆盖其客户区的任何部分来使表单的画布无效,那么 TBitmap32 对象的内容会更新,我保存到磁盘作为检查的位图图像也会更新。

就好像 Graphics32 TBitmap 对象本身需要失效,以便更新我渲染到大型高分辨率工作区的新内容。但是,TBitmap32 没有这样的无效/刷新调用。

如果那里有人对 Graphics32 库有经验并且可以告诉我为什么我只在表单需要重新绘制或它的客户区无效时才看到图像发生变化,那么我将不胜感激。

4

1 回答 1

0

这最终成为一个很好的例子,说明症状如何看起来像是一个与您实际遇到的问题完全不同的问题。尽管我的四核和仅一个处理器上的 CPU 利用率从未超过 25%,但事实证明,缺乏更新是由于图形处理链中某处的处理(而非处理器)过载所致。我仍然不知道确切的位置,也许是在 Windows 图形库的暗处。但是一旦我减轻了处理负载,一切都开始完美更新。事实证明,尝试在大型位图上每秒 20 次运行 Graphics32 库 TLanczos 内核重采样器对于 Windows 图形系统来说太多了。如果我将帧速率(每秒渲染数)降低到每秒 4 次,那么突然更新开始正常进行。通过将 TLanczos 内核重采样器换成更快的草稿重采样器,我能够以出色的视觉美学质量返回到每秒更新 20 次。我想当我移动或调整主机窗口的大小时,这给了图形子系统足够的时间来赶上并正确更新,所以这就是我在这样做之后看到更新的原因。

于 2010-10-11T01:15:54.003 回答