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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Прорисовка массива пикселей на граф. компонент 
:(
    Опции темы
RESIN
  Дата 7.12.2010, 04:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 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-ом (на ассемблере). Тормозит до жути. smile 
С OpenGL не разобрался до конца, сам дошел только до вот такого извращения:
Код

  glPointSize(1);
  glBegin(GL_POINTS);
  For y:=0 to Texture.Height-1 do
      For x:=0 to Texture.Width-1 do
      Begin
        pix:=Texture.Picture[y, x];
        glColor3ub (((pix ShL 24) ShR 24), ((pix ShL 16) ShR 24), (pix ShR 16));
        glVertex(x, y);
      end;
  glEnd;
  swapBuffers(DC);

Но это дебилизм полнейший, хоть и работает (иногда появляются вертикальные черные полоски толщиной 1px).

Пожалуйста, помогите решить задачу с учетом того, что выводить нужно ИМЕННО двумерный массив, описанный мной в пользовательских типах., не битмап, не спрайт, не PNGObject, а именно массив. Буду крайне рад готовому примеру (ну эт я уже обнаглел smile ).
Готов рассмотреть любые варианты: GDI, OpenGL, DirectX (DirectDraw) и любой другой.

Это сообщение отредактировал(а) RESIN - 7.12.2010, 04:04
PM MAIL   Вверх
x128
Дата 7.12.2010, 10:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

...Массив достаточно большой, ~3000х3000 значений (=пикселей). Требуется сравнительно быстро ( > 30 кадров в секунду)...
...К тому же нужно, чтобы алгоритм вывода был не чувствителен к изменению размеров и позиции выбранного компонента...

1) Массив полностью обновляется >30 раз в секунду?
2) Что подразумевается под "не чувствителен к изменению размеров и позиции выбранного компонента", нужно выводить определенную часть массива?
PM MAIL WWW   Вверх
Bitter
Дата 7.12.2010, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

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



Можешь использовать устаревший DIrectDraw, но хоть он и устарел, он именно для этих целей и очень простой. В общем он для быстрого копирования растра на экран.
PM MAIL ICQ Skype   Вверх
RESIN
Дата 7.12.2010, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



to x128:

Полностью обновляется >90 раз в секунду. Массив может менять свои размеры в зависимости от заданного масштаба. В програме так же доступен скроллинг. По-этому при выводе компонент должен менять свой размер, а при скроллинге - позицию.

to Bitter:

А как это сделать? Подскажите, пожалуйста. И где взять SDK DirectDraw для Delphi.
PM MAIL   Вверх
Bitter
Дата 7.12.2010, 16:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

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



скачай книгу М Краснова "DitectX Графика в проектах Delphi". Вот ссылка. http://www.delphilab.ru/files/book/krasnov_dx.7z К ней прилагаются и примеры и модули для подключения DirectX. Там первая половина книги как раз про DirectDraw, но тебе не нужна вся половина, тебе достаточно будет несколько первых глав.
PM MAIL ICQ Skype   Вверх
Alexeis
Дата 7.12.2010, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(RESIN @  7.12.2010,  16:30 Найти цитируемый пост)
Полностью обновляется >90 раз в секунду. Массив может менять свои размеры в зависимости от заданного масштаба

  Нет смысла рисовать чаще чем 30 раз в секунду. Лишние затраты будут. По поводу скорости, то можно попробовать SetDIBitsToDevice


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

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

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


Новичок



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

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



Спасибо большое, Bitter! Скачал, разбираюсь, нравится.
Правда уже при попытке запустить пример Ex10 из Chapter02 возникла проблема. Впринципе, не важно, какой пример, CodGear Rad 2009 ругается на строку #173 в модуле DirectDraw.pas:
Код

      lpDDSZBufferDest            : PDirectDrawSurface; // Surface to use as Z buffer for dest

Пишет: [DCC Error] DirectDraw.pas(173): E2154 Type 'IDirectDrawSurface' needs finalization - not allowed in variant record
Не знаешь, как решить сию проблему?

Цитата(Alexeis @ 7.12.2010,  17:16)
  Нет смысла рисовать чаще чем 30 раз в секунду. Лишние затраты будут. По поводу скорости, то можно попробовать SetDIBitsToDevice

