Войти
ПроектыФорумУтилиты

o2 (3 стр)

Страницы: 1 2 3 4 Следующая »
#30
10:59, 10 янв. 2017

Ducat
> Это типа как Construct2?
Скорее это как Unity, но с плагином, чтобы можно было делать логику как в Construct2


#31
12:22, 10 янв. 2017

Давай игру, сделанную на о2 - будем рекламировать )

#32
15:08, 10 янв. 2017

Ducat
> Давай игру, сделанную на о2 - будем рекламировать )
ага, только сделать еще ее надо )) вообще, хочу сделать демо-презентацию: записать видео-туториал к котором делается какой-нибудь простенький платформер, по ходу которого показываются основные фишки редактора и движка

#33
(Правка: 16:32) 15:57, 19 янв. 2017

Рендеринг
Рендеринг - ключевая фича движка, поэтому он должен быть простой, удобный и в то же время гибкий. Поэтому в этот раз напишу о том, как он устроен в о2.
На данный момент в нем есть несколько базовых вещей, но все еще некоторых не хватает, что будет исправлено в будущем.

Чего умеет:
- динамический батчинг
- загрузка текстур из png, создание текстур
- рендеринг в текстуру
- отрисовка мешей
- отрисовка спрайтов (обычный, 9-sliced, clock-filled, side-filled, tiled)
- растровые шрифты
- векторные шрифты с эффектами (тень, обводка, цвет, градиент, размытие)
- текст
- отсечение по прямоугольнику
- отсечение по маске
- камера
- примитивы: линия, прямоугольник, круг

Чего еще понадобится:
- шейдеры
- отладка фрейма
- сжатие текстур
- конкуретный метод выгрузки текстур
- типы смешивания (Add, Mull, etc)
- quad - что-то типа спрайта, только оптимизированный

Теперь по порядку, какие примитивы используются:

Текстуры
Текстура может быть загружена из файла или создана во время выполнения. Пока что используется png для загрузки текстур, в будущем будет добавлен формат без сжатия, типа bmp, а так же форматы со сжатием, для мобильных устройств.
При создании тестуры можно указать ее назначение - обычная тестура или рендер-таргет.
Используются текстуры не напрямую, а через ссылки. Это необходимо для подсчета количества мест, в которых используется текстура.

+ Sources
+ Примерчики:

Меш
Хранит в себе буффер вершин, буффер индексов полигонов и используемую текстуру. Буферы могут быть заполнены не до конца, например, максимальный размер буфера - 200 вершин, а используется лишь 100 для отрисовки. необходимо для быстрого перестроения меша без постоянной реаллокации буферов. Вершины в буфере имеют параметры положения в мире (xyz), цвет (color) и текстурные координаты (uv).
Меш является базовым примитивом рендера, все остальные примитивы (кроме тех, что рисуются линиями) основаны на нем.

+ Sources
+ Пример использования:

Спрайт
Самый ходовой элемент отрисовки. При своей внешней простоте имеет довольно сложное устройство. Грубо говоря, спрайт - это прямоугольная картинка. Но в о2 спрайт может отрисовывать как целую текстуру, так и ее часть. Например, при использовании текстурных атласов: спрайт ссылается на текстуру атласа, в котором запаковыно много других изображений, но рисует лишь указанную часть. Эту часть можно указать либо через ассет, либо вручную. Так же, спрайт может быть не просто растягивающимся прямоугольником,
но и шкалой заполнения по кругу, 9-way sliced мешем, затайленной картинкой, и вообще принимать форму не только прямоугольника, но и параллелограмма. Кроме отображения самой картинки спрайт может менять цвет и прозрачность.

Рассмотрим устройство спрайта поподробнее.
Для этого необходимо немного разобрать архитектуру отрисовываемых примитивов в о2. Начинается все с объекта IDrawable, который представляет собой интерфейс объекта, который может быть отрисован.

virtual void Draw();
А так как он может быть отрисован, он может быть использован в качестве элемента взаимодействия с пользователем посредством курсора. Для этого нам нужно знать что попадает ли курсор в наш рисуемый объект
virtual bool IsUnderPoint(const Vec2F& point);
Но для качественной и удобной обработки попадания курсора необходимо учитывать очередность отрисовки объектов и отсечение. IDawable делает это автоматически.

