代码之家  ›  专栏  ›  技术社区  ›  Robert Oschler Rob

Delphi 6-使用Graphics32库时,仅当所有者窗口需要重新绘制时,位图才会更新

  •  0
  • Robert Oschler Rob  · 技术社区  · 14 年前

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

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

    Scale an image nicely in Delphi?

    我将代码更改为渲染为一个大的TBitmap32(1100w x 1100h),然后在对其进行下采样时,我使用带有TLanczosKernel内核的Graphics TKernelResampler对象对另一个与TPaintBox画布大小完全相同的TBitmap32进行下采样,并调用TPaintBox的刷新方法。在TPaintBox OnPaint事件I BitBlt()中,将向下采样的TBitmap32映射到TPaintBox画布。

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

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

    1 回复  |  直到 8 年前
        1
  •  0
  •   Robert Oschler Rob    14 年前

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