0

ネイティブの Delphi コードを使用して TPaintBox Canvas で 3D モーションを作成するアプリケーションがあります。古いコードでは、Timer イベントで 3D イメージを一時的な TBitmap にレンダリングしました。TPaintBox の OnPaint() イベントでは、一時的な TBitmap を TPaintBox の Canvas に BitBlt() します。このアプローチはうまくいきましたが、動きがぎくしゃくしていました。

モーションの滑らかさに満足できなかったので、代わりに非常に大きなワークスペース ビットマップに「レンダリング」してから、それを TPaintBox Canvas にダウンサンプリングすることにしました。リサンプリングを行うために、ここで読んだ Graphics32 ライブラリを使用しました。

Delphiで画像をうまくスケーリングしますか?

大きな TBitmap32 (幅 1100 x 高さ 1100) にレンダリングするようにコードを変更し、それをダウンサンプリングするときに、TLanczosKernel カーネルで Graphics TKernelResampler オブジェクトを使用して、別の TBitmap32 にダウンサンプリングします。 TPaintBox Canvas を開き、TPaintBox の Refresh メソッドを呼び出します。TPaintBox OnPaint イベントで、ダウンサンプリングされた TBitmap32 を TPaintBox Canvas に BitBlt() します。

これは機能しますが、問題は、TPaintBox を所有するフォームが再描画を必要とする場合にのみ再描画が表示されることです。これは、レンダリングが完了した直後に TPaintBox で Refresh メソッドを呼び出すという顔にもかかわらず、古いコードでは発生しなかった問題です。私が言ったように、それに。有効性テストとして、事前レンダリングに使用する大きな高解像度 TBitmap32 オブジェクトと小さな TBitmap32 オブジェクトの両方で SaveToFile() を呼び出しました。ビットマップは、Timer イベント間でフレームのコンテンツがまったく変更されていないことを実際に示していたため、少なくとも TPaintBox コンポーネントでは、奇妙な再描画関連の問題ではありません。

フォームを移動するか、フォームのクライアント領域の一部を別のフォームでオーバーレイしてフォームのキャンバスを無効にすると、TBitmap32 オブジェクトのコンテンツが更新され、チェックとしてディスクに保存したビットマップ イメージも更新されます。

大規模な高解像度ワークスペースにレンダリングした新しいコンテンツが更新されるように、Graphics32 TBitmap オブジェクト自体を無効にする必要があるかのようです。ただし、TBitmap32 にはそのような無効化/更新呼び出しはありません。

Graphics32 ライブラリの経験があり、フォームの再描画が必要な場合やクライアント領域が無効になっている場合にのみ画像が変更される理由を教えていただければ幸いです。

4

1 に答える 1

0

これは、実際に抱えている問題とはまったく異なる問題のように見える症状の典型的な例です. クアッド コアと 1 つのプロセッサのみの CPU 使用率が 25% を超えることはありませんでしたが、更新が行われていないのは、グラフィック処理チェーンのどこかで (プロセッサではなく) 処理が過負荷になっていることが原因であることが判明しました。どこにあるのか、まだ正確にはわかりません。おそらく、Windows グラフィック ライブラリの奥深くにあるものでしょう。しかし、処理負荷を軽減すると、すべてが完全に更新され始めました。Graphics32 ライブラリ TLanczos カーネル リサンプラーを大きなビットマップで 1 秒間に 20 回実行しようとすると、Windows グラフィック システムが処理するには多すぎることが判明しました。フレーム レート (1 秒あたりのレンダリング数) を 1 秒あたり 4 回まで下げると、突然更新が正常に行われるようになりました。TLanczos カーネル リサンプラーをはるかに高速なドラフト リサンプラーに交換することで、優れた視覚的美的品質で 1 秒間に 20 回の更新に戻ることができました。ホストウィンドウを移動またはサイズ変更したときに、グラフィックサブシステムが追いついて適切に更新するのに十分な時間を与えたので、それを行った後に更新を見たのだと思います。

于 2010-10-11T01:15:54.003 に答える