Над IDrawable стоит более высокоуровневый объект - IRectDrawable - это интерфейс, определяющий отрисовываемый объект в виде прямоугольника с возможностью задать цвет и прозрачность. Трансформации определяются базовым классом Transform.
Transform - это важный базовый объект математики в о2. Он определяет трансформации объекта: позиция, опорная точка (pivot), размер, скейл, вращение и сдвиг.

Класс спрайта наследуется от IRectDrawable и принимает в себя все вышеперечисленные свойства. Мы можем задать транформацию спрайта, общий цвет, прозрачность и определять попадает ли курсор на него, так же спрайту можно задать коэфициент заполнения (fill), цвета 4х вершин, коэффициент скейла тайла.
Помимо всего этого спрайт может работать в нескольких режимах:
- обычный: просто рисуется картинка на 2х треугольниках
- 9-way sliced: растягивается, сохраняя некоторые части спрайта в пропорциях 1 к 1
- tiled: при увеличении размера картинка не растягивается, а повторяется
- FillLeftToRight, FillRightToLeft, FillUpToDown, FillDownToUp: отображается в виде линейного прогресс-бара с определенной заполненностью (fill)
- Fill360CW, Fill360CCW: заполняется в виде "пирога" по часовой и против часовой стрелки

+ Sources
+ Пример использования:

Шрифты
В общем виде шрифты в рендере все растровые. Глифы символов содержатся в текстурном атласе, при отрисовке текста используется эта текстура и текстурные координаты для отдельных символов.
Отличие векторного шрифта от растрового в том, что он рендерит глифы символов по требованию в тот же растр с возможностью наложения эффектов. Например, нам потребовалось отрисовать текст с векторым шрифтом, в котором используются еще не использованные символы. Сначала определяются новые символы, затем их глифы рисуются в растр. После этого на растр накладываются эффекты: тень, обводка, градиент и тд, в зависимости от настроек шрифта. После этого перекомпоновывается текстура-атлас с уже дополненными символами. Далее новая текстура и гливы используются при рендеринге нового текста.
Работа со шрифтами производится через ссылки, так же как и с текстурами.

+ Sources
#34
(Правка: 16:33) 16:04, 19 янв. 2017

... продолжение

Текст
Так же как и спрайт, текст основывается на IRectDrawable и имеет все те же свойства по трансформации и заданию общего цвета. Кроме этого, конечно же, задается шрифт, содержимый текст и выравнивание.
Выравнивание отдельно задается по горизонтали и вертикали, позволяет прилепить текст к краю, оставить в середине или добавить пространство в пробелах чтобы текст занимал всю область.
Так же можно включить автоперенос текста по словам, увеличить пространство между символами и строками, или  сделать обрезание текста, выходящего за рамки и оканчивая его на троеточие.
Так же как и спрайт текст использует меш для отрисовки. Точнее может использовать даже несколько, в зависимости от объема текста, но как правило хватает одного. Меш генерируется при изменении текста, изменении размера области, изменении цвета и выравнивания.
При изменении позиции текста меш не перестраивается а сдвигается на необходимую разницу.

+ Sources
+ Пример использования:

Render
Собственно центральной системой является класс-синглтон Render, который инициализируется на старте приложения и занимается собственно менеджментом текстур, шрифтов, спрайтов и отрисовкой всего этого.
При рендеринге используется динамический батчинг.

+ Подробнее

При рендеринге разработчик может отдавать на отрисовку меши, примитивы из линий, устанавливать рендер-текстуру, устанавливать отсечение прямоугольником/маской, устанавливать камеру. Далее обо всем отдельно и подробнее.
+ Sources

Камера
Разработчик может использовать стандартную камеру или устанавливать свою.
Стандартная камера подразумевает собой типичную двумерную систему координат в пикселях. Ее центр находится в центре экрана, ось Х направлена вправо, ось У вверх, единица системы координат равна одному экранному пикселю.
Нестандартная камера имеет все трансформации что и Transform, от которого она наследована: смещение, поворот, скейл и тд

+ Sources

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

+ Пример использования

Отсечение по маске
Данный тип отсечения использует стенсил-буфер для хранения маски. Затем эта маска может использоваться для отрисовки других примитивов с отсечением. Алгоритм отсечения: если пиксель в маске не пуст, пиксель рисуется.
Порядок использования:
- включить рендеринг в маску
- очистить маску при необходимости
- рисовать примитивы
- отключить рендеринг в маску
- включить тест маски
- рисовать примитивы (будет применено отсечение)
- выключить тест маски

+ Пример использования

Отсечение по прямоугольнику
Необходимо для простого и быстрого отсечения прямоугольником, где маска излишняя, например активно используется в UI. Отсечение применяется с учетом предыдущего отсечения в виде иерархии. Например, если было сначала включено отсечение с прямоугольником А, а затем включено отсечение В, то итоговм будет отсечение с учетом А и В, то есть область пересечения А и В. Поэтому каждый начатый этам отсечения необходимо закрывать, или же закрывать все сразу. Так же данные об отсечении автоматически записываются во все рисуемые IDrawable, которые используют эти данные для теста на попадание.

+ Пример использования

#35
19:32, 1 фев. 2017

Изображение
Портирование OSX - новый рендер. Ну а рендер начинается с треугольника :)

#36
12:03, 2 фев. 2017

Линуксовых обделили?

#37
(Правка: 12:08) 12:08, 2 фев. 2017

dshtriger
> Линуксовых обделили?
ну, может когда нибудь.. Пока что нет смысла тратить время на линукс

#38
22:01, 23 мар. 2017

заработали прототипы объектов, типа как те самые вложенные префабы, которые все хотят от юнити

теперь то понимаю, почему они их все никак не зарелизят. Дело действительно тонкое, нетривиальное и гораздо более сложное, чем обычные префабы юнити.
Еще почти портировал на mac os x, но все никак не могу решиться смержить 2 ветки.
На горизонте в планах перелопатить интерфейсы и акторы, чтобы можно было редактировать интерфейсы в редакторе и использовать на сцене

Прошло более 8 месяцев
#39
19:44, 17 дек. 2017

Что-то давно ничего не писал...
Итак, что еще успелось сделать за это время

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

Еще подправил и улучшил систему действий и их отмены, Ctrl-Z короче. Теперь кроме определенного списка действий запоминаются изменение полей компонентов, причем даже таких непростых как массивы. При этом, если удалить из массива элементы, при отмене действия они восстановятся. Конечно же эта фича потащила за собой знатный трах с С++, но плюсом идет небольшое улучшение рефлексии.

Кстати, насчет рефлексии. Раньше функции регистарции мета-данных класса были обычными статичными функциями классов, что имело довольно узкий круг применения. Теперь эти функции шаблонные, и в качестве шаблона передается класс-обработчик мета-информации. Например та же регистрация типа происходит с помощью специального класса-регистратора. Плюс в том, что в качестве обработчика можно передать все что угодно, например сериализатор данных. Если так сделать, то на выходе будет сгенерированный код функции идеально выполняющий сериализацию, без каких-либо накладных ресурсов.

Вообще, вся эта канитель затеивалась ради одной спорной фичи - виртуальное множественное наследование. Да да, то что настолько не любят, что даже многие языки этого впринципе не поддерживают. Копнув глубже, появилась мысль что виртуального наследования нет в других языках не из-за того что это "признак плохого кода", а из-за того что это может конфликтовать с некими парадигмами языка. Если есть множественное виртуальное наследование - объект может лежать в памяти как попало, что создает сложности. То ли дело линейное наследование, где все лежит упорядоченно в линию. Ну да ладно.. А насчет спорности этого архитектурного решения, то без него иногда никуда не деться. Например если все ваши классы наследуются от какого-то общего класса, например IObject. И тут уж очень сильно нужно вертеться, чтобы избежать ромбовидного наследования. И тут даже не понятно что хуже, множественное наследование или пляски вокруг того чтобы избежать ромбовидного наследования.

Сейчас в процессе большого рефакторинга, из-за того что почти в самом начале сделал ошибку - решил делать UI отдельно от сцены. Однако со временем пришло понимание что эти вещи нераздельны. Как в плане игровой логики сцены, так и в плане редактирования. Конечно же хочется использовать все те фишки объектов сцены в интерфейсах - компоненты и вложенные прототипы. И это действительно важно, тк UI в играх иногда являются большей частью игры. Финал этого рефакторинга близок - скоро восстановится работоспособность редактора.

