Как ускорить прорисовку векторной графики ?
Модератор: Модераторы
А что мешает по Z координате сортировать?
Ничего. в 2д случае это не координата как таковая, а порядок отрисовки
Понял..
На TBitmap-е рисуете графику, потом BitBlt обновляете.
Чё то думал, что на панели расположены были контролы.
На TBitmap-е рисуете графику, потом BitBlt обновляете.
Чё то думал, что на панели расположены были контролы.
>>На TBitmap-е рисуете графику, потом BitBlt обновляете.
У меня не получилось использовать TBitmap. Подробностей не помню, но битмап у меня получался в озу, а не в видеопамяти, соответственно запоминание-восстановление изображения приводило к ненужному перегону мегобайтиков между процом и видюхой (у ТС судя по всему проблема таже, раз ему это чувствительно и жалуется на зависимость времени от разрешения). Потыкавшись написал свой контрол для этих целей на основе LCLной реализации GDI, пусть кривой но зато с полным контролем процесса отрисовки.
Кстати GDI в LCL кроссплатформенно, а вот метафайлы емнип нет, Alex2013 чтоб потом для тебя сюрпризом небыло, когда под линь компильнуть решишь))
У меня не получилось использовать TBitmap. Подробностей не помню, но битмап у меня получался в озу, а не в видеопамяти, соответственно запоминание-восстановление изображения приводило к ненужному перегону мегобайтиков между процом и видюхой (у ТС судя по всему проблема таже, раз ему это чувствительно и жалуется на зависимость времени от разрешения). Потыкавшись написал свой контрол для этих целей на основе LCLной реализации GDI, пусть кривой но зато с полным контролем процесса отрисовки.
Кстати GDI в LCL кроссплатформенно, а вот метафайлы емнип нет, Alex2013 чтоб потом для тебя сюрпризом небыло, когда под линь компильнуть решишь))
Alex2013 писал(а):Просто TMetafile (+ Еще и скрипты) неизбежное зло с которым более мене понятно что делать (или не делать если все более или менее но утраивает )... Вот явно непропорциональные тормоза при увеличении разрешения рабочего поля напрягают. (Тем боле что ничего похожего во многих программах нет )
прорисовка элементов в TMetafile и из TMetafile в общий TMetafile, А это зачем ?У меня цикл сразу выводит отдельные "Metafile" на теневой битмап который потом копируется на канвас ПаинтБокса ... Хотя если подумать возможно будет реально быстрее ( за счет того, что Metafile может не иметь заранее заданных границ и не передает лишних "пустых "данных) . Но мне показалась, что если я буду рисовать метофайлы на прямую то будет видно как и куда "процесс пошел " что не есть хорошо .
У нас двойной вывод элементов в TMetafile и из TMetafile в общий TMetafile и далее в TBitmap используются для того:
1. Metafile элемента формируется один раз до изменения конкретного элемента (рисование примитивов один раз за весь период работы программы).
2. На этапе сборки общего Metafile идет отсеивание элементов, не входящих в видимую область. Работает быстро, т.к. по сути Metafile - это коллекция векторных примитивов, и добавляя в коллекцию другую готовую коллекцию никакой перерисовки и не происходит.
3. На этапе вывода общего Metafile в теневой Bitmap осуществляется масштабирование и обрезание строго по границам экрана.
Если все работало быстро на старых компах на разрешениях (1280*1024, 1600*1200 и более высоких), то на современных компах на самых больших мониторах число точек больше всего примерно в 4 раза, то и никаких особых тормозов тоже не наблюдается. Мы еще лет 7 тому назад в одном проекте работали с видеокартой AMD, к которой было подключено 6 мониторов по 1920*1080 повернутых на 90 гр (общее разрешение 6480 на 1920). Особых тормозов не было еще тогда, не говоря о сегодняшнем железе. Да и откуда им быть. Даже на таком разрешении размер TBitmap всего 48 Мб (4 байта на пиксель) - это копейки для оперативной памяти при частотах в несколько ГГц.
Поэтому тормозить операции с Bitmap не могут по определению, искать там выигрыш в микросекунды или даже в миллисекунды бессмысленно. Тормозить может только вывод векторной графики. Если у Вас масштаб не меняется часто, а графических примитивов очень и очень много, то элементы можно из элементного TMetafile можно переводить в TBitmap.
Данная схема либо требует от графической системы поддержки трансформаций, либо подходит только для статичных "картинок". Соглашусь с Alex2013 в векторном редакторе, где всё постоянно зумится и панится общий метафайл лишний - очень большая вероятность того что при следующей отрисовке он будет неактуален, например в кадр попадет чтото что раньше было невидимо и наоборот, ранее видимые примитивы уйдут за преджелы экрана
zub писал(а):Данная схема либо требует от графической системы поддержки трансформаций, либо подходит только для статичных "картинок". Соглашусь с Alex2013 в векторном редакторе, где всё постоянно зумится и панится общий метафайл лишний - очень большая вероятность того что при следующей отрисовке он будет неактуален, например в кадр попадет чтото что раньше было невидимо и наоборот, ранее видимые примитивы уйдут за преджелы экрана
Я как раз про векторный редактор и говорю. Общий метафайл, как посредник перед общим битмапом - это не панацея, но нам было так проще, а возможно было даже быстрее (делали 15 лет тому назад, всех нюансов уже не помню, пробовали разные варианты, остановились на этом). Вывод метафайла в метафайл практически не занимает времени, т.к. как таковой отрисовки при этом не происходит, происходит копирование списка графических примитивов из одной коллекции в другую.
Учитывая, что мы делали во времена, когда графическая подсистема была очень примитивной, то никаких функций ускорителей не использовалось (таково было железо тех времен), но работало все достаточно быстро.
Я говорю не о теоретических рассуждениях и предположениях, а о реальной практической реализации векторного редактора и векторного визуализатора. Этот путь был нами выбран на основании сравнения разных вариантов. Это вариант оказался самым быстрым, т.к. в те времена быстродействие было критически важным.
Ок пусть будет общий метафайл. Но это только технический момент - способ скармливания большого числа примитивов в GDI, причем не везде он присутствует.
Отталкиваться надо от алгоритмов, а не от деталей реализации
Отталкиваться надо от алгоритмов, а не от деталей реализации
про какой метафайл вы говорите?
про TMetafile? А он еще используется?
про TMetafile? А он еще используется?
- serbod
- постоялец
- Сообщения: 449
- Зарегистрирован: 16.09.2016 10:03:02
- Откуда: Минск
- Контактная информация:
Пересечения легко вычислять по пикселям:
https://habrahabr.ru/post/202888/
https://code.tutsplus.com/tutorials/pix ... tive-10862
https://habrahabr.ru/post/202888/
https://code.tutsplus.com/tutorials/pix ... tive-10862
Операции с пикселями на CPU - главный тормоз. Будте любезны на GPU в шейдеры, если есть такая нужда
Вчера ушел в глубокий офлайн и сделал два полезных дела:
1 Выделил работу с метафайлами в отделенную процедуру.
2 Окончательно подавил мерцание при рисовании мышкой...
И вот с этим возникли странные трудности ( Пока не нашел ничего лучшего чем сделать еще один буфер )
Тормозов вроде не наблюдается ... но изначально я думал сделать значительно менее ресурсоёмко .
1 Включить для фонового битмапа mpNotXor
2 Нарисовать фигуру на фоновом битмапе ( именно на фоновом !...дабы сей замечательный процесс видно не было ...)
3 Вывести на экран ...(ReStoreBuf; )
4 Снова нарисовать фигуру на фоновом битмапе (то бишь затереть то что было нарисовано первым проходом )
5 Вернуть для фонового битмапа mpСоpy ...
...и "Ку вам товарищ четланин" ничего не фурычит как ни бился ...
Посему вопрос, какого лешего это вообще даже в принципе может не работать
Там же все "тупо как сибирский валенок" ... 
Еще вариант нарисовать фигуру на пустом битмапе как "спрайт " и сложить фоновым но это уже явный тормоз (при создании битмапа его нужно ресайзить и/или чистить )
Добавлено спустя 53 минуты 12 секунд:
Я думаю что все дело как раз в особенностях реализации .
Например у меня есть идея рисовать на метофалах все с нуля координат (добавляя смещение дополнительным параметром ).
Вроде "деталь реализации" но логику она может изменить очень сильно.
Добавлено спустя 1 час 2 минуты 33 секунды:
Почему это ? Я использую модуль MyMetaFile от сюда http://wiki.freepascal.org/TMetafile_/_ ... leCanvas...
Гм действительно "only works on windows" но возможно это верно для старой версии лазруса (Там многое из того что сейчас вполне работает даже не компилировалось )...
Да и вообще это не единственная реализация (я даже где-то в дебрях LCL что-то похожее видел )
1 Выделил работу с метафайлами в отделенную процедуру.
Код: Выделить всё
// Быстрая прорисовка призвольного фрагмента DrawList
// на CurCanvas
procedure TRF1.FastDrawFig(PosInList,FigCount:LongInt);
var I:Integer;
MC:TMetafileCanvas;
MyMetafile: TMetafile;
SaveCanvas:TCanvas;
FADD:Boolean;// Флаг для наглядого представления условий
Const
FMD:Boolean=True; // Флаг первого запуска
begin
// Ограничения
if DrawList=NIL then exit;
if DrawList.Count = 0 then exit;
If FigCount < 0 then exit;
If PosInList < 0 then exit;
If PosInList > DrawList.Count-1 then exit;
If PosInList+FigCount > DrawList.Count then
FigCount:= DrawList.Count-PosInList;
//Если список не пуст ...
SaveCanvas:=CurCanvas;
// проверка и создание MetaDrawList и ShadowDrawList ;
If MetaDrawList = Nil Then MetaDrawList:=Tlist.Create ;
If ShadowDrawList = Nil Then Begin ShadowDrawList:=TStringlist.Create ;
ShadowDrawList.Text:=DrawList.Text;
end;
// Главный цикл
For I:=PosInList TO PosInList+FigCount -1 DO
Begin
FADD :=FmD Or (I > ShadowDrawList.Count-1);
FADD := FADD Or (I > MetaDrawList.Count-1);
FADD := FADD Or (ShadowDrawList[I] <> DrawList[I]);
If FADD Then
begin
// Инициализирую метафайл ...
MyMetafile := TMetafile.Create;
MC:= TMetafileCanvas.CreateWithComment(MyMetafile, BufBMP.Canvas.handle,
'Author', 'Made This');
CurCanvas:=MC;//Перенаправляю Canvas
DrawFig(-1,DrawList[i]);//Рисую фигуру
MC.Free; //! Обязательно очищать MetafileCanvas преред "клонированием" ...
CurCanvas:=SaveCanvas;// Востанавливаю Canvas...
// Доплнение изменение списка MetaDrawList
//----------------------------------------
If FmD then MetaDrawList.Add(MyMetafile)
// Первый раз безусловное добавление
else
if I<=MetaDrawList.Count-1 then
// Простая замена в границах списка
begin
TMetafile(MetaDrawList[i]).Free;
MetaDrawList[i]:=MyMetafile;
end
else
if I=MetaDrawList.Count then
// Добавить в конец списка если на единцу бльше
MetaDrawList.Add(MyMetafile);
//=================================================
CurCanvas.Draw(0,0,TMetafile(MetaDrawList[i])); //draw
end else
begin
CurCanvas.Draw(0,0,TMetafile(MetaDrawList[i])); //fast draw
end
end ;
FMD:=False ;// Сброс флага
ShadowDrawList.Text:=DrawList.Text; // Сбросить различия
Listbox1.Items.Text:=DrawList.Text; //? Освежить видимый список комманд
end;
2 Окончательно подавил мерцание при рисовании мышкой...
И вот с этим возникли странные трудности ( Пока не нашел ничего лучшего чем сделать еще один буфер )
Код: Выделить всё
// Защита от мерцания
If b1=nil then B1:=TBitmap.Create;
B1.Assign(BufBMP);// сохраняю теневой битмап
//кстати это еще один способ быстрого копирования между битмапами
CurCanvas :=BufBmp.Canvas;
FastDrawFig(DrawList.Count-1,1);// рисую на нем ...
ReStoreBuf; // "Восстанавливаю" картинку ( то есть рисую в месте с фигурой )
CurCanvas:=PaintBox1.Canvas;
CurCanvas.Refresh;
BufBMP.Assign(B1); // ...и командую "тень знай свое место "... :wink:
b1.FreeImage;
//--------------------------------------
Тормозов вроде не наблюдается ... но изначально я думал сделать значительно менее ресурсоёмко .
1 Включить для фонового битмапа mpNotXor
2 Нарисовать фигуру на фоновом битмапе ( именно на фоновом !...дабы сей замечательный процесс видно не было ...)
3 Вывести на экран ...(ReStoreBuf; )
4 Снова нарисовать фигуру на фоновом битмапе (то бишь затереть то что было нарисовано первым проходом )
5 Вернуть для фонового битмапа mpСоpy ...
...и "Ку вам товарищ четланин" ничего не фурычит как ни бился ...
Еще вариант нарисовать фигуру на пустом битмапе как "спрайт " и сложить фоновым но это уже явный тормоз (при создании битмапа его нужно ресайзить и/или чистить )
Добавлено спустя 53 минуты 12 секунд:
zub писал(а):Ок пусть будет общий метафайл. Но это только технический момент - способ скармливания большого числа примитивов в GDI, причем не везде он присутствует.
Отталкиваться надо от алгоритмов, а не от деталей реализации
Я думаю что все дело как раз в особенностях реализации .
Например у меня есть идея рисовать на метофалах все с нуля координат (добавляя смещение дополнительным параметром ).
Вроде "деталь реализации" но логику она может изменить очень сильно.
Добавлено спустя 1 час 2 минуты 33 секунды:
zub писал(а):>>На TBitmap-е рисуете графику, потом BitBlt обновляете.
Кстати GDI в LCL кроссплатформенно, а вот метафайлы емнип нет, Alex2013 чтоб потом для тебя сюрпризом небыло, когда под линь компильнуть решишь))
Почему это ? Я использую модуль MyMetaFile от сюда http://wiki.freepascal.org/TMetafile_/_ ... leCanvas...
Гм действительно "only works on windows" но возможно это верно для старой версии лазруса (Там многое из того что сейчас вполне работает даже не компилировалось )...
Да и вообще это не единственная реализация (я даже где-то в дебрях LCL что-то похожее видел )
Последний раз редактировалось Alex2013 13.11.2016 14:46:55, всего редактировалось 1 раз.
>>1 Выделил работу с метафайлами в отделенную процедуру.
>>2 Окончательно подавил мерцание при рисовании мышкой...
Ты собираешся постить на форуме каждый чих? Для этого есть комменты к комитам системы контроля версий.
Фигово ты както выделил - какието глобальные переменные остались
>> но возможно это верно для старой версии лазруса
)) метафайлы - часть GDI, их нет нет под линуксом.
>>Да и вообще это не единственная реализация
Это не реализация а интерфейс к функциям gdi
>>2 Окончательно подавил мерцание при рисовании мышкой...
Ты собираешся постить на форуме каждый чих? Для этого есть комменты к комитам системы контроля версий.
Фигово ты както выделил - какието глобальные переменные остались
>> но возможно это верно для старой версии лазруса
)) метафайлы - часть GDI, их нет нет под линуксом.
>>Да и вообще это не единственная реализация
Это не реализация а интерфейс к функциям gdi
zub писал(а):Ты собираешся постить на форуме каждый чих? Для этого есть комменты к комитам системы контроля версий.
Фигово ты както выделил - какието глобальные переменные остались
Не каждый, а только на сабжевую тему ...
(И есть мысль что моя "наскальная живопись" может кому-то немного помочь ... А тот код, что я постил сюда ранее слишком уж "локальный"(привязан к моей программе ) чтобы в нем было просто разобраться .(Эта версия тоже не лишена "локальности" но факт что она значительно понятнее)
Что до второй части то я запостил ее просто для того чтобы не создавать новой темы из за такой ерунды .
(Да и близко довольно к теме : мерцание нужно победить по возможности не теряя скорости )
Зы
метафайлы - часть GDI, их нет нет под линуксом.
И что эмулировать на уровне канваса никак нельзя ?
>>И что эмулировать на уровне канваса никак нельзя ?
(Там же просто запись команд в формате WMF вместо реального рисования )
Тебе и карты в руки))
http://msdn.microsoft.com/en-us/library/cc250370.aspx
http://wvware.sourceforge.net/caolan/ora-wmf.html
http://www.symantec.com/avcenter/refere ... format.pdf
>>(Да и близко довольно к теме : мерцание нужно победить по возможности не теряя скорости )
Дак оно прекрасно побеждается без потерь производительности. Такими кусками кода ты общаешся сам с собой. Есть проблема - делаешь минимальную демку ее демонстрирующую
Тебе и карты в руки))
http://msdn.microsoft.com/en-us/library/cc250370.aspx
http://wvware.sourceforge.net/caolan/ora-wmf.html
http://www.symantec.com/avcenter/refere ... format.pdf
>>(Да и близко довольно к теме : мерцание нужно победить по возможности не теряя скорости )
Дак оно прекрасно побеждается без потерь производительности. Такими кусками кода ты общаешся сам с собой. Есть проблема - делаешь минимальную демку ее демонстрирующую
