Модераторы: 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   Вверх
x128
Дата 8.12.2010, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

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

Если массив обновляется >90 раз в секунду (более 3гб в сек.), это уже за приделами производительности для большинства компьютеров даже при обычном копировании не говоря о прочих операциях. Самый разумный подход, это обновлять только видимую часть изображения(массива) и выводить этот участок на экран, при таком подходе нагрузка будет минимальная.
PM MAIL WWW   Вверх
RESIN
Дата 8.12.2010, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Alexeis @ 8.12.2010,  09:00)
+ отказаться от floating poing для вычисления точки откуда брать цвет.

Не понял? Вещественные числа для вычисления координат пикселей, рисуемых на экран под масштабом? Итак использую целочисленный алгоритм (спер идею у Брезентхамма).
PM MAIL   Вверх
AntonN
Дата 8.12.2010, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата

Да, и при скроллинге боюсь появления мерцаний и "артефактов", если вывод не будет скроллы догонять... 

А у меня видел мерцание? =)

Затестил с ресайзом из fastlib, файсресайз и билинейный, оба позволяют отресайзить поле 1024*786 почти без тормозов (первый так вообще без них). Правда на линиях при таком ресайзе даже биленейного мало для качества. http://desksoft.ru/index.php?downloads=att...ents&id=305


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


Новичок



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

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



Цитата(AntonN @ 8.12.2010,  14:11)
А у меня видел мерцание? =)

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

Это сообщение отредактировал(а) RESIN - 8.12.2010, 14:29
PM MAIL   Вверх
AntonN
Дата 8.12.2010, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



В onpaint рисуй буферный битмап на контрол, и не будет мерцания.
мне пока некогда выпилить из класса вещи, которые я не могу показывать smile к тому же массив линейный, а не двумерный (хз как он в памяти лежит).


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


Новичок



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

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



Цитата(AntonN @ 8.12.2010,  16:55)
к тому же массив линейный, а не двумерный (хз как он в памяти лежит).

Так и лежит smile В памяти все массивы линейны )
А проблема то в том и состоит, что буферный битмап долго рисуется даже со сканлайном. Ищу сейчас методы быстрого формирования битмапа...
PM MAIL   Вверх
AntonN
Дата 9.12.2010, 01:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



рисуется или формируется?


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


Новичок



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

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



Не так выразился, справедливое замечание ). Формируется медленно. BitBlt куда быстрее на канву Пейнтбокса происходит, в сравнении с самим формированием битмапа.
PM MAIL   Вверх
Alexeis
Дата 9.12.2010, 09:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


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

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



Цитата(RESIN @  9.12.2010,  06:13 Найти цитируемый пост)
 Формируется медленно. BitBlt куда быстрее на канву Пейнтбокса происходит, в сравнении с самим формированием битмапа. 

  Не может быть! Совсем наоборот ScanLine дает адрес обычной памяти. При помощи него я за секунду могу создать несколько тысяч кадров, но отрисовать лишь несколько десятков.


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

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

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


Опытный
**


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

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



Цитата

Не может быть! Совсем наоборот ScanLine дает адрес обычной памяти. 

может, сканлайн дает адрес, а мы кроме того что берем адрес еще им и манипулируем, вот тут и затык - как быстро заполнить данными битмап


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


Амеба
Group Icon


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

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



Цитата(AntonN @  9.12.2010,  20:42 Найти цитируемый пост)
а мы кроме того что берем адрес еще им и манипулируем

  Адресация по указателю никак не медленнее чем элемента массива, так что не вижу ни каких оснований для тормозов. Кстати построчная обработка быстрее чем послолбцовая.


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

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

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


Новичок



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

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



Цитата(Alexeis @ 9.12.2010,  20:14)
Кстати построчная обработка быстрее чем послолбцовая.

100% вы правы! Только вот сама функция Scanline, видимо не очень быстро адрес возвращает.
PM MAIL   Вверх
RESIN
Дата 10.12.2010, 04:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вот так я сейчас отрисовываю, используя библиотеку QuickPixels с мастеров делфи: http://www.delphimaster.ru/articles/pixels/

Код

  BMP:=TBitmap.Create;
  BMP.PixelFormat:=pf24bit; // !!!
  BMP.SetSize(Texture.Width, Texture.Height);
  QP:=TQuickPixels.Create;
  QP.Attach(BMP);
  for y:=0 to Texture.Height-1 do
  begin
    Scanline:[email protected][y];
    for x:=0 to Texture.Width-1 do
    begin
      pix:=Scanline^[x];
      QP.SetPixel(x, y, ((pix shl 8) shr 24)+(((pix shl 16) shr 24) shl 8)+((pix shl 24) shr 8));
    end;
  end;
  BitBlt(PAINT_BOX.Canvas.Handle, 0, 0, Screen.Texture.Width, Screen.Texture.Height, BMP.Canvas.Handle, 0, 0, srccopy);
  BMP.Free;


Или вот так, со сканлайном, без QuickPixels:

Код

  BMP:=TBitmap.Create;
  BMP.PixelFormat:=pf32bit; // !!!
  BMP.SetSize(Texture.Width, Texture.Height);
  for y:=0 to Texture.Height-1 do
  begin
    Scanline:[email protected][y];
    BMP_Scanline:=BMP.ScanLine[y];
    for x:=0 to Texture.Width-1 do
      BMP_Scanline[x]:=Scanline^[x];
  end;
  BitBlt(PAINT_BOX.Canvas.Handle, 0, 0, Screen.Texture.Width, Screen.Texture.Height, BMP.Canvas.Handle, 0, 0, srccopy);
  BMP.Free;


Разници на своем E8600 не заметил.
Если есть идеи, как это можно улучшить, делитесь, пожалуйста smile Так же интересно ваше мнение о том, какой из способов лучше.

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


Опытный
**


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

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



Цитата

Адресация по указателю никак не медленнее чем элемента массива, так что не вижу ни каких оснований для тормозов. Кстати построчная обработка быстрее чем послолбцовая.

Преобразование типов при изменении байта по указателю, операции над longint при изменении байта по указателю smile
В то время как у меня "пиксели" напрямую копируются через регистр MMX в две операции. Вот о чем я - мало адрес получить, важно какими операциями в него писать.


RESIN, у меня там было два массива, один 3000*3000, второй по размеру битмапа вывода (он потом 1:1 выводился в битмап, который и рисовался). Быстрый ресайз (fast который, без качества) на меньший массив (так проще было сделать переключалку на полный показ массива и только на его часть), потом вывод. Постараюсь сегодня выпилить пример.

Добавлено через 1 минуту и 16 секунд
Ах да, самое главное - битмап создавать только один раз, а не при каждом выводе


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


Амеба
Group Icon


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

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



Цитата(RESIN @  10.12.2010,  04:02 Найти цитируемый пост)
 Только вот сама функция Scanline, видимо не очень быстро адрес возвращает. 

  Так зачем же вызывать ее каждый раз? На самом деле ее достаточно вызывать всего 1 раз, после создания битмапа для получения адреса последней строки, что и будет адресом начала всего битмапа. Дальше строки идут одна за другой.

Цитата(AntonN @  10.12.2010,  10:12 Найти цитируемый пост)

Преобразование типов при изменении байта по указателю, операции над longint при изменении байта по указателю

  А я и не говорил что нужно адресовать байты.
Цитата(AntonN @  10.12.2010,  10:12 Найти цитируемый пост)
В то время как у меня "пиксели" напрямую копируются через регистр MMX в две операции. 

  А смысл? Запись в регистры mmx и вывод из них в память займет дополнительное время, в результате выигрыш от такого копирования будет исчезающе мал (по сравнению с той же CopyMemory). 

 smile 
Цитата(AntonN @  10.12.2010,  10:12 Найти цитируемый пост)
Ах да, самое главное - битмап создавать только один раз, а не при каждом выводе 

  Интересно, что такой же косяк я заметил в коде в механизме двойной буферизации VCL  smile . Подозреваю, что отрисовка юзер интерфейса не столь частая, поэтому тормоза не так заметны. 


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

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

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


Опытный
**


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

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



Цитата

А смысл? Запись в регистры mmx и вывод из них в память займет дополнительное время, в результате выигрыш от такого копирования будет исчезающе мал (по сравнению с той же CopyMemory). 

потому что я не копирую весь массив в битмап, а лишь часть его. CopyMemory тоже не волшебством работает, пока в тестах победил вариант с копированием через регистры MMX (по 4 байта в регистре, но с movq по 8, я обычно парой запускаю, это 16).
Еще одна фича - у битмапа в памяти строки наоборот.

Цитата

 А я и не говорил что нужно адресовать байты.

что быстрее:
Код

movq  mm0, [esi]
movq  mm1, [esi+8]
movq  [edi], mm0
movq  [edi+8], mm1

или 
Код

QP.SetPixel(x, y, ((pix shl 8) shr 24)+(((pix shl 16) shr 24) shl 8)+((pix shl 24) shr 8));

? вот о чем я, то что сканлайн дал адрес - это одно, то что нам в этот адрес надо записать (и главное как записать) - другое.


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


Опытный
**


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

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



Проект, выпиленый.
Кроме самого массива 3000*3000 создается дополнительный под размер вывода, на который ресайзится большой, потом этот меньший выводится в битмап, битмап на канву

Присоединённый файл ( Кол-во скачиваний: 18 )
Присоединённый файл  test.rar 22,52 Kb


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


Новичок



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

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



AntonN: Спасибо огромное за пример!  smile  Допилил его до минимума, разбираюсь )) На выводе, при развороте на весь экран, дает >50 кадров за 1000 тиков.

Добавлено @ 10:30
Вопрос теперь, ко всем. Какой код будет работать быстрее?
Этот:

Код

  A:=pix shr 24;
  B:=(pix shl  8) shr 24;
  G:=(pix shl 16) shr 24;  
  R:=(pix shl 24) shr 24;


или этот:

Код

  A:=pix shr 24;
  B:=(pix shr 16) and $000000FF;
  G:=(pix shr 8) and $000000FF;  
  R:=pix and $000000FF;


A, B, G, R : byte;
pix : longint;

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


Шустрый
*


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

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



Быстрей будет такой код:
Код

type
  TRGB = packed record
    r,g,b,a: byte;
  end;

var
  p: TRGB;
  pix: integer;
...
  DWORD(p):=pix;


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

Запрещено:

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

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

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

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


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

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


 




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


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

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