![]() |
|
Модераторы: Snowy, MetalFan, bems, Poseidon |
![]()
|
|
| Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
Прошу прощения, что создаю тему в этом разделе, но раздел для графики мне сейчас просто недоступен из-за каких-то идиотизмов в настройке нашей корпоративной системы безопасности и экономии трафика, которая похоже принимает его за развлекательный сайт.
Суть такая, есть самодельный компонент для отрисовки графиков (ни TeeChart, ни другие бесплатные компоненты меня не устроили). Порядок отрисовки такой: Точек для отрисовки может быть несколько десятков тысяч. Наборы точек перед отрисовкой сортируются и не попадающие в диапазон по оси Х отсекаются. Все основное рисование:
Отрисовка всего этого дела при толщине линий трендов равной 2 занимает в худшем случае ~600 мс. Что меня не очень устраивает. Как показали замеры, почти все время уходит на Canvas.LineTo соединяющие точки трендов, отрисовка координатной сетки, прочих вспомогательных элементов, рассчеты требуют меньше 32 мс. Можно использовать единичную толщину линий, тогда тренд рисуется раз в 8-10 быстрее, но от возможности настройки отказываться не хочу. Как можно ускорить? Мне пока в голову приходит только использовать DirectX. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 34 Всего: 459 |
Если с дровами OpenGL нет проблем, то я бы посоветовал OpenGL. В нем есть функции работы с графикой 2D графикой. DirectX будет работа с 3D. Я сам так делал. Есть также возможности аппаратной отрисовки штриховых линий. Скорость намного выше. Есть более простое решение. Использовать вместо LineTo Polyline и передвать сразу массив вершин. LineTo тормозит из-за издержек на начало рисования и окончание. Polyline производит всего одну операция начала и завершения поэтому скорость будет в n раз выше (где n число точек) -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| ~FoX~ |
|
|||
![]() НЕ рыжий!!! ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2819 Регистрация: 8.10.2003 Где: Зеленоград Репутация: 5 Всего: 68 |
GDI+
|
|||
|
||||
| Beltar |
|
||||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
Я рассуждая примерно так же, что вдруг хотя бы на вызовах сэкономлю, кинул на форму TPaintBox с парой кнопок:
При D=999 polyline отрабатывала за 172 мс, а цикл с LineTo 32, при D=9999 polyline просто вешает компьютер так, что его потом только ресетом.
Э-э. Вроде они с любыми драйверами видеокарт, даже чипсетками всегда идут? Вообще с DirectX я пару лет назад ковырялся, даже книжечку купил небезызвестного Миши Фленова, так что в этом плане он немного предпочтительнее OpenGL, который я не ковырял вообще.
Качнул либы, немного покурил форум, как заставить их работать с 2007.
И Label1.Caption=32
И Label1.Cation=18266 Это сообщение отредактировал(а) Beltar - 14.10.2009, 15:40 -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
||||||||||||
|
|||||||||||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 34 Всего: 459 |
Ну NVidia и Ati ничего драйвера, а про остальные такого не скажешь. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| ~FoX~ |
|
|||
![]() НЕ рыжий!!! ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2819 Регистрация: 8.10.2003 Где: Зеленоград Репутация: 5 Всего: 68 |
Beltar, патрисающе
Тогда могу порекомендовать, рисовать прямо в памяти и по окончании выводить уже готовый битма на какой то контент, это реально быстрее будет работать.. |
|||
|
||||
| Hexel |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 30.10.2007 Где: UA Репутация: нет Всего: нет |
дурацкий вариант, но все же предложу)
рисуешь серию единичной толщины, а потом размножаешь по вертикали копированием с прозрачностью на столько пикселей, сколько нужно)). но так глубоко я в графику не влезал, точные названия процедур не знаю или чисто графические приемы растушевки (как в фотошопе) - расширения границы выделения. только не спрашивай, как это сделать просто. поищи в исходниках фотошопа |
|||
|
||||
| AntonN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 3 Всего: 18 |
рисуйте не на canvas, а на буферном Tbitmap.canvas, который по окончании выводите на тот самый canvas
|
|||
|
||||
| Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
Попиксельный доступ, это вообще ужас будет. Я на выходных повспоминал, чего там с DirectX делать, вспомнил про буфер индексов, мне стало грустно от всех этих сложностей, с OpenGL вроде легче получается. Пока сей вопрос решил отложить, установив линии единичной толщины по умолчанию, что вроде как всех устраивает и реализовывать остальной функционал проекта, мне там до конца годы работы должно хватить. Потом скорее всего, попробую на OpenGL отрисовку повесить.
А не то же самое обеспечивает свойство DoubleBuffered? Впрочем еще поэксперементирую. Это сообщение отредактировал(а) Beltar - 22.10.2009, 17:16 -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
| Hexel |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 30.10.2007 Где: UA Репутация: нет Всего: нет |
Beltar, ты, наверное, не понял сути первого предложения, попробую объяснить проще.
строишь на прозрачном канвасе (в буфер) график единичной толщины. потом процедурой типа BitBlt копируешь его ВЕСЬ, а не попиксельно, например, по вертикали со сдвигом на 1 пиксель (вверх или вниз). в итоге у тебя получится график толщиной в 2 пикселя. сколько раз выполнишь этот шаг, такой толщины у тебя и будет линия. копировать можно и по горизонтали, и по диагонали. это смотря, какой вид графика? разрывный? гладкий, без завитушек? какая система координат, прямоугольная или полярная? на крайняк, скинь мне исходник, если хочешь. ту часть, которая отвечает за вывод графики, может помогу. |
|||
|
||||
| AntonN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 3 Всего: 18 |
Hexel, тормозить будет больше, чем рисовать одинарную линию 2 раза со сдвигом в нужную сторону (по перпендикуляру к линии) средствами canvas.lineto()
|
|||
|
||||
| Hexel |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 30.10.2007 Где: UA Репутация: нет Всего: нет |
Beltar, можно размеры канваса, количество точек, вид графика, тип системы координат?
сам попробую, а то что-то не верится, что построить 50000 точек lineto быстрее, чем скопировать изображение растровыми методами |
|||
|
||||
| AntonN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 3 Всего: 18 |
Hexel, на картинке 100х100 будет 10к точек которые ты будешь перебирать при построении каждой линии? к тому же "скопировать" понятие размытое, что будет если нужно будет построить 200 цветных линий под разными углами друг у другу, алгоритм твой не сдуется?
|
|||
|
||||
| Hexel |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 30.10.2007 Где: UA Репутация: нет Всего: нет |
хорошо. не буду голословным. раз уж меня не понимают со слова, выражусь более кратко
(конкретную буфферизацию я не умею делать, но думаю, вы поймете идею) Присоединённый файл ( Кол-во скачиваний: 8 )
GraphicsTest1.rar 8,33 Kb |
|||
|
||||
| Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
Прежде чем скопировать изображение с битмепа на битмеп, его надо еше сначала на буферном битмепе нарисовать. Код завтра дооформлю и если хочешь могу выложить. График предназначен для отрисовки архивных параметров технологических процессов, потому система координат декартова, но с нулем в углу, а вероятность попадания соседних замеров в одну экранную точку очень высокая, к сожалению при росте разршения она резко уменьшается.
-------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
| Hexel |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 30.10.2007 Где: UA Репутация: нет Всего: нет |
еще раз повторюсь: я не умею рисовать на буферном битмапе, поэтому для наглядности метода просто взял 2 паинт бокса
ну хоть теперь я ясно выразил свою идею? ЗЫ: если не сложно, выклади свой замер производительности. а то мне сложно судить, у меня атлон х2 4200 (2.2ГГц) х ДДР2 800МГц и как вообще эта произодительность замеряется? gettickcount? Это сообщение отредактировал(а) Hexel - 24.10.2009, 00:09 |
|||
|
||||
| Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
Попробовал я порисовать на буферном битмепе, результат поразителен отсутствием какой-либо разницы от рисования сразу на PaintBox'е, при отключении отрисовки, ни синусы, ни создание и удаление большого битмепа не смогли занять одно ядро E-4500 (2.2 HHz) на время большее времени выделяемому процессу.
2 Hexel: Сырец контрола можешь посмотреть. D 2007 Эксперементировал я с твоим примером, получилось вот что. Присоединённый файл ( Кол-во скачиваний: 6 )
AvgChart.rar 9,06 Kb-------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
| Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
Второй аттач. Да, в контроле там много чего inline помечено, без них по идее должно скомпилиться в семерке, а может и нет.
Присоединённый файл ( Кол-во скачиваний: 6 )
GraphicsTest1.rar 11,64 Kb-------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
| Hexel |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 30.10.2007 Где: UA Репутация: нет Всего: нет |
да, щас скачаю, погляжу. кстати, нашел, как рисовать в буферном битмапе, но разницы не заметил)))
вот ято я хотел сказать после некоторых размышлений. для технической задачи: 1) лучше применить векторную графику. лучше выглядит, проще обрабатывается (например, масштабируется, анализируется), и, главное, легче всего подготавливается в печать. 2) не знаю, что у тебя за график, но иногда его выгодно апроксимировать какой-то функцией, нас так в универе учили. если надо - помогу, у меня с математикой проблем нет. такая фича позволяет устранить посторонние шумы, например несистемные ошибки измерений (график выглядит более гладким). такой график, кстати, можно рисовать кривой Безье, буквально за несколько вызовов. по второму с выводом не спеши, посоветуйся со спецами Добавлено через 10 минут и 16 секунд Delphi6 нискампилил инлайны поубивал (я, кстати, и не знаю, что это), но обламался на
([Error] AvgChart.pas(180): Undeclared identifier: 'TFormatSettings') меня вот мучит вопрос: а что такого прикольного в новых IDE, помимо компонент, которые можно скачать с инета? до сих пор моей 6 мне хватало с головой, еще и оставалось |
|||
|
||||
| Hexel |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 30.10.2007 Где: UA Репутация: нет Всего: нет |
насчет моего метода - да, разница в скорости есть. 500 тиков (мс?) для рисования толщиной 5, и 46 тиков для рисвания той же толщиной (или толщиной 50) с помощью CopyRect. в буфер, потом на паинтбокс
Добавлено через 3 минуты и 6 секунд при том, как оказалось, ВСЕ это время уходит на LineTo )))) |
|||
|
||||
| Beltar |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
Так, я-таки решил сделать отрисовку диаграммы на буферном битмепе.
В интересующих случаях (из MouseMove, MouseUp и Click контрола) FastRepaint вызывается напрямую, в отличие от пред. версии ничего не лагает, но зато неприлично мерцает. Все, что после Canvas.Draw(0,0,Bmp); никакого влияния на мерцание не оказывает. Как побороть? -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
||||
|
|||||
| AntonN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 3 Всего: 18 |
вместо Canvas.Draw() юзать сразу BitBlt().
что такое вот это?
вся идея в том, чтобы вообще все рисовать на буфере. Если рисование подложки графика ресурсовемко и нечастое, можно использовать два буфера, на первом рисовать подложку, на второй его копировать и наносить маркеры. Если мало - три буфера В итоге вывод на форму будет краток - один вызов BitBlt() |
|||
|
||||
| Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
Обошелся двумя буферами, итоговый код FastRepaint:
В кишках всех этих DrawSomething просто перед каждый канвасом приписал Bmp1. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
| AntonN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 3 Всего: 18 |
ты создаешь каждый раз битмап, но не удаляешь его.
а буферные битмапы и есть буферизация |
|||
|
||||
| Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
if Assigned(Bmp1) then Bmp1.Free; Если бы тут текло, то у меня, наверное, оперативки хватило бы на несколько минут максимум т. к. терять при каждом движении мышки с зажатой кнопкой экземпляр битмепа размером в пару метров должно быть приличным экстримом. Х) Хотя при разрушении компонента действительно забыл. -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
| AntonN |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 3 Всего: 18 |
Я не посмотрел, думал он локально используется. Тогда и смысла нет его каждый раз пересоздавать, создай при создании формы один раз, да и усе
|
|||
|
||||
| Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 0 Всего: 7 |
Там лажа с неочисткой битмепа получалась, поэтому не мудрствуя лукаво сделал так.
-------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
| Mikel |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 882 Регистрация: 30.3.2002 Где: Саратов Репутация: нет Всего: 2 |
Для начала попробуй все рисовать в отдельном bitmap буфере, потом bitblt на paintbox. И кстати, зачем рисовать несколько десятков тысяч точек на дисплее с разрешением по Х порядка тысячи точек? Если график на столько подробный, можно рисовать прямо в памяти битмапа, без обращения к APIшному SetPixel. А вообще подумайте стоит ли их все рисовать
-------------------- ...so remember, it's better to burn out than to fade away |
|||
|
||||
![]()
|
| Правила форума "Delphi: Для новичков" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Для новичков | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |