Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.17.128.129] |
|
Сообщ.
#1
,
|
|
|
Какой компонент (из стандартных) лучше использовать, чтобы рисовать на форме без мерцания: TImage, TPaintBox или что-то ещё?
И как это делается вообще? Ну то есть методов BeginUpdate в Canvas я не вижу. У меня представление такое: рисуешь на Canvas, не заморачиваясь, а потом всё само перерисовывается при OnPaint Как оно на самом деле? Добавлено Т.е. чтобы не надо было перерисовывать каждый раз в OnPaint. Рисунок может быть сложным (через линии и пр). |
Сообщ.
#2
,
|
|
|
Для динамических картинок - TPaintBox.
Важно - само изображение формируется в битмапе, в нужный момент вызывается Invalidate Paintbox-а, в его OnPaint шлёпаешь (Draw, BitBlt) готовый битмап. Родителю перерисовываемого контрола (форме?) может быть полезно установить DoubleBuffering. Для контролов на панели, на PageControl проверить ParentBackground to False. Кроме того, могут быть заморочки при использовании VCL Styles в свежих Дельфях. DoubleBuffering у родителя не всегда спасает, может сделать даже хуже. |
Сообщ.
#3
,
|
|
|
Цитата Jin X @ Какой компонент (из стандартных) лучше использовать, чтобы рисовать на форме без мерцания: TImage, TPaintBox или что-то ещё? ... У меня представление такое: рисуешь на Canvas, не заморачиваясь, а потом всё само перерисовывается при OnPaint В этом и есть принципиальное различие между TImage и TPaintBox. TImage хранит изображение в памяти (в объекте Graphic = TBitmap и т.п.) и автоматически копирует его на экран при WM_PAINT. При этом копирование происходит максимально быстро (методом Canvas.Draw = BitBlt и т.п.). Если изображение динамическое, то его изменение в памяти, как правило (при правильном проектировании), осуществляется по неким внешним событиям, не связанным с обработкой WM_PAINT\OnPaint. В итоге вывод (уже готового) изображения на экран всегда происходит быстро. TPaintBox сам по себе никакого изображения не хранит и рисует его непосредственно на экране во время обработки WM_PAINT => OnPaint. Соотв-но, если изображение сложное и рисуется долго, то возможны мерцания (особенно при родительском DoubleBuffering = false). Поэтому для сокращения времени вывода изображения на экран, можно его предварительно формировать в памяти во вспомогательном битмапе, а затем выводить на экран тем же методом Canvas.Draw => BitBlt (о чем уже сказал MBo). Однако, если этот битмап формируется заранее, то по сути это является ненужным дублированием функциональности, уже реализованной в TImage. Если же он формируется динамически во время OnPaint, то это имеет смысл только при отключенном DoubleBuffering родителя, т.к. при включенном DoubleBuffering изображение копируется не напрямую в буфер экрана, а в тот же временный битмап родителя (который будет скопирован на экран после отрисовки всех контролов). |
Сообщ.
#4
,
|
|
|
Графика делиться на статическую и динамическую.
Статическую рисуем по событию OnPaint. Закрыли вашу форму другим окном потом показали, виндоус устанавливает регион который следует обновить и вызывает OnPaint. Такое годиться для статически изображений. А вот если вам надо нарисовать в динамике. Тут начинаешь думать как да что. Графика это дело такое тут всегда не хватает производительности. Цитата Jin X @ Т.е. чтобы не надо было перерисовывать каждый раз в OnPaint. TImage рисует в буфере. Все остальные рисуют сразу на экране. Не важно когда и в каком месте программы вы рисуете оно тут же отображается на экране. Что касается двойной буферизации. То она появилась в XE, а до этого ... подзабыл, короче говоря до этого была имитация которая просто убирались фризы. У меня вот векторный редактор сделан на PaintBox.OnPaint и всё нормально бегает: 100 линий + 100 сплайнов + 10 прозрачных-картинок. Никаких оптимизаций специально не делал. Win10 сама со всем сносно справляется. А если вводить кэши из битмапов и отсечения невидимых объектов, то можно ещё в 10 раз поднять. А вот если фильм показывать или анимацию делать. Тога да нужно думать о буферизации. |
Сообщ.
#5
,
|
|
|
Цитата Pavia @ Графика делиться на статическую и динамическую. Статическую рисуем по событию OnPaint. Может наоборот? Какой смысл рисовать статическую графику в OnPaint, если ее можно загнать в TImage.Graphic, и она будет отрисовываться автоматически? Цитата Pavia @ Что касается двойной буферизации. То она появилась в XE, а до этого ... подзабыл ... Никаких оптимизаций специально не делал. Win10 сама со всем сносно справляется. DoubleBuffered появилась еще "с незапамятных времен", когда "деревья были большими", а компьютеры "маленькими" (хилыми по нынешним меркам). С тех времен производительность компов выросла в разы, а требования к времени перерисовки практически не изменились (человеческий глаз моргает также, как и сто\тыщу лет назад). Поэтому и "специальные оптимизации" теряют смысл, т.к. "Win10 сама со всем сносно справляется". |
Сообщ.
#6
,
|
|
|
Всё ясно, всем спасибо
Добавлено Я правильно понял, что после отрисовки в TImage.Canvas выполнять Invalidate/Repaint смысла нет? Все изменения сами отрисуются при первом же "простое"? |