2010-10-10 51 views
0

我有一個應用程序使用原生Delphi代碼在TPaintBox Canvas上創建3D運動。在舊代碼中,我將3D圖像渲染爲Timer事件上的臨時TBitmap。在TPaintBox OnPaint()事件中,我將BitBlt()臨時TBitmap作爲TPaintBox的Canvas。這種方法運行良好,但該議案是生澀。德爾福6 - 只有當所有者窗口需要使用Graphics32庫重繪時,位圖纔會更新

因爲我對運動的平滑性不滿意,所以我決定嘗試「渲染」到一個非常大的工作空間位圖,然後將其下采樣到TPaintBox畫布。要做到重採樣我用Graphics32庫,我約在這裏讀到:

Scale an image nicely in Delphi?

我改變了我的代碼來渲染一個大TBitmap32(1100瓦特X 1100H),然後當我下采樣它我使用帶有TLanczosKernel內核的Graphics TKernelResampler對象對與TPaintBox Canvas尺寸完全相同的另一個TBitmap32執行下采樣,並調用TPaintBox的Refresh方法。在TPaintBox OnPaint事件中,我將BitBlt()向下採樣的TBitmap32添加到TPaintBox畫布。

這樣的工作,但問題是我只看到重繪當擁有TPaintBox的窗體需要重繪,我沒有舊代碼的問題,儘管面對我在TPaintBox後立即調用Refresh方法正如我所說的那樣,它完成了渲染。作爲有效性測試,我在大型高分辨率TBitmap32對象和用於預先呈現的較小TBitmap32對象上都調用了SaveToFile()。位圖顯示幀的內容在Timer事件之間並沒有發生任何變化,所以它不是一個奇怪的重繪相關問題,至少不是TPaintBox組件。

如果我通過移動表單或使用其他表單覆蓋客戶區域的任何部分來使表單的畫布無效,那麼TBitmap32對象的內容會更新,因此我將這些圖像保存到磁盤作爲檢查。

就好像Graphics32 TBitmap對象本身需要失效一樣,以便我更新呈現給大型高分辨率工作空間的新內容。但是,TBitmap32沒有這種invalidate/refresh調用。

如果任何人都有經驗的Graphics32庫,並可以告訴我爲什麼我只看到圖像更改時,表單需要重新繪製或其客戶區失效,那麼我將不勝感激。

回答

0

這最終成爲症狀如何看起來像一個完全不同於你實際存在的問題的主要例子。儘管我的四核和只有一個處理器的CPU利用率從未超過25%,但事實證明,缺少更新是由於圖形處理鏈中的處理器(而非處理器)超載所致。我仍然不知道到底在哪裏,可能是Windows圖形庫的黑暗凹陷處。但是一旦我緩解了處理負載,所有事情都開始更新。事實證明,試圖在一個大的位圖上每秒運行20次的Graphics32庫TLanczos內核重採樣器對於Windows圖形系統來說處理太多了。如果我將幀速率(每秒渲染速度)降至每秒4次,而不是突然更新開始正常進行。通過更換TLanczos內核重採樣器以獲得速度更快的草稿重採樣器,我可以每秒更新20次,並具有出色的視覺美學質量。我想當我移動或調整主機窗口的大小時,這給了圖形子系統足夠的時間來跟上並正確更新,這就是爲什麼我在看完這些更新後纔看到更新。