![]() |
Модераторы: Snowy, Alexeis, MetalFan |
![]() ![]() ![]() |
|
RESIN |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.10.2010 Репутация: нет Всего: нет |
Здравствуйте уважаимые!
Очень нужна помощь. Имеется двумерный массив значений цветов пикселей Picture[y, x] типа array of array of longint. Массив достаточно большой, ~3000х3000 значений (=пикселей). Требуется сравнительно быстро ( > 30 кадров в секунду) выводить этот массив на любой графический компонент (по вашему усмотрению), который позволит создать события OnDblKlick, OnMouseMove, OnMouseDown и OnMouseUp. К тому же нужно, чтобы алгоритм вывода был не чувствителен к изменению размеров и позиции выбранного компонента, а при изменении позиции (Left и Top) изображение не "мерцало". Уже пробовал Scanline-ами, BitBlt-ом, Handle-ом, QCanvas-ом (на ассемблере). Тормозит до жути. ![]() С OpenGL не разобрался до конца, сам дошел только до вот такого извращения:
Но это дебилизм полнейший, хоть и работает (иногда появляются вертикальные черные полоски толщиной 1px). Пожалуйста, помогите решить задачу с учетом того, что выводить нужно ИМЕННО двумерный массив, описанный мной в пользовательских типах., не битмап, не спрайт, не PNGObject, а именно массив. Буду крайне рад готовому примеру (ну эт я уже обнаглел ![]() Готов рассмотреть любые варианты: GDI, OpenGL, DirectX (DirectDraw) и любой другой. Это сообщение отредактировал(а) RESIN - 7.12.2010, 04:04 |
|||
|
||||
x128 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 29.9.2009 Репутация: 5 Всего: 7 |
1) Массив полностью обновляется >30 раз в секунду? 2) Что подразумевается под "не чувствителен к изменению размеров и позиции выбранного компонента", нужно выводить определенную часть массива? |
|||
|
||||
Bitter |
|
|||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: 6 Всего: 27 |
Можешь использовать устаревший DIrectDraw, но хоть он и устарел, он именно для этих целей и очень простой. В общем он для быстрого копирования растра на экран.
|
|||
|
||||
RESIN |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.10.2010 Репутация: нет Всего: нет |
to x128:
Полностью обновляется >90 раз в секунду. Массив может менять свои размеры в зависимости от заданного масштаба. В програме так же доступен скроллинг. По-этому при выводе компонент должен менять свой размер, а при скроллинге - позицию. to Bitter: А как это сделать? Подскажите, пожалуйста. И где взять SDK DirectDraw для Delphi. |
|||
|
||||
Bitter |
|
|||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: 6 Всего: 27 |
скачай книгу М Краснова "DitectX Графика в проектах Delphi". Вот ссылка. http://www.delphilab.ru/files/book/krasnov_dx.7z К ней прилагаются и примеры и модули для подключения DirectX. Там первая половина книги как раз про DirectDraw, но тебе не нужна вся половина, тебе достаточно будет несколько первых глав.
|
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Нет смысла рисовать чаще чем 30 раз в секунду. Лишние затраты будут. По поводу скорости, то можно попробовать SetDIBitsToDevice -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
RESIN |
|
||||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.10.2010 Репутация: нет Всего: нет |
Спасибо большое, Bitter! Скачал, разбираюсь, нравится.
Правда уже при попытке запустить пример Ex10 из Chapter02 возникла проблема. Впринципе, не важно, какой пример, CodGear Rad 2009 ругается на строку #173 в модуле DirectDraw.pas:
Пишет: [DCC Error] DirectDraw.pas(173): E2154 Type 'IDirectDrawSurface' needs finalization - not allowed in variant record Не знаешь, как решить сию проблему?
Чаще и не нужно )) Просто сейчас я иногда не получаю и 15 кадров в сек., и это косяк именно вывода на экран (проверял). По поводу SetDIBitsToDevice - а она правда сможет принять в качестве параметра мой массив? Это сообщение отредактировал(а) RESIN - 7.12.2010, 17:54 |
||||
|
|||||
Bitter |
|
||||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: 6 Всего: 27 |
RESIN, попробуй написать вместо
вот так:
а если он тебе понадобится, то использовать приведение типов. но я думаю не понадобится Добавлено через 1 минуту и 47 секунд По поводу той ошибки, я так понял, что в делфи 2010 (как и в Делфи 5) нельзя включать COM объекты в вариантные записи, бла бла бла и так далее |
||||
|
|||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Нет конечно, но операция копирования байтов в DIB Bitmap не такая уж трудоемкая по сравнению с операцией вывода на экран (по времени) средствами GDI. На самом деле это отнимет времени не превышающего 10% от времени отрисовки (зависит от производительности процессора), поэтому ею можно пренебречь. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
AntonN |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 7 Всего: 18 |
А вы найдете такой монитор, чтобы вывести все 3000*3000 пикселей?
Вывод на экран осуществляется путем копирования куска этого массива ил ресайзом массива до размеров контрола? |
|||
|
||||
AntonN |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 7 Всего: 18 |
Если нужно выводить часть массива, то выводи в битмап только часть его, а сам битмап ограничь размерами контрола. Вывод на контрол через BitBlt() (это очень быстрая функция по сравнению с остальным GD).
Однако собрав тестовый проект я не смог без тормозов изменять данные хотя бы 30 раз в секунду по всему массиву (рандомный нойс по всем каналам), уже один проц полностью напрягался (коре 2 дуо 6420). Вывод же сам по себе по диспетчеру занимает 0-1%. Прилепил тестовый проект (только ехе, проверить напряжность операции) - http://desksoft.ru/index.php?downloads=att...ents&id=304 (380кб), исходный массив за кадр изменяется путем рисования пяти линий, ума не приложу как изменять его полностью, это гигабайт в секунду (при 30 кадрах) нужно проворачивать, писать и читать в память - нехило так. ЗЫ курсорными клавишами - "навигация" Это сообщение отредактировал(а) AntonN - 8.12.2010, 00:42 |
|||
|
||||
Bitter |
|
|||
![]() Опытный лентяй ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1209 Регистрация: 15.8.2004 Где: Харьков, Ukraine Репутация: 6 Всего: 27 |
Думаю всё же под "полностью обновляется" автор имел в виду "частично обновляется", потому, что действительно гиг в секунду переписать это анбиливбл какой-то.
Хотя вот я только что попробовал в фотошопе картинку 3000х3000 прогнать через фильтр "шум", ну замерить время выполнения я не знаю как, но на глаз миллисекунд 50 заняло это, так что теоретически это можно делать 20 раз в секунду как минимум. да, и если уж нужно всё таки обновлять такой массив, то это делается частичным обновлением видимой области. |
|||
|
||||
AntonN |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 491 Регистрация: 8.8.2006 Репутация: 7 Всего: 18 |
Это реально, но задача так нефигово ресурсоемкая, в плане пропускной способности (если тупо переписывать из какого то массива в этот).
Фотошоп может использовать универсальные методы, потому может позволить себе тормозить. В принципе, я могу понять когда массив обновляется кем-то (класс какой либо, процесс) в какой либо области, и нам не известна эта область (как у меня в архиве выше - рисуется линия с рандомными координатами), но нужно быть готовым увидеть любую часть такого массива. Тогда рекомендую делать как я выше сказал - в битмап загонять лишь часть массива, а сам битмап через BitBlt() (битмап нужен для буферизации, в onpaint контрола его же и рисовать на контроле). Тогда вывод получается вполне быстрым и ненапряжным. |
|||
|
||||
RESIN |
|
|||
Новичок Профиль Группа: Участник Сообщений: 20 Регистрация: 8.10.2010 Репутация: нет Всего: нет |
Заверяю всех, что макссив по крайней мере 2000х2000 пикселей у меня меняется с весьма высокой скоростью. Проверял так: создал таймер интервалом 5 сек., создал отдельный поток, на который в бесконечный repeat-until повесил преобразование массива (склейка из отдельных массивов того же типа с наложением некоторых поверх и некот. вычислениями). Там же сделал инкрементацию переменной, считающей колличество повторений цикла. В самом таймере обнулял значение кол-ва кадров, предварительно выведя его, деленное на 5, в капчу формы. Даже относительно старый Pentium 4 с тактовой 1,3 примерно пятьдесят раз в секунду мой массив обновлял. Потому что в преобразованиях я использовал указатели на строки массивов пикселей (индексы Y), а сами преобразования для каждого пикселя хорошо оптимизировал (битовые сдвиги вместо умножений и делений, вынесения общих множетелей и т.д.).
После формирования массив масштабируется исходя из вещественного коэффициента: создается еще один массив, в который переписывается выборка строк и столбцов из исходного массива. Выборка тоже быстрая, т.к. вычисление индексов производится в целых числах: использовал алгоритм Брезентхамма для инкрементирования индексов, если интересно - могу показать. Эту часть тоже включал в зацикленный поток - утяжелила на ~0,3 кадра в секунду. А вот вывод отмасштабированного массива очень медленен. Если масштаб =0.2 (20%) то еще терпимо, а вот когда =1 (100%) - жестокие тормоза, даже на моем Core2 Duo E8600. Насчет обрезки массива по видимой области контролла уже думал, но будет очень неудобно переписывать часть программы: у меня много действий происходит по нажатию клавиши мыми по контроллу, и сам скроллинг контролла происходит по движению мыши по нему с зажатой ЛКМ. Придется подумать над преобразованием координат. Сделать впринципе можно, но размер контролла почти равен размеру самой формы (за минусом бордеров, гор. и верт. скроллов и маленькой панельки сверху, кот. скрывается либо отображается по двойному ЛКМ), а форма, в свою очередь, может и на весь экран быть растянута. Боюсь, что даже обрезка массива до 1200х980 не даст требуемой производительности (хоть правда, будет быстрее, чем сейчас). Добавлено через 2 минуты и 50 секунд Да, и при скроллинге боюсь появления мерцаний и "артефактов", если вывод не будет скроллы догонять... |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Можно использовать метод ближайшего соседа + отказаться от floating poing для вычисления точки откуда брать цвет. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
![]() ![]() ![]() |
Правила форума "Delphi: Звук, графика и видео" | |
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делится вскрытыми компонентами
FAQ раздела лежит здесь! Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |