Модераторы: Snowy, MetalFan, bems, Poseidon

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ускорение отрисовки графика 
:(
    Опции темы
Beltar
Дата 14.10.2009, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 0
Всего: 7



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

Суть такая, есть самодельный компонент для отрисовки графиков (ни TeeChart, ни другие бесплатные компоненты меня не устроили).
Порядок отрисовки такой:

Точек для отрисовки может быть несколько десятков тысяч. Наборы точек перед отрисовкой сортируются и не попадающие в диапазон по оси Х отсекаются. Все основное рисование:
Код

for j:=Seria.LeftX to Seria.RightX do
  begin
  P:=ValueToPoint(Seria.FPoints[j]);
  if ((PrevP.X=P.X) and (PrevP.Y=P.Y)) then Continue;
  Canvas.LineTo(P.X,P.Y);
  PrevP.X:=P.X;
  PrevP.Y:=P.Y;
  end;


Отрисовка всего этого дела при толщине линий трендов равной 2 занимает в худшем случае ~600 мс. Что меня не очень устраивает. Как показали замеры, почти все время уходит на Canvas.LineTo соединяющие точки трендов, отрисовка координатной сетки, прочих вспомогательных элементов, рассчеты требуют меньше 32 мс. Можно использовать единичную толщину линий, тогда тренд рисуется раз в 8-10 быстрее, но от возможности настройки отказываться не хочу.

Как можно ускорить? Мне пока в голову приходит только использовать DirectX.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
Alexeis
Дата 14.10.2009, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(Beltar @  14.10.2009,  11:19 Найти цитируемый пост)
Как можно ускорить? Мне пока в голову приходит только использовать DirectX. 

  Если с дровами OpenGL нет проблем, то я бы посоветовал OpenGL. В нем есть функции работы с графикой 2D графикой. DirectX будет работа с 3D. Я сам так делал. Есть также возможности аппаратной отрисовки штриховых линий. Скорость намного выше. 

  Есть более простое решение. Использовать вместо LineTo Polyline и передвать сразу массив вершин. LineTo тормозит из-за издержек на начало рисования и окончание. Polyline производит всего одну операция начала и завершения поэтому скорость будет в n раз выше (где n число точек)


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
~FoX~
Дата 14.10.2009, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 5
Всего: 68



GDI+


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
Beltar
Дата 14.10.2009, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 0
Всего: 7



Цитата

 Есть более простое решение. Использовать вместо LineTo Polyline и передвать сразу массив вершин. LineTo тормозит из-за издержек на начало рисования и окончание. Polyline производит всего одну операция начала и завершения поэтому скорость будет в n раз выше (где n число точек)


Я рассуждая примерно так же, что вдруг хотя бы на вызовах сэкономлю, кинул на форму TPaintBox с парой кнопок:

Код

procedure TForm2.Button1Click(Sender: TObject);
var w,h,i:Integer;
    Canvas:TCanvas;
    t:Cardinal;
begin
w:=PB.Width;
h:=PB.Height;
Randomize;
Canvas:=PB.Canvas;
Canvas.Pen.Width:=2;
t:=GetTickCount;
for i:=0 to D do
  Canvas.LineTo(Random(w-1),Random(h-1));
Label1.Caption:=IntToStr(GetTickCount-t);
end;

procedure TForm2.Button2Click(Sender: TObject);
var w,h,i:Integer;
    Canvas:TCanvas;
    t:Cardinal;
begin
w:=PB.Width;
h:=PB.Height;
Randomize;
Canvas:=PB.Canvas;
Canvas.Pen.Width:=2;
for i:=0 to D do
  begin
  P[i].X:=Random(w-1);
  P[i].Y:=Random(h-1);
  end;
t:=GetTickCount;
Canvas.Polyline(P);
Label1.Caption:=IntToStr(GetTickCount-t);
end;


При D=999 polyline отрабатывала за 172 мс, а цикл с LineTo 32, при D=9999 polyline просто вешает компьютер так, что его потом только ресетом.  smile 

Цитата
  Если с дровами OpenGL нет проблем


Э-э. Вроде они с любыми драйверами видеокарт, даже чипсетками всегда идут?

Вообще с DirectX я пару лет назад ковырялся, даже книжечку купил небезызвестного Миши Фленова, так что в этом плане он немного предпочтительнее OpenGL, который я не ковырял вообще.

Цитата

GDI+


Качнул либы, немного покурил форум, как заставить их работать с 2007.

Код

Randomize;
t:=GetTickCount;
for i:=0 to 9999 do
  PB.Canvas.LineTo(Random(100), Random(100));
Label1.Caption:=IntToStr(GetTickCount-t);


И Label1.Caption=32

Код

Randomize;
GDIPlus := TGPGraphics.Create(PB.Canvas.Handle);
pen:= TGPPen.Create(MakeColor(255, 0, 0, 255));
t:=GetTickCount;
for i:=0 to 9999 do
  GDIPlus.DrawLine(pen, 0, 0, Random(100), Random(100));
GDIPlus.DrawRectangle(pen,20,20,200,200);
GDIPlus.Free;
pen.Free;
Label1.Caption:=IntToStr(GetTickCount-t);


И Label1.Cation=18266 smile Что я делаю не так??

Это сообщение отредактировал(а) Beltar - 14.10.2009, 15:40


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
Alexeis
Дата 14.10.2009, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 34
Всего: 459



Цитата(Beltar @  14.10.2009,  14:39 Найти цитируемый пост)
Э-э. Вроде они с любыми драйверами видеокарт, даже чипсетками всегда идут?

  Ну NVidia и Ati ничего драйвера, а про остальные такого не скажешь. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
~FoX~
Дата 14.10.2009, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


НЕ рыжий!!!
****


Профиль
Группа: Участник Клуба
Сообщений: 2819
Регистрация: 8.10.2003
Где: Зеленоград

Репутация: 5
Всего: 68



Beltar, патрисающе  smile у меня 125 и 750 соответственно...
Тогда могу порекомендовать, рисовать прямо в памяти и по окончании выводить уже готовый битма на какой то контент, это реально быстрее будет работать..


--------------------
user posted image
…множественность никогда не следует полагать без необходимости…
PM MAIL WWW ICQ Jabber   Вверх
Hexel
Дата 22.10.2009, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 30.10.2007
Где: UA

Репутация: нет
Всего: нет



дурацкий вариант, но все же предложу)

рисуешь серию единичной толщины, а потом размножаешь по вертикали копированием с прозрачностью на столько пикселей, сколько нужно)). но так глубоко я в графику не влезал, точные названия процедур не знаю

или чисто графические приемы растушевки (как в фотошопе) - расширения границы выделения. только не спрашивай, как это сделать просто. поищи в исходниках фотошопа   smile 
PM MAIL   Вверх
AntonN
Дата 22.10.2009, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



рисуйте не на canvas, а на буферном Tbitmap.canvas, который по окончании выводите на тот самый canvas


--------------------
user posted image
PM MAIL WWW   Вверх
Beltar
Дата 22.10.2009, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 0
Всего: 7



Попиксельный доступ, это вообще ужас будет. Я на выходных повспоминал, чего там с DirectX делать, вспомнил про буфер индексов, мне стало грустно от всех этих сложностей, с OpenGL вроде легче получается. Пока сей вопрос решил отложить, установив линии единичной толщины по умолчанию, что вроде как всех устраивает и реализовывать остальной функционал проекта, мне там до конца годы работы должно хватить. Потом скорее всего, попробую на OpenGL отрисовку повесить.

Цитата

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


А не то же самое обеспечивает свойство DoubleBuffered? Впрочем еще поэксперементирую.

Это сообщение отредактировал(а) Beltar - 22.10.2009, 17:16


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
Hexel
Дата 22.10.2009, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 30.10.2007
Где: UA

Репутация: нет
Всего: нет



Beltar, ты, наверное, не понял сути первого предложения, попробую объяснить проще.

строишь на прозрачном канвасе (в буфер) график единичной толщины. потом процедурой типа BitBlt копируешь его ВЕСЬ, а не попиксельно, например, по вертикали со сдвигом на 1 пиксель (вверх или вниз). в итоге у тебя получится график толщиной в 2 пикселя. сколько раз выполнишь этот шаг, такой толщины у тебя и будет линия.

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

на крайняк, скинь мне исходник, если хочешь. ту часть, которая отвечает за вывод графики, может помогу.
PM MAIL   Вверх
AntonN
Дата 23.10.2009, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



Hexel, тормозить будет больше, чем рисовать одинарную линию 2 раза со сдвигом в нужную сторону (по перпендикуляру к линии) средствами canvas.lineto()


--------------------
user posted image
PM MAIL WWW   Вверх
Hexel
Дата 23.10.2009, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 30.10.2007
Где: UA

Репутация: нет
Всего: нет



Beltar, можно размеры канваса, количество точек, вид графика, тип системы координат? 

сам попробую, а то что-то не верится, что построить 50000 точек lineto быстрее, чем скопировать изображение растровыми методами
PM MAIL   Вверх
AntonN
Дата 23.10.2009, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 3
Всего: 18



Hexel,  на картинке 100х100 будет 10к точек которые ты будешь перебирать при построении каждой линии? к тому же "скопировать" понятие размытое, что будет если нужно будет построить 200 цветных линий под разными углами друг у другу, алгоритм твой не сдуется? smile


--------------------
user posted image
PM MAIL WWW   Вверх
Hexel
Дата 23.10.2009, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 73
Регистрация: 30.10.2007
Где: UA

Репутация: нет
Всего: нет



хорошо. не буду голословным. раз уж меня не понимают со слова, выражусь более кратко

(конкретную буфферизацию я не умею делать, но думаю, вы поймете идею)

Присоединённый файл ( Кол-во скачиваний: 8 )
Присоединённый файл  GraphicsTest1.rar 8,33 Kb
PM MAIL   Вверх
Beltar
Дата 23.10.2009, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 627
Регистрация: 11.1.2006

Репутация: 0
Всего: 7



Прежде чем скопировать изображение с битмепа на битмеп, его надо еше сначала на буферном битмепе нарисовать. Код завтра дооформлю и если хочешь могу выложить. График предназначен для отрисовки архивных параметров технологических процессов, потому система координат декартова, но с нулем в углу, а вероятность попадания соседних замеров в одну экранную точку очень высокая, к сожалению при росте разршения она резко уменьшается.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. smile(с) я, хотя может и нет
Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0617 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.