форум DProgramming.ru
03 Сентября 2010, 22:15:04 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
   Начало   Помощь Поиск Войти Регистрация  
Страниц: [1] 2
  Печать  
Автор Тема: Редизайн (лог работы)  (Прочитано 1429 раз)
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« : 30 Октября 2009, 18:39:36 »

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

Я посчитал данное время подходящим для исправления того, что не устраивало в разработке движка и нем самом, посему:
1. Subversion -> Mercurial
2. GoogleCode -> BitBucket
3. Derelict -> xf.Dog и пр
4. Helix -> xf.OMG
5. MoonGlide += xf.Hybrid GUI
6. MoonGlide += MiniD scripting

Заодно пробую поправить архитектуру на более интересную/удобную/дишную: в эту тему буду писать о новых решениях в движке.
« Последнее редактирование: 02 Апреля 2010, 09:46:12 от digited » Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #1 : 30 Октября 2009, 18:42:42 »

Том Стаховьяк посоветовал почитать game architect, понравились статьи по движок Despair. В одной из них говорится про компонентный подход к объекту сцены вместо древовидного и про объединение объектов движка с игровыми.

Подумал, как может выглядеть нод сцены, содержащий компоненты, ну и работа с ними:

Код:
module TemplatesTest;

import tango.io.Console;

class Geometry { void DoSomething() { Cout("Working with a Geometry component").newline;}}
class Camera { void DoSomething() { Cout("Working with a Camera component").newline; }}

class Node
{
protected:
Object[char[]] components;

public:
Node AddComponent(T)(T component = null)
{
if( component !is null )
{
components[component.stringof] = component;
}
else
{
if((T.stringof in components) is null)
components[T.stringof] = new T;
}

return this;
}

bool WorkWith(T)(void delegate(T component) dg)
{
Object *c = T.stringof in components;

if( c !is null )
{
dg(cast(T)(*c));
return true;
}
else
return false;
}
}

void main()
{
scope node = new Node;
node.AddComponent!(Camera)().AddComponent!(Geometry)(); // по идее, подобное нужно будет и из редактора, и в рантайме.

node.WorkWith((ref Geometry g) { g.DoSomething; });  // делегат вызывается, если компонент данного типа содержится в ноде.
node.WorkWith((ref Camera c) { c.DoSomething; }); // такой вызов можно проверить на true/false, кроме того, делегат видит локальные переменные.
}

Вот что пока получилось: http://bitbucket.org/digited/moonglide/src/tip/scene/Node.d
« Последнее редактирование: 02 Ноября 2009, 13:46:21 от digited » Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #2 : 30 Октября 2009, 18:50:28 »

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

Пока получается как-то так:

Код:
module Main;

import
mg.gl.Renderer,
mg.demo.simple.SimpleScene;

void main()
{
scope r = new glRenderer();

auto scene = new SimpleScene(new sceneProcessor(r));
scope(exit) delete scene;
    
while (r.gotWindow() && scene.running())
scene.Run();
}

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

Создание сцены зовет ее инициализацию (что частично защищено тем, что процессор требует отрисовщика, то есть уже можно инициализировать графические ресурсы), по итогам которой сцена может или не может Run.

Процессор сцены не знает о самой сцене, а после Run() получает граф сцены с некоторыми настройками. Граф тоже может быть любой и рулить нодами по-своему.

Окно уехало в отрисовщик, xf.Dog так упрощен. Ну и оно неплохо, самому граф движку ведь на окно, по большому счету, забить.

Менеджер сцен отмер за ненадобностью, ядра движка тоже не будет.
« Последнее редактирование: 30 Октября 2009, 19:03:17 от digited » Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #3 : 02 Ноября 2009, 01:19:43 »

Добавил инструкции по сборке в вику: http://bitbucket.org/digited/moonglide/wiki/Build_instructions
Инструкция подразумевает, что у вы под линуксом и у вас установлены LDC + Tango из транков.
Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #4 : 02 Ноября 2009, 11:31:20 »

Mesh приобрел человеческий вид благодаря небольшому использованию шаблонов, ну и динамические поля за неактуальностью стали статическими (хотя сами по себе - все те же динамические массивы).

Как было: http://code.google.com/p/moonglide/source/browse/trunk/trunk/moonglide/resources/resobjects/lowlevel/ResMesh.d
Как стало: http://bitbucket.org/digited/moonglide/src/tip/res/Mesh.d

Наследование от IResource тоже ушло: загрузка ресурса типа "черный ящик" (была по opCall с внутренним обращением аж до менеджера ресурсов и в io) отправилась в топку, io будет явным.

Ну и поскольку древовидность в Ди встроена (все классы наследуются от Object), а динамическое приведение вниз достаточно дешево, плюсовые темы общего интерфейса к принципиально разным сущностям в ди не нужны.
« Последнее редактирование: 02 Ноября 2009, 11:39:13 от digited » Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #5 : 02 Ноября 2009, 11:47:21 »

Поскольку в Ди модули образуют собственное пространство имен, названия классов лишились балласта ввиде C/I + конечного пакета - теперь в названии модуля лучше используется полное имя пакета для избежания дублирования букв: resource.lowlevel.mesh.CResMesh -> res.Mesh, res.mesh.Factory, res.mesh.IO, scene.Node, scene.Graph и тд.
Конфликты использования имен (типа получившегося gl.Renderer vs scene.Renderer в Main.d) решаются с помощью алиасов (по месту использования или объявления, я пока использовал второе):

http://bitbucket.org/digited/moonglide/src/tip/scene/Renderer.d (последняя строка)
http://bitbucket.org/digited/moonglide/src/tip/gl/Renderer.d (последняя строка)

http://bitbucket.org/digited/moonglide/src/tip/demo/Main.d - использование алиасов (glRenderer).
« Последнее редактирование: 02 Ноября 2009, 14:06:17 от digited » Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #6 : 03 Ноября 2009, 20:19:12 »

Собрал под WinXP: http://bitbucket.org/digited/moonglide/wiki/Build_instructions
Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #7 : 05 Ноября 2009, 11:26:27 »

Вот так выглядит работа с xf.Dog на примере gl caps, а так было (в начале модуля).
Классная штука, в общем.

Камера стала работать следующим образом:
- нод с камерой можно свободно цеплять к любому родителю в графе;
- на один проход графа устанавливаются параметры проецирования и смещение одной камеры, хотя самих нодов-камер в графе может быть сколько угодно;
- при добавлении/перемещении нода-камеры граф снабжает его делегатом на изменение состояния (камера вкл/выкл), сохраняет в массив камер и, если она вкл, ставит активной. Один граф - одна активная камера, но все учтены, и процессор имеет к этому делу доступ.
- пока сделал просто установку матрицы проекции, позже добавлю к этому размотку родителей нода камеры для установки смещения/поворота матрицы модели-вида.

Поэкспериментировал с variadic templates, в итоге нод получил определение компонентов в один вызов:
Код:
auto n = new Node;
n.willBe!(Placed, Camera);
заодно добавил фабрику (статический метод of):
Код:
auto n = Node.of!(Placed, Camera);
« Последнее редактирование: 06 Ноября 2009, 01:16:07 от digited » Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #8 : 07 Ноября 2009, 05:22:02 »

Проблема в xf.dog с закрытием декорированного окна решается пока патчем (обсудим с Томом, как лучше сделать обработку запроса от иксов на закрытие окна).
Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #9 : 08 Ноября 2009, 04:24:29 »

Долго думал и экспериментировал с интерфейсом рендерера, glRenderer и передачей объектов на рендеринг:

- надо передавать произвольные компоненты на отрисовку;
- шаблонные функции не могут быть полиморфными (перегружаться в наследниках с добавлением в vtable);
- хотелось бы рендерер сделать именно интерфейсом, а интерфейсы в ди плохо дружат с шаблонными методами (в отличие от классов).

В итоге остановился на простейшем варианте: поскольку объекты для рендеринга не зависят от конкретной реализации рендерера, те обобщены, и каждому рендереру надо реализовывать метод с каждым объектом в качестве параметра, то просто тупо импортировал нужные компоненты (Geometry и Sprite пока) в рендерер и написал по методу под каждый с перегрузкой по типу параметра. В общем, brute force, не хотелось убивать добрую неделю на эту мелочь. В будущем можно замутить что-нибудь гибкое, но пока с разбегу не получилось, поэтому - нафиг.

Сделал рендеринг сеток и применение ориентации и положения как камеры, так и объектов, выглядит так (в движении):


Соответственно, в вике появилась страница со скриншотами.
Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #10 : 05 Января 2010, 13:43:13 »

Прикрутил Hybrid, добавляю виджеты, ну и добавил немного звезд на фон (меш с отрисовкой точками). Демо тут (для Windows).

700 кадров в секунду под Windows, 1.3 под Ubuntu Karmic с NVidia proprietary driver 185, профилирование показывает, что тормозит код (!) и весь равномерно и ужасно. Ночью поставлю OpenSuse, сравню.
Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #11 : 06 Января 2010, 15:19:03 »

Фиксы в xf:
Dog - поправлено закрытие декорированного окна под линуксом, добавлены gl.GetError, glu.ErrorString.
Hybrid - налажен Input (кривая кодогенерация DMD 1.051 в In-контракте).

Все еще тормозит в убунте, сколь чудовищно, столь и необъяснимо, собираюсь потестить в сузе на днях.


Опробован xfProf, очень понравился.
« Последнее редактирование: 06 Января 2010, 16:58:31 от digited » Записан

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #12 : 07 Января 2010, 04:48:32 »

Добавил консоль.
Демо тут (пока только под Windows).

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

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #13 : 02 Апреля 2010, 09:45:56 »

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

0 errors, 0 warnings, 0 survivors
digited
Модератор
Энтузиаст

Сообщений: 529

3D

digited@jabber.ru
« Ответ #14 : 05 Апреля 2010, 17:00:30 »

Уровень тесселяции сферы в demo.Sphere теперь настраивается через ui, сама тесселяция производится в отдельном потоке.

Чтобы собрать текущий код, обновите его весь (под виндой - mg\demo\build\UpdateAll.bat) и в xf.hybrid.widgets.Spinner сделайте у InputSpinner внутренние компоненты публичными: http://welna.team0xf.com:8080/hybrid/file/143c882eb6de/widgets/Spinner.d#l296 (пока общаюсь с Томом по этому поводу).

Обнаружились две вещи:
- создание tango.core.Thread с inline delegate в качестве параметра работает криво - что-то где-то в коде кешируется, и обновить переменные в теле делегата при пересоздании потока нельзя. Использование ссылки на метод работает, как надо.
- tango.util.container.HashMap отказался корректно работать на winXP на работе, испортив содержимое. Попробую потестить разные аллокаторы позже, пока перевел scene.Node на Object[char[]]
« Последнее редактирование: 05 Апреля 2010, 17:03:57 от digited » Записан

0 errors, 0 warnings, 0 survivors
Страниц: [1] 2
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.10 | SMF © 2006-2008, Simple Machines LLC Valid XHTML 1.0! Valid CSS!