我有一个使用原生 Delphi 代码在 TPaintBox 画布上创建 3D 运动的应用程序。在旧代码中,我将 3D 图像渲染为 Timer 事件上的临时 TBitmap。在 TPaintBox OnPaint() 事件中,我将 BitBlt() 临时 TBitmap TPaintBox 的画布。这种方法效果很好,但动作很生涩。
因为我对运动的平滑度不满意,所以我决定尝试“渲染”到一个非常大的工作区位图,然后将其下采样到 TPaintBox 画布。为了进行重新采样,我使用了我在这里读到的 Graphics32 库:
我更改了我的代码以渲染为一个大的 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 库有经验并且可以告诉我为什么我只在表单需要重新绘制或它的客户区无效时才看到图像发生变化,那么我将不胜感激。