После этого в планах сделать редактрирование UI в редакторе, и наконец-то избавиться от тысяч строк кода генерации UI стилей.

#40
22:30, 19 апр. 2018

Немного новостей

Наконец-то закончил рефакторнг сцены и UI. Теперь UI это часть сцены, и все элементы интерфейса являются полноценными акторами, что значит что система прототипов (вложенных префабов) будет распространяться и на них. Правда, работа доделана не до конца, некоторые функции акторов не реализованы в UI. Сначала хочется сделать поддержку редактирования UI в редакторе.

Кстати, о редакторе. Собственно он, как и прежде, работает на своих же движковых UI. Был немного оптимизирован алгоритм пересчета layout'ов при изменении параметров, дабы уменьшить кол-во пересчитываемых элементов. Так же слегка оптимизирован и улучшен алгоритм отсечения невидимых элементов. Здесь, пожалуй, хочется только привнести еще большую оптимизацию - при простом перемещении элементов, например скролл, не пересчитывать заново всю геометрию, а сдвигать на вектор.

Еще оптимизировал property. Оказалось, что на них теряется очень много ресурсов. Изначально идея была простая - есть структура, которая принимает в себя указатель на getter и setter, хранит в себе промежуточное значение и инициализируется при создании объекта. Однако, здесь зарылся дьявол. Всего лишь пара аллокаций на одну property. Поначалу была уверенность, что кол-во property на одном объекте будет в районе 5ти штук, и такая реализация не отразится на производительности. Но количество property доходило до нескольких десятков, и на каждую несколько лишних байт и пара аллокаций. Например, ActorTransform, который содержал в себе параметры трансформации актора, без всех property создавался в 1000 раз быстрее и занимал в 6 раз меньше памяти, чем вариант с property. То есть создание каждого виджета сопровождалось кучей аллокаций, кучей лишней малоиспользуемой памяти. Решение простое, на первый вгляд эффективное, но не очень изящное: на каждую property теперь создается небольшой класс, которых хранит в себе this указатель на объект, который владеет этим property, и определены функции, которые используют те же setter и getter. Все это обернуто в макрос. Из плюсов, конечно же, стала производительность. Из минусов - пришлось переделывать рефлексию, синтаксис стал сложнее, ну и куча небольших классов плодиться на каждую property.

Вывод из этого в том, что куча ресурсов теряется на удобных мелочах. В такие моменты начинаешь ощущать, насколько много таких вещей в C#, Java, JavaScript и подобных на уровне языка.

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

Из недавнего, сделал отрисовку линий с небольшим антиалиасингом. Работает просто - генерируется меш нужной толщины, с небольшой кромкой вокруг, с уходящей альфой в ноль. Работает быстро и выглядит приемлимо, относительно обычных OpenGL линий. Как бонус можно лепить текстуру на линию, и можно делать всякие полосатые, пунктирные и всякие нескучные линии, что очень даже неплохо в редакторе.

Ближайшие планы - сделать редактирование интерфейсов, ну а после редактор анимаций. После этого (хоспаде когда уже это закончу), можно будет начинать делать какую-нибудь игру, параллельно и по мере надобности прикручивать скрипты типа LUA или JS, портировать на мобильные платформы, прикручивать звук и все такое. Спасибо что дочитал, мой дорогой аноним! )

#41
22:29, 20 апр. 2018

То что есть на гитхабе уже можно использовать для создания игры?

#42
0:29, 21 апр. 2018

Madware
> То что есть на гитхабе уже можно использовать для создания игры?
вообще при некотором усердии можно, но пока редактор мало полезен (

#43
16:07, 22 апр. 2018

Немного подправил линии, теперь в сравнении с обычными линиями просто ништяк
curves | o2

#44
21:30, 22 апр. 2018

оу, новые линии стали краше старых, прогресс идет!
а теперь без иронии, имхо так никогда инструмент не будет готов, если концентрировать свое внимание на таких мелочах

Страницы: 1 2 3 4 Следующая »
ПроектыФорумУтилиты