forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   Вопрос по архитектуре (http://forum.boolean.name/showthread.php?t=19741)

Nikich 17.03.2015 20:28

Вопрос по архитектуре
 
Есть объекты, который можно отрисовывать, обновлять, отрисовывать и обновлять. Хочется иметь общий контейнер для всех объектов и удобный способ выполнять над ними соответствующие действия (отрисовка, обновление). Как лучше всего реализовать?

Samodelkin 17.03.2015 20:55

Ответ: Вопрос по архитектуре
 
Самое простое это сделать иерархию и методы render() и update() этих объектов.
Код:

class object {
public:
    object* mpParent;
    std::vector< object* > mDescendants;

    void mUpdate_r( void ) {
        // TODO Update itself.

        for ( auto x : mDescendants ) {
            x.mUpdate_r();
        }
    }

    void mRender_r( void ) {
        // TODO Render itself.

        for ( auto x : mDescendants ) {
            x.mRender_r();
        }
    }
};

Таким образом можно выполнять все действия через корневой объект сцены.
Код:

sceneRoot.mUpdate_r();
sceneRoot.mRender_r();

Однако такой код -- далеко не самое эффективное решение с точки зрения производительности и гибкости и в более-менее серьезном проекте делают по другому.

Nikich 17.03.2015 21:15

Ответ: Вопрос по архитектуре
 
Спасибо! А не подскажете примеры открытых более-менее серьезных проектов?

Samodelkin 17.03.2015 21:54

Ответ: Вопрос по архитектуре
 
Среди серьёзных есть как плохие так и хорошие.
Например показывали что в Ogre3D очень плохой код.
В качестве хороших можно назвать idTech4 Engine.
Однако нужно учитывать что и язык и техники рендера с тех времён изменились, и не все подходы нужно бездумно копировать.
Я думаю что неправильно ориентироваться на готовые проекты, лучше понять что нужно именно вам и строить архитектуру исходя из этого.
Часто правильное решение возникает уже во время разработки, когда становятся ясны детали проекта.
Важно учитывать аппаратную составляющую платформы.
Из моих последних находок могу назвать data oriented design подход к программированию.
Одним словом полезно кроме знания готовых техник иметь навык и эвристических подходов к решению задач -- обычно верное решение может существовать только одно и только для вашего проекта, готовых рецептов нет.

Igor 18.03.2015 02:36

Ответ: Вопрос по архитектуре
 
Хм, а зачем ссылка на корневой объект?
Я бы просто сделал интерфейс с методами render и update, и его реализации в виде контейнера для других объектов и самих объектов.
P.S. это максимально общий уровень без залезания в подробности реализации, в каждом конкретном случае можно добавить какие-нибудь хаки для ускорения. Например, группировать их так, чтобы объекты с общим шейдером/ресурсами рисовались один за другим или обновлять объекты сразу из нескольких потоков - но все эти оптимизации есть смысл проводить, только если они действительно что-нибудь ускорят.

Samodelkin 18.03.2015 04:26

Ответ: Вопрос по архитектуре
 
Ну например чтобы правильно сделать трансформацию дочернего объекта, нужно знать данные о положении родительского.
В методе update может ещё что-то находиться, что требует данных о родительском объекте.
Если не нужно то можно и убрать.

Естественно можно сделать дофига и больше.
Нельзя же в одном посте рассказать о всех типах и деталях архитектур, это нереально.

pozitiffcat 15.04.2015 12:54

Ответ: Вопрос по архитектуре
 
Я делаю объект сцены, в нем список моделей, список освещений, камера. В свою очередь у модели есть геометрия, у геометрии есть список поверхностей с материалами. Все это модель мира. Скармливаем модель мира какому-нибудь рисовальщику, который в свою очередь юзает инфу и выпоняет методы рисования.
Так например для разделения OpenGL и DirectX можно использовать разные рисовальщики, при одной и тойже модели данных. Все ресурсы (Теустуры, буфферы), вы храните в каком-то контексте, и используете интерфейсы для них.
Незнаю насколько понятно объяснил.

P.s. насчет update. Делаете какой либо FrameListener с виртуальным методом update, и кормите своему объекту ядра. Ядро будет вызывать всем FrameListener-ам метод update. А что вы там реализуете, какой будет конкретный клас и чем заниматься, это уже ваще дело. Аля Ogre3D.

Samodelkin 16.04.2015 18:54

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

pozitiffcat 18.04.2015 19:21

Ответ: Вопрос по архитектуре
 
Цитата:

Сообщение от Samodelkin (Сообщение 295041)
pozitiffcat, модель гибкая но может страдать некоторыми проблемами с производительностью. Обычно я рекомендую в таких архитектурах перед рисовальщиком (который только рисует) вставлять сортировщик/кешировщик, который вытаскивает из всего этого запутанного дерева сцены данные в нужном порядке и распределяет это ввиде "сырого массива" без лишнего оверхеда и одним блоком. Таким образом быстро рисуется и нету кеш-промахов.

Так сортируй сценой, кто тебе не дает.

Samodelkin 18.04.2015 20:35

Ответ: Вопрос по архитектуре
 
Конечно код сортировки можно вставить куда угодно. Но если ты строго следуешь концепции ООП где всё должно быть разложено по полочкам то сцена и сортировщик вещи разные. Сцена это скорее не объект, а форма доступа к данным, просто в ООП всё называется объектами. Информацию об иерархии и отношениях между объектами сцены лучше хранить отдельно от самих объектов сцены. А сами объекты сцены должны содержать только то что требуется для рендера. Таким образом сцена делает надстройку (информационную и функциональную) над объектами сцены для возможности работать с ними с точки зрения взаимодействия пользователя со сценой. Но во время рендера эти надстройки убираются и остается сырой материал для максимально быстрого его вывода на экран. Так что формально сортировщик наверное должен находится где-то посередине и не относиться ни к сцене ни к рендеру. Потому что вот например фрустум или октри относятся к сцене, а сортировщик больше основывается на машинном представлении данных и относится скорее к менеджеру памяти или ресурсов.

pozitiffcat 19.04.2015 17:32

Ответ: Вопрос по архитектуре
 
Цитата:

Сообщение от Samodelkin (Сообщение 295089)
Конечно код сортировки можно вставить куда угодно. Но если ты строго следуешь концепции ООП где всё должно быть разложено по полочкам то сцена и сортировщик вещи разные. Сцена это скорее не объект, а форма доступа к данным, просто в ООП всё называется объектами. Информацию об иерархии и отношениях между объектами сцены лучше хранить отдельно от самих объектов сцены. А сами объекты сцены должны содержать только то что требуется для рендера. Таким образом сцена делает надстройку (информационную и функциональную) над объектами сцены для возможности работать с ними с точки зрения взаимодействия пользователя со сценой. Но во время рендера эти надстройки убираются и остается сырой материал для максимально быстрого его вывода на экран. Так что формально сортировщик наверное должен находится где-то посередине и не относиться ни к сцене ни к рендеру. Потому что вот например фрустум или октри относятся к сцене, а сортировщик больше основывается на машинном представлении данных и относится скорее к менеджеру памяти или ресурсов.

Я думаю не стоит мне разъяснять, что такое ООП. Я на данный момент ведущий-инженер программист одной крупной компании в сфере ритейла.
С опытом становится понятно, что ООП - это лишь средство для достижения цели. И не нужно городить ООП ради ООП. Тут нужно понимать, если твой код после внедрения фичи становится сложно читаемым и неразборчивым, выдели отдельный объект. Иначе нехер этого делать. Тоже касается и дублирования кода. Любую проблему можно решить миллиардами ООП способами. Тебе никто не мешает осуществить Mix-in, или например предположить, что все дочерние сцены будут иметь одинаковый метод сортировки, тогда сортировку можно реализовать в базовом классе. Нужно понимать, что ты хочешь, и просто делать это, ооп получится само с собой, когда ты начнешь понимать основные принципы.

Samodelkin 19.04.2015 18:32

Ответ: Вопрос по архитектуре
 
Цитата:

И не нужно городить ООП ради ООП.
Верно.

Просто у тебя был пост где ты отвергаешь очень полезные альтернативы.
Может ты конечно уже пересмотрел свои взгляды.
ООП помогает структурировать код, но и часто вредит производительности. Например есть безвредное ООП на уровне синтаксиса языка такие как Си структура при компиляции превращается в обычный блок данных, а вот например для полиморфизма нужно создавать дополнительные механизмы RTTI, как например хранение информации о типе вместе с данными объекта, которые часто сильно замедляют код.
Моё мнение что ООП хорош когда его используют на уровне языка или каких то конструкций на уровне проекта в целом, а при создании конкретного кода лучше ориентироваться на более платформозависимые подходы, такие как data oriented design.
Вот поэтому, если возвратиться к сцене, данные объектов, относящиеся к сцене, лучше хранить отдельно от данных объектов, относящихся к рендеру.

pozitiffcat 19.04.2015 19:14

Ответ: Вопрос по архитектуре
 
Тут опять таки неоднозначности. Если ты хочешь использовать несколько видов сцен? Обычные (тупые), окто, и BSP, смысл разделять код не вижу.

З.Ы. программирование - творчество. Тут не может быть единственно верного подхода. Каждые делает так как считает нужным. Я рассказал про свои взгляды, ты про свои. Не стоит разводить здесь холивар на эту тему.

А мой пост столетней давности не стоит воспринимать серьезно. Вся эта лабуда с интерфейсами нужна только ради чистоты пользовательского кода, не более. Я давно это понял и перестал так делать.
Код должен работать. Не стоит каждый раз думать о том, что "А вдруг мне это пригодится?", не пригодится ))) (С) Дядюшка Боб.


Часовой пояс GMT +4, время: 12:34.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot