Форум программистов, компьютерный форум, киберфорум
PascalABC.NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
0 / 0 / 1
Регистрация: 12.01.2017
Сообщений: 104
1

Как сделать быструю графику?

04.07.2020, 00:26. Показов 3191. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пытаюсь собрать свою игру, и нужно быстро выводить на экран много картинок.
Вот пример кода:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
uses graphabc;
...
lockdrawing;
for var bar: integer := 0 to width - 1 do
    begin
          pic.CopyRect(
            rect( bar, 
                  Round((height div 2 - lob.height[bar] / (coscam(width, bar, cam.getFoV)) * (height div 2))), 
                  bar + 1, 
                  Round((height div 2 + lob.height[bar] / (coscam(width, bar, cam.getFoV)) * (height div 2)))),
            bt,
            rect( Round((bt.Width - 1) * lob.percent_of_block[bar]), 
                  0, 
                  Round((bt.Width - 1) * lob.percent_of_block[bar] + 1), 
                  bt.Height));
end;
pic.Draw;
redraw;
...
Уже при width = 640 оно делает примерно 20 кадров в секунду.
Даже если не использовать CopyRect текстуры с масштабированием, на что, я думаю, всё же ресурсы нужны, а использовать простой графический примитив Rectangle() или Line() для вывода прямоугольника одного цвета -- ситуация не становится лучше.
Видеокарта при этом не загружается вовсе, а вот процессор нагружается изрядно.

Могу ли я повысить производительность этого алгоритма штатными средствами PascalABC.NET, без дополнительных библиотек?
Могу ли я повысить производительность этого алгоритма с помощью дополнительных библиотек?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.07.2020, 00:26
Ответы с готовыми решениями:

Как сделать быструю сортировку?
Как сделать быструю сортировку???

Как сделать быструю сортировку в деке?
Я создал дек, и нужно применить к нему быструю сортировку (Обменную сортировка с разделением). А...

Как сделать быструю смену анимации?
юнити 2д персонаж. у меня есть 4 анимации ходьбы. но чтобы анимация успела смениться нужно отжать...

как сделать эту графику?
Изобразить финальную сцену некоторой театрального представления; на экране: произвольное...

12
2309 / 1420 / 516
Регистрация: 07.04.2017
Сообщений: 4,723
04.07.2020, 01:49 2
Цитата Сообщение от Kujivunia Посмотреть сообщение
Видеокарта при этом не загружается вовсе, а вот процессор нагружается изрядно.
Потому что GDI, на котором основан GraphABC. GDI изначально задумывался только для простеньких окон с меню, обновляющимися раз в несколько сек.

А ещё GraphABC устарел. Используйте вместо него GraphWPF. Возможности примерно те же, но основано всё на WPF.

Вообще, быстрее всего графика будет с чем то низкоуровневым типа OpenGL. Но с ним и код писать сложнее.

---

Цитата Сообщение от Kujivunia Посмотреть сообщение
var bar: integer
Зачем вы явно объявляете тип? пишите просто var bar
0
0 / 0 / 1
Регистрация: 12.01.2017
Сообщений: 104
04.07.2020, 02:16  [ТС] 3
Т.е. я пытался выводить сложную высокозатратную графику с помощью библиотеки рисования окошек для пользовательских приложений? Забавно.
Цитата Сообщение от Sun Serega Посмотреть сообщение
А ещё GraphABC устарел. Используйте вместо него GraphWPF. Возможности примерно те же, но основано всё на WPF.
А в чём тогда отличие, чем он лучше?
Вообще, быстрее всего графика будет с чем то низкоуровневым типа OpenGL. Но с ним и код писать сложнее
А есть что-то такое для этого языка, но попроще?
Я слышал про SFML, но у меня не получилось нормально её запустить, да и я не уверен, что оно работает с чем-то низкоуровневым, мб это тоже библиотека для рисования окон?

---

Сам не знаю, иногда явно объявляю, иногда нет.
0
2309 / 1420 / 516
Регистрация: 07.04.2017
Сообщений: 4,723
04.07.2020, 04:30 4
Лучший ответ Сообщение было отмечено Kujivunia как решение

Решение

Цитата Сообщение от Kujivunia Посмотреть сообщение
А в чём тогда отличие, чем он лучше?
Тем что основан на WPF.
Ну а ещё он не устарел. То есть если вы найдёте в нём что то кривое - можно написать разработчикам и ожидать что это исправят.

Цитата Сообщение от Kujivunia Посмотреть сообщение
мб это тоже библиотека для рисования окон
WPF тоже задумывался для рисования менюшек, но в отличии от GDI - в основные принципы не входило "для менюшек - и так сойдёт". На нём и 3D прекрасно идёт (есть модуль Graph3D).

Цитата Сообщение от Kujivunia Посмотреть сообщение
работает с чем-то низкоуровневым
Всё работает с чем то низкоуровневым. GDI, на самом деле, тоже использует GPU. Просто не для всего, для чего стоило бы. Вопрос только в том, как низкоуровневые библиотеки используются и сколько между ними и интерфейсом прокладок.

Насчёт SFML - сам с ним не работал, но вроде обычно о нём хорошо отзываются. Ну, он, по крайней мере, явно лучше GDI. Хотя мне лично только что то низкоуровневое как OpenGL напрямую и подавай)
1
0 / 0 / 1
Регистрация: 12.01.2017
Сообщений: 104
04.07.2020, 13:25  [ТС] 5
Хорошо, попробую.
Но WPF гораздо сложнее и непонятнее.
Вот мой список вопросов после первой пробы:
1) Что значит и как работает синтаксис
Pascal
1
procedure Redraw(d: ()->());
Т.е. я нашёл примера кода в интернете, и смог запустить свой, но всё равно ничего не понял.
2) Как работать с изображениями, если graphWPF поддерживает только прямое рисование целой картинки из файла, насколько я понял?
3) Как подключить graph3D вместе с graphWPF , если вылезает "Ошибка времени выполнения: System.InvalidOperationException: Нельзя создать более одного экземпляра System.Windows.Application в одном AppDomain"? Или их не нужно подключать вместе, а для графики использовать graph3D, но для менюшек graphWPF? При этом, если подключить graph3D отдельно, то сразу начинает запускаться окно с просмотром непонятной 3д сцены. И в нём я тоже не нашёл, как работать с картинками.
4) Исходя из вопросов выше: а есть ли вообще способ воспроизвести алгоритм из шапки поста в graph3D/graphWPF ?

5) OpenGL хорошо работает с этим языком? Посоветуйте, что базово почитать про него, чтобы, опять же, можно было хотя бы воспроизвести алгоритм из шапки поста
0
2309 / 1420 / 516
Регистрация: 07.04.2017
Сообщений: 4,723
04.07.2020, 22:46 6
Лучший ответ Сообщение было отмечено Kujivunia как решение

Решение

1)
Цитата Сообщение от Kujivunia Посмотреть сообщение
Что значит и как работает синтаксис
У разработчиков есть своя презентация:
http://pascalabc.net/downloads... ambdas.pdf
Но своё объяснение я тоже дам:

Эта процедура принимает ссылку на другую процедуру в виде параметра. Эта запись примерно равноценна:
Pascal
1
procedure Redraw(d: procedure);
Но писать Action0 или ()->() лучше, потому что это встроенный тип делегата (ссылки на подпрограмму), в то время как d: procedure создаст новый тип.

Если это не сразу интуитивно - integer->() это процедура принимающая integer. В то время как ()->integer это функция, ничего не принимающая и возвращающая
integer. Если параметров несколько - добавляйте скобки и перечисляйте их типы через запятую.

---

Pascal
1
2
3
4
5
6
7
8
9
10
11
uses GraphWPF;
 
procedure p1;
begin
  GraphWPF.DrawCircle(15,15,10);
  GraphWPF.DrawCircle(15,45,10);
end;
 
begin
  Redraw(p1);
end.
Но как и в объявлении типа параметра - лучше использовать "лямбда-подпрограмму" (или просто лямбду):
Pascal
1
2
3
4
5
6
7
8
9
uses GraphWPF;
 
begin
  Redraw(()->
  begin
    GraphWPF.DrawCircle(15,15,10);
    GraphWPF.DrawCircle(15,45,10);
  end);
end.
1. Так код выглядит чище и читабельнее. Действия объявлены там, где они выполняются, а не где то сверху.

2. Лямбда это анонимная подпрограмма. Это значит что пространство имён (то что видно, к примеру, в Ctrl+пробел) - не забивается лишним именем. Обычно то что вы передаёте в Redraw - будет использовано только в 1 месте в программе, поэтому странно выделять ему своё имя.

3. Лямбды могут захватывать локальные переменные:
Pascal
1
2
3
4
5
6
7
8
9
10
11
uses GraphWPF;
 
