MiF
Shared_Material_Render устойчивый интерфейс через него рулит материал в Material::setup_material(Shared_Materila_Render);
xmvlad
вообще скажи мне о чем тут речь, об построении абстракного много целевого движка, или о создании движка под конкретную игру \ проект ?
т.к. подходы тут совершенно разные - в первом случае на 1м месте архитектура а во втором - элементы ХР подхода.
korak
первое, но эта архитектура вполне сочитается с ХР :))
MiF
на свежую голову, проанализирвоал то что вчера мы тут с тобой написали :) материалы надо отделять в параллельную иерархию, тот же паттерн, что и с рендер агентами, только применяется к материалам, все остальное (рендер агенты, сортировка, отсечение) остается таким же(без интерфейса Shared_Material_Render)
class Material { virtual void bind() = 0; }; class Concrete_Material: public Material { void bind( ) { m_mat_binder->bind_concrete_material( this); } private: Material_Binder* m_mat_binder }; class Material_Binder { private: void bind_concrete_material( Concrete_Material* concrete_material); };
xmvlad
Я тебе об этом сказал в аське два дня назад.
PS: XP еще тот, от первоначального дизайна нифига уже не осталось :)
MiF
>Я тебе об этом сказал в аське два дня назад.
нет, ты тогда про рендер агентов говорил :)
> PS: XP еще тот, от первоначального дизайна нифига уже не осталось :)
как это не осталось, все рендер агенты на месте :) и работают, просто произошло расширение :)
PS: в общем все кристализовалось :), скоро сваяю статью с детальным более описанием архитектуры.
так, основной пойнт - для ацкого рендера нужен общий пайплайн для сортировки, early-z, back-to-front и других вещей, в том числе глобальных операций. Конкретные типы не нужны, рендер агенты в топку.....
Ну вот прям так сразу и приплыли. За что боролись, на то и напоролись. По-моему, тема про HOM тебе голову сильно вскружила.
Я думаю, на самом деле тут такая вилка:
1. Cache coherency (TnL, post-TnL)
1.1. Shaders/Textures/States sorting
1.2. Mesh sorting
2. Z-ordering
То есть, либо идти по пути улучшения всяческих операций, связанных с увеличением эффективности кеша (1),
либо бить на сортировку по удаленности (2) - для сбережения филлрейта и еще бог знает чего (OQ и др).
Естественно, если выбрать какую-то одну установку, то аццкого рендера не выйдет. Как вариант, можно попробовать
извратиться и добавить к твоим агентам дополнительную функциональность для сортировки.
Padawan
> Ну вот прям так сразу и приплыли. За что боролись, на то и напоролись. По-моему, тема про HOM тебе голову сильно
> вскружила.
нет HOM не виноват :)
мне удалось в мирке пообщаться с СЕМЕН ом на эту тему, и он меня просветил :) что для z-early, front 2 back, прозрачности и т.д вещей нужна общая сортировка, то есть основной мой пойнт: конкретные типы (у каждого рендер агента) в процессе рендеринга, становится без смысленным. :( Нужен общий пайп + "локальная" обработка, которую можно всунуть на уровень объектов. (непосредственно в ->render()).
xmvlad
Можешь сформулировать положения, когда нужен early z? Так-то я понимаю, что для экономии филлрейт-ресурсов, поедаемых сложными пиксельными шейдерами и если имеются разноразмерные объекты. Если еще принять во внимание амбиентные хардварные оптимизации, то в этом свете не очень четко понятно, когда применять early z.
Такое впечатление, что пропущен важный пункт, а именно - ТЗ на рендер. То есть, создание архитектуры началось как-бы из одной точки (ты так и назвал "пойнт"). Давайте попробуем оформить свойства рендера.
Чтобы формализовать требования к рендеру, нужно обозначить основную сущность, с которой будет работать рендер. Её основные и специфические свойства. Впоследствии выделить структуру рендера (SceneGraph + принимающая примитивы часть или еще как-то). А потом подумать над архитектурой, вывести абстрактные интерфейсы.
Ой, меня понесло немного. Давайте коллективным разумом определим "сущность", с экземплярами которой работает рендер.
Padawan
join #gamedev_lecture :)
xmvlad
Мои 5 копеек. Render agent architecture позволяет привязать к одному Mesh'u несколько агентов (аниматоров). Так сделано в Irrlich'e. И мне больше нравится. Например привязываем к Mesh'у FrameAnimationAnimator и SplinePathFollowingAnimator. А вот APIWrapper должен быть один.
Например:
class IAnimator; ///// Mesh - только контейнер данных (вершины, материалы etc., etc., etc) class IMesh : public ISceneNode { Vertices vertices; Materials mat; TexCoords tex; ....................... int addAnimator (IAnimator& anim); void removeAnimator ( int animatorNum); } class IAnimator { IAnimator ( IMesh& AnimatedObject); virtual ~IAnimator( ); virtual void update ( float deltaTime) = 0; } /////////////////////////////////////////////////////////////////////////////////////// // API Wrapper - шняга, которая занимается рендерингом и ВСЕ ////////////////////////////////////////////////////////////////////////////////////// class IVideoDriver { virtual bool init ( int width, int height, int color_depth, int window_id /*HWND для Windows*/, bool Z_Buffer, bool Stencil_Buffer); virtual void shutDown ( ); virtual void renderMesh ( IMesh mesh); virtual void applyTransformation ( Matrix_4x4& mat, TANSFORM_TYPE type); virtual Matrix_4x4 getTransformation ( TRANSFORM_TYPE type) const; virtual void bindTexture ( ITexture& tex); virtual void bindMaterial ( Material& mat); } class D3DVideoDriver : public IVideoDriver; class OGLVideoDriver : public IVideoDriver;
А вот сортировкой по материалам и отсечением по Frustum'у занимается SceneManager. (подробнее про SceneManager я написал http://www.gamedev.ru/community/oo_design/forum/?id=835)
Мнение: выглядит это "не красиво" :). Я до сих пор не знаю как сделать "красиво" :)...но попытка сделать так (примерно) привела к полному сливанию в ... всего двига (моего первого). Теперь делаю как можно проще "чем меньше иерархия классов тем лучше", это главное правило. Я теперь постоянно ловлю себя на желании наплодить лишних потомков...и успешно его подавляю :). Кстати, может не по теме, но хороший результат при разработке подобных "больших" классов, дает отделение их в отдельный проект. У меня сейчас под большие классы, сделаны отдельные (не связанные) проекты. Это позволяет писать "многоразовый" код...и не запутаный (в вашем случае чем дальше тем запутанее будет). При этом отделение классов друг от друга позволяет их писать так (выхода другого нет...проект отдельный совсем) что потом я использую их в самых разных программах :). В редких случаях приходиться делать несколько классов в одном проекте. Т.е. в солюшене "Game" есть штук 10 проектов таких как "Loader", "Physics" и.т.д. И эти классы могут существовать независимо.
В общем навеяло :)
3DRaven
Пиши процедурами:
while(1) { if ( !GetAllEvents( )) return 0; CalcAllPhysics( ); AnimateAllModels( ); PlayAllSounds( ); DrawAll( ); }
Будет очень красиво :)
Тема в архиве.