Delphi 6 - Растровое изображение обновляется только тогда, когда окно владельца требует перерисовки при использовании библиотеки Graphics32 - PullRequest
0 голосов
/ 10 октября 2010

У меня есть приложение, которое создает трехмерное движение на холсте TPaintBox, используя собственный код Delphi.В старом коде я рендерил трехмерное изображение во временную карту TBitmap по событию Timer.В событии TPaintBox OnPaint () я бы использовал BitBlt () временный TBitmap для холста TPaintBox.Этот подход работал нормально, но движение было прерывистым.

Поскольку я не был доволен плавностью движения, я решил вместо этого попробовать «отрендерить» очень растровое изображение очень большого рабочего пространства, а затем уменьшить его до TPaintBox.Холст.Для повторной выборки я использовал библиотеку Graphics32, о которой я читал здесь:

Масштабирование изображения в Delphi?

Я изменил свой код для рендеринга набольшой TBitmap32 (1100w x 1100h), а затем при его понижающей выборке я использую объект Graphics TKernelResampler с ядром TLanczosKernel для выполнения понижающей выборки до другого TBitmap32, который точно такого же размера, что и TPaintBox Canvas, и вызывает метод Refaint TPaintBox,В событии TPaintBox OnPaint I BitBlt () преобразовывает TBitmap32 с пониженной выборкой в ​​холст TPaintBox.

Это работает, но проблема заключается в том, что я вижу перерисовки только тогда, когда форма, владеющая TPaintBox, требует перерисовки, проблема, которую я сделалсо старым кодом, несмотря на то, что я вызываю метод Refresh в TPaintBox сразу после завершения рендеринга, как я уже сказал.В качестве теста достоверности я вызвал SaveToFile () как для большого объекта TBitmap32 с высоким разрешением, так и для меньшего объекта TBitmap32, который я использую для предварительного рендеринга.Растровые изображения показали, что на самом деле кадр между событиями Timer не изменился вообще, поэтому это не странная проблема, связанная с перерисовкой, по крайней мере, с компонентом TPaintBox.

Если я аннулирую холст формы, переместив форму или наложив какую-либо часть ее клиентской области другой формой, то содержимое объектов TBitmap32 обновится, и растровые изображения, которые я сохраню на диске в качестве проверки, будут обновлены..

Это как если бы сам объект Graphicsit TBitmap был признан недействительным, чтобы новый контент, который я рендерил в большую рабочую область высокого разрешения, обновлялся.Тем не менее, TBitmap32 не имеет такого вызова для аннулирования / обновления.

Если кто-то имеет опыт работы с библиотекой Graphics32 и может сказать мне, почему я вижу изменения изображений только тогда, когда форма требует перерисовки или ее клиентобласть признана недействительной, тогда я был бы признателен за это.

1 Ответ

0 голосов
/ 11 октября 2010

Это стало ярким примером того, как симптомы могут выглядеть как проблема, которая совершенно отличается от той, которая у вас есть на самом деле. Несмотря на то, что загрузка процессора на моем четырехъядерном процессоре и только на одном процессоре никогда не превышала 25%, оказалось, что отсутствие обновления было связано с перегрузкой обработки (а не процессора) где-то в цепочке обработки графики. Я до сих пор точно не знаю, где, возможно, что-то в темных уголках графических библиотек Windows. Но как только я ослабил нагрузку обработки, все начало обновляться отлично. Оказалось, что попытка запустить ресэмплер ядра TLanczos из библиотеки Graphics32 20 раз в секунду на большом растровом изображении была слишком сложной для обработки графической системой Windows. Если я снизил частоту кадров (рендеринг в секунду) до 4 раз в секунду, то внезапно обновления начали происходить нормально. Заменив ресэмплер ядра TLanczos на более быстрый черновой ресэмплер, я смог вернуться к обновлению 20 раз в секунду с превосходным визуальным эстетическим качеством. Я думаю, когда я переместил или изменил размер окна хоста, это дало графической подсистеме достаточно времени, чтобы наверстать упущенное и правильно обновить, поэтому после этого я увидел обновления.

...