begin
  var i := 5;
  Redraw(()->
  begin
    $'i = {i}'.Println;
    GraphWPF.DrawCircle(15,15,10);
    GraphWPF.DrawCircle(15,45,10);
  end);
end.
Можно, конечно, объявить i как глобальную переменную. Но, кроме того что они в несколько раз медленнее локальных... И того что они тоже забивают глобальное пространство имён - они не потоко-безопастны. То есть ваш код может одновременно попытаться записать значение в 2 параллельных потоках выполнения (как поток графики и поток физики), из чего выйдет каша.

Хотя лямбды - это сахар. То есть они превращаются в другой код при компиляции. А точнее:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
uses GraphWPF;
 
type
  // вместо этого - какое то новое, не использованное имя
  lambda_container_1 = class
    i: integer;
    
    // вместо этого - какое то новое, не использованное имя
    procedure lambda_1;
    begin
      $'i = {i}'.Println;
      GraphWPF.DrawCircle(15,15,10);
      GraphWPF.DrawCircle(15,45,10);
    end;
    
  end;
  
begin
  var c := new lambda_container_1;
  c.i := 5;
  Redraw(c.lambda_1);
end.
(это если захвачена локальная переменная, если нет - создаётся только подпрограмма, без нового класса)
Можно и так писать, но, опять же, п.1 и п.2 .

Добавлено через 19 минут
2)

Цитата Сообщение от Kujivunia Посмотреть сообщение
Как работать с изображениями, если graphWPF поддерживает только прямое рисование целой картинки из файла, насколько я понял?
В данный момент изображения кешируются при первом рисовании. То есть 1 раз читаются из файла и навсегда остаются в памяти (пока программа не завершится).
ИМО в GraphABC с этим было лучше. Ну, можете сами и спросить разработчиков, почему всё ещё ничего лучше не сделали. У них свой форум для таких вопросов есть.

Ну, в WPFObjects это уже нормально реализовано.

3)
Цитата Сообщение от Kujivunia Посмотреть сообщение
Как подключить graph3D вместе с graphWPF
Таки не подключайте их вместе. GraphWPF, WPFObjects и Graph3D - не должны вместе использоваться. Хотя WPFObjects не упадёт если подключать вместе с GraphWPF. Но вполне возможно что они будут конфликтовать при попытках что то нарисовать.

Цитата Сообщение от Kujivunia Посмотреть сообщение
начинает запускаться окно с просмотром непонятной 3д сцены
Координатную сетку можно отключить. Graph3D в основном используется как раз для создания и просмотра 3D сцен, поэтому она по дефолту - включена.

Цитата Сообщение от Kujivunia Посмотреть сообщение
И в нём я тоже не нашёл, как работать с картинками
Наверное, вы просто устали обыскав всё с GraphWPF
Я сам точно не помню, но идея понятна - как и во всём низкоуровневом вроде OpenGL, чтобы нарисовать картинку в Graph3D - надо загрузить её как текстуру и наложить на какой то объект. Посмотрите в папку примеров. Там было наложение текстуры даже на шарики. На плоскость должно быть проще, наверное.

4)
Цитата Сообщение от Kujivunia Посмотреть сообщение
а есть ли вообще способ воспроизвести алгоритм из шапки поста в graph3D/graphWPF ?
Честно - не знаю, не достаточно с ними работал чтоб в таком разбираться. Лучше, опять же, спрашивайте разработчиков, которые эти модули писали.

Добавлено через 37 минут
5)
Цитата Сообщение от Kujivunia Посмотреть сообщение
OpenGL хорошо работает с этим языком? Посоветуйте, что базово почитать про него, чтобы, опять же, можно было хотя бы воспроизвести алгоритм из шапки поста
Если начинать именно базово в OpenGL, а не с постройки космического корабля без понимания что такое F=ma - это пару недель чтения как минимум. Ну, я вас не отговариваю, сам считаю что это луший вариант, потому что он даст максимум возможной производительности и возможностей. Просто если решите таки использовать OpenGL - будьте готовы.

---

Модуль OpenGL, который сейчас скачивается с последней версией паскаля - я сам делал. А в папке примеров есть .html файлы документации к ним.

Ну, то документация к работе с модулям, документация по OpenGL - это вотъ эта жуть. Хотя, конечно, это как бетонная стена - большая, плотная и явно не пробиваемая с первой попытки. Сам пока модуль делал - несколько раз перепрочитал, чтоб хоть какой то минимум понять.

Лучше начать с туториалов. А документацию использовать походу, для более точной инфы.
Из того что могу по-быстрому найти - вот этот выглядит очень хорошо.