Чаще и не нужно )) Просто сейчас я иногда не получаю и 15 кадров в сек., и это косяк именно вывода на экран (проверял).
По поводу SetDIBitsToDevice - а она правда сможет принять в качестве параметра мой массив?

Это сообщение отредактировал(а) RESIN - 7.12.2010, 17:54
PM MAIL   Вверх
Bitter
Дата 7.12.2010, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

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



RESIN, попробуй написать вместо 

Код

lpDDSZBufferDest            : PDirectDrawSurface;


вот так:

Код

lpDDSZBufferDest            : pointer;


а если он тебе понадобится, то использовать приведение типов. но я думаю не понадобится

Добавлено через 1 минуту и 47 секунд
По поводу той ошибки, я так понял, что в делфи 2010 (как и в Делфи 5) нельзя включать COM объекты в вариантные записи, бла бла бла и так далее
PM MAIL ICQ Skype   Вверх
Alexeis
Дата 7.12.2010, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(RESIN @  7.12.2010,  18:42 Найти цитируемый пост)
По поводу SetDIBitsToDevice - а она правда сможет принять в качестве параметра мой массив?

  Нет конечно, но операция копирования байтов в DIB Bitmap не такая уж трудоемкая по сравнению с операцией вывода на экран (по времени) средствами GDI. На самом деле это отнимет времени не превышающего 10% от времени отрисовки (зависит от производительности процессора), поэтому ею можно пренебречь. 


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

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

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


Опытный
**


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

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



А вы найдете такой монитор, чтобы вывести все 3000*3000 пикселей?
Вывод на экран осуществляется путем копирования куска этого массива ил ресайзом массива до размеров контрола?


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


Опытный
**


Профиль
Группа: Участник
Сообщений: 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


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


Опытный лентяй
***


Профиль
Группа: Завсегдатай
Сообщений: 1209
Регистрация: 15.8.2004
Где: Харьков, Ukraine

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



Думаю всё же под "полностью обновляется" автор имел в виду "частично обновляется", потому, что действительно гиг в секунду переписать это анбиливбл какой-то.

Хотя вот я только что попробовал в фотошопе картинку 3000х3000 прогнать через фильтр "шум", ну замерить время выполнения я не знаю как, но на глаз миллисекунд 50 заняло это, так что теоретически это можно делать 20 раз в секунду как минимум.

да, и если уж нужно всё таки обновлять такой массив, то это делается частичным обновлением видимой области. 
PM MAIL ICQ Skype   Вверх
AntonN
Дата 8.12.2010, 01:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Это реально, но задача так нефигово ресурсоемкая, в плане пропускной способности (если тупо переписывать из какого то массива в этот).
Фотошоп может использовать универсальные методы, потому может позволить себе тормозить. В принципе, я могу понять когда массив обновляется кем-то (класс какой либо, процесс) в какой либо области, и нам не известна эта область (как у меня в архиве выше - рисуется линия с рандомными координатами), но нужно быть готовым увидеть любую часть такого массива. Тогда рекомендую делать как я выше сказал - в битмап загонять лишь часть массива, а сам битмап через BitBlt() (битмап нужен для буферизации, в onpaint контрола его же и рисовать на контроле). Тогда вывод получается вполне быстрым и ненапряжным.


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


Новичок



Профиль
Группа: Участник
Сообщений: 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 секунд
Да, и при скроллинге боюсь появления мерцаний и "артефактов", если вывод не будет скроллы догонять...
PM MAIL   Вверх
Alexeis
Дата 8.12.2010, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(RESIN @  8.12.2010,  04:17 Найти цитируемый пост)
А вот вывод отмасштабированного массива очень медленен. Если масштаб =0.2 (20%) то еще терпимо, а вот когда =1 (100%) - жестокие тормоза, даже на моем Core2 Duo E8600.

  Можно использовать метод ближайшего соседа + отказаться от floating poing для вычисления точки откуда брать цвет.


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

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

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

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

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

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

FAQ раздела лежит здесь!


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

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


 




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


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

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