Быстрая отрисовка

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Re: Быстрая отрисовка

Сообщение Alex2013 » 06.05.2018 19:04:42

Mavlyudov писал(а):Через Pixels не вариант. Пишу на WinApi. Хочу сделать аналог setpixel, а через него и lineto.


1 Если хочешь делать через WinApi фокус с рисованием на битмапе все равно работает .
2 Может для тебя новость но Pixels сделан как раз через стандартный WinApi.SetPixel ...
3 Примитивы вроде canvas.Lineto работают не так уж медленно (там есть оптимизация для вывода именно их ).
4 Даже мой вариант SetPixel (и любой другой способ работы с каждым пиксилем ) по умолчанию дико медленный способ рисования чего-бы то не было в векторной форме.
5 Доступ к растру по точкам приходится применять только при необходимости обработки изображений .(Даже вывод мало цветных растровых изображений обычно пытаются оптимизировать например выводом через LineTo )
6 Если программа будет писаться только под Виндовс можно получить неслабое ускорение вывода векторной графики используя Метафайлы http://wiki.freepascal.org/TMetafile_/_TMetafileCanvas
Можешь почитать вот эту тему:
Как ускорить прорисовку векторной графики ?
(Флуда много но польза от споров была ! )
Последний раз редактировалось Alex2013 23.04.2019 23:22:16, всего редактировалось 1 раз.
Alex2013
долгожитель
 
Сообщения: 2922
Зарегистрирован: 03.04.2013 11:59:44

Re: Быстрая отрисовка

Сообщение xterro » 07.05.2018 10:48:39

А почему собственно способ рисования на битмапе, а потом копирования его на канвас быстрее чем если просто рисовать на канвасе? Ведь по сути тоже самое рисование + ещё нужно копировать кадр, тоже затраты :?
xterro
постоялец
 
Сообщения: 148
Зарегистрирован: 23.02.2014 13:49:33

Re: Быстрая отрисовка

Сообщение Alex2013 » 07.05.2018 15:55:54

xterro писал(а):А почему собственно способ рисования на битмапе, а потом копирования его на канвас быстрее чем если просто рисовать на канвасе? Ведь по сути тоже самое рисование + ещё нужно копировать кадр, тоже затраты :?


По очень простой причине :
1 Канвас использует методы работы с растром через дисплейный контекст . Это универсальная но ОЧЕНЬ медленная методика . А рисование на битмапе работает с жестко заданными параметрами например 1000х500х24бита и просто считает что это обычная память (После включения BeginUpdate ), а не закрытый "филиал фрейм буфера" с принципиально возможным отображением куда-то в дебри видеокарты . Сделал дело ? Вернул EndUpdate... (Кстати можно включать его для всей перерисовки а не для вывода каждой точки в отдельности - будет слегка быстрее )

2 Копирование через BitBlt и StretchBlt обычно использует аппаратные или оптимизированные методы копирования растра. (Это же-то на чем держится весь GDI ! )

НО повторяю рисовать ПО ТОЧКАМ что-либо кроме точечных графиков медленно по умолчанию! (какой-бы быстрой не была сама операция это все равно медленно )
Даже построение линии можно не слабо ускорить если использовать блочные операции + еще можно оптимизировать вычисление адреса ячейки выкинув например медленное деление и упростив математику в целом с использованием "особых случаев" .
Alex2013
долгожитель
 
Сообщения: 2922
Зарегистрирован: 03.04.2013 11:59:44

Re: Быстрая отрисовка

Сообщение zub » 07.05.2018 19:59:24

Alex2013
Ты вводишь людей в заблуждение. А ктонибудь тебя может послушать
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Быстрая отрисовка

Сообщение runewalsh » 08.05.2018 04:09:55

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

В том, что встроенное рисование линии быстрее её же наивного рисования по точкам, легко убедиться самому, а заглянув в код — и понять, почему: в LCL то и то перенаправляется в TWidgetSet, и, например, SetPixel под Win32 сводится к такому вот ужастику (и это ещё за 5 обёртками выше по стеку!), повторяющемуся по числу пикселов в линии, против одного раза для .Line.
win32object.inc.png
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
runewalsh
энтузиаст
 
Сообщения: 578
Зарегистрирован: 27.04.2010 00:15:25

Re: Быстрая отрисовка

Сообщение Mavlyudov » 08.05.2018 04:18:30

А откуда функция VistaSetPixel ?

Применительно к отрисовке одного пиксела, чем можно заменить
Код: Выделить всё
tbyte=array of byte;
?
Нужно, чтобы массив был размерный.
Пробую заменить на
Код: Выделить всё
tbyte=array[0..3] of byte;

Но тогда рисует черным почему-то.

Кусок кода
Код: Выделить всё
procedure draw(DC:HDC;X1,Y1:INTEGER;IC:TCOLORREF);
var
bBytes : tbyte;
bi24BitInfo : tBITMAPINFO;
Cnt : longint;
xc : integer;
yc : integer;
wth,hth:integer;
begin
wth:=1;
hth:=1;
with bi24BitInfo.bmiHeader do begin
biBitCount := 24;
biCompression := BI_RGB;
biPlanes := 1;
biSize := sizeof(bi24BitInfo.bmiHeader);
biWidth := Wth;
biHeight := Hth;
end;
SetLength(bBytes, ceil(Wth*3/4)*4*Hth+1);
for yc := 0 to hth-1 do begin
for xc := 0 to wth-1 do begin
GFX_SET_PIXEL_DIB(bBytes , xc , yc , {IC}RGB(255,0,0) , bi24BitInfo.bmiHeader.biWidth );
end;
end;
Mavlyudov
новенький
 
Сообщения: 50
Зарегистрирован: 24.01.2010 20:35:23

Re: Быстрая отрисовка

Сообщение Alex2013 » 08.05.2018 08:31:36

zub писал(а):Alex2013
Ты вводишь людей в заблуждение. А ктонибудь тебя может послушать

Ну и где я ошибаюсь ? "Подробности в студию!" Как по моему я просто "изобразил Кепа Очевидность" ... :wink:

Добавлено спустя 13 минут 49 секунд:
Mavlyudov Просто сам проверь что работает быстрее . Иначе вполне вероятно выйдет "мартышкин труд" ....
(Мой опыт говорит что работа с растром через функции ВинАпи значительно медленнее чем предварительное рисование на битмапе
+ совсем неплохо иметь буфер для того чтобы не наблюдать "перерисовку кадра онлайн" (что часто чисто психологически на нервы действует ) )
Alex2013
долгожитель
 
Сообщения: 2922
Зарегистрирован: 03.04.2013 11:59:44

Re: Быстрая отрисовка

Сообщение zub » 08.05.2018 09:45:39

>>Ну и где я ошибаюсь ? "Подробности в студию!"
например тут
Доступ к пикселям на битмапе можно делать так :

или тут, если она основана на предидущем
Вот моя библиотечка для более менее быстрой 2д-графики ...

А по сути - рисовать надо не байтиками и битиками на CPU, а соответствующими апи canvas(обертка над gdi, qt, gtk), opengl, dx - есть шанс что будет заюзан gpu и отрисовка пройдет действительно быстро
Ну а если желание в байтики и битики перебороть неполучается, делайть это надо без кривых великов, есть же agg, bgra...
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Быстрая отрисовка

Сообщение Alex2013 » 08.05.2018 23:50:26

Удивительно! :idea: Знаешь я почти полностью согласен с тобой ... ты просто не очень внимательно читал то что я написал .

1 Я про доступ к пикселям . (мене пришлось лезть к ним через "байтики" только потому что понадобиться хоть какой-то вменяемо быстрый способ доступа для по кадровой обработки видео потока )
2 Я честно предупредил что быстро примитивы через доступ к точкам нарисовать нельзя почти в принципе . (Даже линии !)
3 Точки на битмапе "мой"(хотя какой он "мой"? Да, можно сделать чуть лучше но иначе никак ) метод рисует .
И в разы быстрее чем через Pixels[] . (и кстати с кросспланомерностью там все ок )
Зы
Ну а если желание в байтики и битики перебороть неполучается, делайть это надо без кривых великов, есть же agg, bgra...

Вот с этого и нужно начинать ! (Причем со ссылками !)
Зы Зы
Я вообще не знаю задачи но так как хочет сделать ТС (через WinApi.SETPIXEL(DC,IX,IY,IC); а потом например через уравнение прямой нарисовать линию будет сто процентов медленнее чем если c умом применить "мои" идеи.

Зы Зы
Про GPU: да это мысль ! Но делать все в 3Д движке или через ДиректДрав/Директ3Д/OpenGL означает что нужно заранее сделать зависимость от их версии и вообще наличия ... (Пример сейчас сижу на 10-тке где игровой OGL какая-то крова языком слизала ... ну мне он тут и не нужен это "походный" интернет-планшет ... но факт есть факт ! )
Alex2013
долгожитель
 
Сообщения: 2922
Зарегистрирован: 03.04.2013 11:59:44

Re: Быстрая отрисовка

Сообщение Снег Север » 09.05.2018 08:09:30

Alex2013 писал(а):Но делать все в 3Д движке или через ДиректДрав/Директ3Д/OpenGL означает что нужно заранее сделать зависимость от их версии и вообще наличия ...
Даже если вы ухитрились не поставить дрова своей видеокарты (а я плохо представляю как такое возможно), минимальная версия OGL у вас всё равно будет. И для рисования ее хватит с головой, всё равно это будет быстрее, чем через канвас. Да и Mesa 3D никто не отменял, можете распространять со своей программой.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2990
Зарегистрирован: 27.11.2007 16:14:47

Re: Быстрая отрисовка

Сообщение Alex2013 » 09.05.2018 12:32:40

1 OpenGl у меня работает но первый квак и унриал (с походной флешки где они случайно завалялись ) не запускается в опенгл режиме (Фиг его знает почему ) то есть более сильная зависимость от версии на лицо. (Хотя тот-же Унриал лихо "летает" в директх )

2 OpenGl быстрее но смотря где и для чего: Быстрее в построении 3д сцен ? Вне всяких сомнений ! Но включи вывод модели в режиме "скелета" и удивись внезапному проседаю скорости . + опять же работа с текстурой при необходимости вывести туда видео поток тормозит необходимостью перелопатить BGR в RGB. А обработка видео потока разными фильтрами если не подключать шейдеры вообще ничем от "игры в байтики" не отличается .
Изображение

3 Канвас разумеется вообще довольно медленный способ рисования а использование Pixels совсем уж дикий тормоз .
Но я предложил использовать метофайлы они не то что-бы сильно быстрее но точно значительно менее зависимы от разрешения поля вывода.
Вот например такое тестовое изображение(Les4.lst) строит в высоком разрешении (1920x1080) практически мгновенно . (В чем можно убедится перетаскивая и масштабируя элементы в моем "редакторе форм и страниц" FR0004_20_5_47_7_bin.7z чуть притормаживает только вывод и масштабирование большой растровой картинки(кстати только что проверил не так уж сильно ) но это почти неизбежное зло всех векторных редакторов )
Изображение

4 Кстати если нет желания возится с изобретением велосипеда можно как вариант рисовать через всем известный OpenCV ( Он умеет и это )
ИзображениеИзображение
https://youtu.be/ti13V4hxPIQ
(Извиняясь за артефакты на видео но это кстати показатель того что программа работает быстрее чем кодек успевает кодировать видео )
Зы
С денем Победы !
Alex2013
долгожитель
 
Сообщения: 2922
Зарегистрирован: 03.04.2013 11:59:44

Re: Быстрая отрисовка

Сообщение Mavlyudov » 10.05.2018 00:23:13

Можно кусок кода для рисования точки на DC:HDC через OpenGL?
Mavlyudov
новенький
 
Сообщения: 50
Зарегистрирован: 24.01.2010 20:35:23

Re: Быстрая отрисовка

Сообщение Alex2013 » 10.05.2018 00:58:25

Mavlyudov писал(а):Можно кусок кода для рисования точки на DC:HDC через OpenGL?


Я про OpenCV а не про OpenGL...
Open Source Computer Vision Library, библиотека компьютерного зрения с открытым исходным кодом) — библиотека алгоритмов компьютерного зрения, обработки изображений и численных алгоритмов общего назначения с открытым кодом. Реализована на C/C++, также разрабатывается для Python, Java, Ruby, Matlab, Lua и других языков[2]. Может свободно использоваться в академических и коммерческих целях — распространяется в условиях лицензии BSD.


В OpenGL если честно я слабо разбираюсь ... но в принципе можешь глянуть тут
:arrow: viewtopic.php?f=5&t=5647
Точнее тут
:arrow: viewtopic.php?p=130415#p130415
(в примере 2д работает как часы а с 3д есть чуть мороки исправленной подбором настроек но я уже понял где собака зарыта... там 2 контекста OpenGL активны один через OpenGLContext; другой я через битмап сам создаю вот лезет " сдвиг по фазе" в перспективе и координатах ...выкидываешь OpenGLContext и все станет где нужно )

Код: Выделить всё
// : Аналог "Способа Maxizar-ра" - "рисует" на "фоновом" битмапе.
procedure TForm1.Button3Click(Sender: TObject);
var CanvasHandle,hrc:HDC;
   pfd: TPixelFormatDescriptor;
  nPixelFormat: Integer;
FormatIndex: Integer;
lFDC: HDC;
  ps : TPaintStruct;
  b:TBitMap;
begin

lFDC := ScrBitmap.Canvas.Handle;
FillChar(PFD, SizeOf(PFD), 0);
  With PFD do begin
  nSize := SizeOf(PFD);   nVersion := 1;
  dwFlags := pfd_Draw_to_Bitmap or pfd_Support_OpenGL
  or    PFD_GENERIC_ACCELERATED;
  iPixelType := pfd_Type_RGBA;
  cColorBits := 24;    cDepthBits := 32;
  iLayerType := pfd_Main_Plane;
  end;

FormatIndex := ChoosePixelFormat(lFDC, @PFD);
SetPixelFormat(lFDC, FormatIndex, @PFD);
HRC := wglCreateContext(lFDC);
wglMakeCurrent(lFDC, HRC);
// 2D....
If not CheckBox1.Checked then
  begin
   glLineWidth(9); // размер точек
   glColor3ub(255,0,0); // цвет примитивов
   glBegin(GL_LINES); // открываем командную скобку,
   glVertex2f(-1,-1);
   glVertex2f(1,1);
   glEnd; //Закрываем командную скобку GL
  end
    else //3D...
      MyPaint01(ScrBitmap.Width,ScrBitmap.Height);

   glFlush;
   Image1.Picture.Bitmap.Canvas.Draw(0, 0, ScrBitmap);
   wglDeleteContext(hrc);
end;


Но там по сути тот же "рисунок на битмапе"... только с OpenGL... мне нужно было вывести 3д-МОДЕЛЬ поверх кадра (с камеры) с возможностью пост/пред обработки микса для работы с дополненной реальностью . (Что в целом как видишь получилось )
ИзображениеИзображение
Alex2013
долгожитель
 
Сообщения: 2922
Зарегистрирован: 03.04.2013 11:59:44

Re: Быстрая отрисовка

Сообщение Mavlyudov » 10.05.2018 16:22:23

Alex2013

Как-то так?

Код: Выделить всё
procedure WritePoint(DC:HDC; x,y:integer; ic:TColorREF);
var
r,g,b:DWORD;
begin
glViewPort (0, 0, 1, 1); //Что тут писать?
glPointSize(1);
r:=GetRValue(ic);
g:= GetGValue(ic);
b:= GetBValue(ic);
glColor3f(R,G,B)
glBegin(GL_POINTS);
glVertex2f(x,y);
glEnd;
SwapBuffers(DC);
end;
Mavlyudov
новенький
 
Сообщения: 50
Зарегистрирован: 24.01.2010 20:35:23

Re: Быстрая отрисовка

Сообщение Alex2013 » 10.05.2018 18:04:48

Почти но там нужно подготовить контекст или использовать компонент OpenGLContext;
... Это контекст окна хотя к нему можно привязаться привязываться (У меня привязывается к специально доработанному битмапу )
glFlush; или SwapBuffers(DC); пишется после загрузки (прорисовка происходит после этой команды ) данных всего кадра а не одного элемента .
glTranslatef() можешь пропустить...

glColor3f(R,G,B) пишется внутри "скобки " иначе действует глобально .
glViewPort (); можно не писать если юзаешь OpenGLContext; и вообще для 2д кажется по умолчанию стоит поле от -1,-1 до 1,1.

Но повторяю я в OpenGL неспециалист .

Зы
Делать-то что хочешь ? Зачем и именно точки нужны ? OpenGL- полно векторных примитивов на любой вкус и они точно строятся БЫСТРО !

Зы Зы
А еще посмотри внимательно в эту тему и поспрашивай её хозяина olegy123 думаю много вопросов сразу отпадет.
Графика 3М (GUI на базе OpenGL)
Последний раз редактировалось Alex2013 10.05.2018 23:31:55, всего редактировалось 2 раз(а).
Alex2013
долгожитель
 
Сообщения: 2922
Зарегистрирован: 03.04.2013 11:59:44

Пред.След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Рейтинг@Mail.ru