Что касается минимального шаблона, что запустится в паскале - вообще с паскалем ставится пример программы. Но я только что понял, чтоб в папке примеров которая устанавливается с паскалем - не хватает файла шейдера (.glsl). А без него пример не запустится.
В ближайшее время это исправится, но пока - берите версию этого примера из моего собственного репозитория.
Там, кстати, всегда можно найти ещё и более новую версию модулей для OpenCL и OpenGL. Хотя это же значит что там эти модули менее протестированы.
1
15 / 13 / 3
Регистрация: 20.08.2017
Сообщений: 32
04.07.2020, 23:35 7
В инсталляте (c:\PABCWork.NET) есть пример gr_MovingObjectsWPF.pas
Замените в нём функцию NewRandomABC на такую:

Pascal
1
2
3
4
5
6
7
8
function NewRandomABC: ObjectWPF;
begin
  case Random(3) of
0: Result := new PictureWPF(Random(Window.Width.Round-w)+w/2,Random(Window.Height.Round-w)+w/2,50,60,'m1.png');
1: Result := new RectangleWPF(Random(Window.Width.Round-w)+w/2,Random(Window.Height.Round-w)+w/2,Random(w),Random(w),RandomColor);
2: Result := new StarWPF(Random(Window.Width.Round-w)+w/2,Random(Window.Height.Round-w)+w/2,Random(w/2),Random(w/2),Random(4)+4,RandomColor);
  end;
end;
Файл 'm1.png' должен быть в папке с программой

И укажите размеры изображения вместо 50 и 60

У меня скорость обновления при 1000 объектах - 120 кадров в секунду

Не знаю, верно ли я понял, что вам нужно
2
0 / 0 / 1
Регистрация: 12.01.2017
Сообщений: 104
09.07.2020, 19:36  [ТС] 8
В принципе, это хорошо, но всё равно, оно просто рисует картинку из файла. А мне нужно рисовать произвольную часть загруженной в память картинки.
0
257 / 149 / 70
Регистрация: 29.07.2018
Сообщений: 1,241
09.07.2020, 20:29 9
Цитата Сообщение от Kujivunia Посмотреть сообщение
А мне нужно рисовать произвольную часть загруженной в память картинки.
Т.е. достать картинку из ресурсов программы?
0
2309 / 1420 / 516
Регистрация: 07.04.2017
Сообщений: 4,723
09.07.2020, 21:36 10
Цитата Сообщение от Пс Посмотреть сообщение
Т.е. достать картинку из ресурсов программы?
Внимательно перечитайте. И не только последнее сообщение.

Ресурсы вообще не загружаются в память автоматически. Они живут на диске, как часть .exe файла, пока их явно не запросят.
0
257 / 149 / 70
Регистрация: 29.07.2018
Сообщений: 1,241
09.07.2020, 21:44 11
Sun Serega, А,понял.
0
15 / 13 / 3
Регистрация: 20.08.2017
Сообщений: 32
11.07.2020, 02:48 12
Да, тогда вам лучше использовать GraphABC. В GraphWPF мы не делали такой возможности как рисование части картинки
0
2309 / 1420 / 516
Регистрация: 07.04.2017
Сообщений: 4,723
11.07.2020, 03:41 13
С GraphABC начали, но у него не хватает производительности.

По моему из предложенных вариантов валидными остаются только:
1. OpenGL, который 100% будет работать, хоть это и сложный путь...
2. Высокоуровневые враперы, вроде SFML. Но с ними я уже не смогу помочь.
0
11.07.2020, 03:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.07.2020, 03:41
Помогаю со студенческими работами здесь

Как сделать примитивную графику....
суть: надо сделать так чтобы при нажатии какой-нибудь клавиши появлялась анимация примитивная....

Как сделать подпись к графику функции?
Как сделать подпись к графику функции (в виде сноски как на рисунке) в скайлабе? Помогите...

Как сделать разметку на координатных осях по данному графику?
график выводится,функция нужная тоже, а как можно сделать разметку координатных осей и подписать их...

Как оптимизировать быструю сортировку?
Помогите пожалуйста оптимизировать быструю сортировку. Какой лучше выбрать опорный элемент? ...

Как вставить счетчик в быструю сортировку?
нужно написать счетчик, какой определяет кол-во перестановок и сравнений в быстрой сортировке ...

Как реализовать быструю сортировку для структуры?
Что нужно поправить? #include<iostream> #include<fstream> #include<vector> #include<string>...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru