Pushkoff
Как по мне, то слишком рьяно пытаться запретить все "неправильные" действия и влепить проверку везде где может случиться пух во первых бессмысленно, а во вторых иногда и вредно в плане производительности.
Эти методы отрисовки, к которым ты прицепился, суть просто инструмент для масштабирования приложения.
Простая сцена - юзай пару спрайтов, больше и не надо, но ни кто не запрещает выстроить по полной.
Сложнее - юзай список спрайтов, если больше не надо, зачем юзать лишний функционал.
Ещё сложнее - юзай уже полные наборы менагеров, и другие графические объекты.
Ну а самые сложные - уже оперировать на уровне полных графических сцен.
При том ни кто не мешает в самом лёгком приложении сразу использовать графическую сцену.
А метод рисования всегда один - вызов функции Draw():
Sprite.Draw() - рисуем один спрайт
SpriteList.Draw() - рисуем список спрайтов
RenderQueue.Draw() - рисуем кучу объектов, и спрайтов, и текст и банки
Monax-At
Поддерживаю.
Pushkoff
По поводу одного универсального метода, в любом случаи он будет набором компромиссов и здесь очень важно поймать баланс между удобством использования, безопасность, производительностью и масштабированием с точки зрения приложения. Что парой бывает очень сложной задачей, а вот от кривых рук ты ни как не защитишься(хотя можно уменьшить их влияние , делая перекос в сторону безопасность жертвую производительностью, но и эта проблема перекоса решается и можно компенсировать потерю производительности, но вылезет еще кое что еще один перекос ), можно уложить одним плевком и очень сбалансированную систему, а потом удет туева куча времени что бы раз рулить ситуацию.
MaximusPrime
Monax-At
я вам предлагаю перекос в сторону простоты и расширяемости - а это поважнее удобства будет...
я не знаю есть ли у вас опыт в разработке игр, но сядьте на досуге и подумайте как много у вас будет сцен с 2 спрайтами и как много сложных... сделайте работу с множеством спрайтов такой же легкой как и с одним! и помните что излишняя универсальность никому не нужна, движок должен делать только то что от него просят, и больше ничего...
Pushkoff
Опять повторюсь:) Смотрите что вам написал Monax-At
>Сложнее - юзай список спрайтов, если больше не надо, зачем юзать лишний функционал.
>Ещё сложнее - юзай уже полные наборы менагеров, и другие графические объекты.
И будет все пучком ни каких перекосов.. достаточно удобства и производительности и маштабируемо и в чем проблема.. спор не имеет смысла:) Но я хочу сказать что удобство то же должно присутствовать и все 4 составляющие должны быть в балансе. Я встречал очень много интересны вещей и производительных и маштабируемых(хотя не которые люди под маштабируемостью подразумевают удобство и это то же встречал), но использование и интеграция, а так же тиражировании их представляло собой очень серьезную проблему или требовало очень квалифицированного персонала. Я за баланс всех составляющих, это как вопрос многих или мейчас беспокоит вызов _ftol() внутренней функции С/C++(2001 году приходилось и это оптимизировать:) ух время было) , сейчас это ни кого не беспокоит производительности хоть отбавляй.
MaximusPrime
я не вижу здесь проблемы, так как движок не мой... я уже немного перерос тот возраст, когда от сферического движка в вакууме нужно было и блекджек, и девушки легкого поведения, и виски с виноградным соком, и сигара толщиной с 2 пальца скрученная меж грудей потомственной девственницы... поэтому, глядя с высоты своего опыта (а судя по упомянутым датам, смотрел я вверх) и намекнул вам на избыток функционала... а обращать внимание или нет на мое заявление это уже ваша проблема...
Pushkoff
Я согласен, с вами это дает определенный избыток, но он не так страшен и смысла его убирать нет. Хотя это не составляет проблемы.
Pushkoff
> движок должен делать только то что от него просят, и больше ничего...
Собственно сейчас всё что есть в движке, как раз и используется в реальных проектах.
> и намекнул вам на избыток функционала
То есть не нравится возможность отдельного графического объекта самого себя рисовать? + набор списков этих объектов + те же спрайт банки?
а какой функционал избыточен? вообще что предлагаешь сделать?
Monax-At
> а какой функционал избыточен? вообще что предлагаешь сделать?
у нас основной функционал это вывод меша с заданными атрибутами вершин и материалом, все остальное работает через него... то есть чтоб нарисовать квад надо написать 10-15 строк кода, но можно на пальцах посчитать места где нам нужно нарисовать квад, в остальных 99% случаев рисуется меш, и этот функционал ему как раз подходит...
я предлагаю вам хорошо подумать с чем работает ваш рендер... если это треугольники то сделать функцию вывода меша, если спрайты - то вывод картинки (в казуалках на попкапе которые я делал, в функции Draw в итоге пришли к обычному выводу картинки в заданный прямоугольник, в итоге, при правильном рефакторинге, необходимости виртуального вызова Draw не стало бы), если спрайты c анимацией - то сделать функцию типа Render.DrawSprite( sprite ), где sprite это просто data holder... где-то в одной из тем товарищ Z рассказал что их рендер оперирует RenderOPами и подробно описал их сортировку (у нас приблизительно тоже, но из-за избытка этого не видно)...
а банки спрайтов, списки спрайтов, слои и тп реализовывать уже поверх этого базового функционала, причем сразу думать в сторону компонентов (сейчас много тем в коде по этому поводу)...
исходный код вашего движка открыт?? а то, только что начало казаться что pTSpriteViewer и pTBaseVertexData и являются классами которыми оперирует рендер, но я не могу понять почему их 2 и почему они так названы... рантайм мультирендер?
Pushkoff
> чтоб нарисовать квад надо написать 10-15 строк кода, но можно на пальцах посчитать места где нам нужно нарисовать квад, в остальных 99% случаев рисуется меш, и этот функционал ему как раз подходит...
Интересно интересно. 10-15 строк кода, это с инициализацией всей системы рендера или только настройка меша?
У нас несколько отличный опыт от вышеприведённого, как раз спрайты покрывают весь нужный объём функционала, доступ к самому мешу используется только для специальных спецэффектов.
Кстати, спрайт первоначально использовал меш-элемент, но в последствии так как сам меш не использовался на полную, он превратился в 2 треугольника в TGraphicElementSquare
> пришли к обычному выводу картинки в заданный прямоугольник
Тоже знакомый метод, и приходилось работать с одним движком, который его использовал. Но у нас меш выводится.
> исходный код вашего движка открыт??
Нет, не открыт. У нас есть определённые договорённости с одним заказчиком, запрещающие открывать исходный код, да и пока ещё не пришли к единому мнению по поводу открытия.
По поводу pTBaseVertexData и pTSpriteViewer я уже как то писал. Суть в том, они оба используются, при том если уж так смотреть, то конечно pTBaseVertexData можно убрать с частью функционала, но есть один момент, он может использоваться для внешнего задания пула вершин, для оптимизации некоторых тяжёлых сцен.
Да, поддерживается OpenGL и DirectX8(хотя лично я бы уже давным давно перешёл бы на как минимум 9-тый ДХ)
Вообще о чём речь идёт.
Основные идеи, которые определяют его архитектуру:
- Графический объект не зависит от типа рендера, для его рисования используется специальный объект-виевер, который и зависит от типа рендера и создаётся устройством.
- Графические объекты состоят из набора элементов, которые и определяют его структуру. Для того, что бы добавить новый графический объект, достаточно собрать его из нескольких готовых элементов. Например - тот же воксель. Цвет, размер, позиция, эти элементы уже есть и готовы к работе, надо только добавить класс и описать виевер.
Собственно эти две идеи и используются уже хз сколько времени.
Весь функционал, который сейчас входит в движок, он используется постоянно. Вот те же банки спрайтов, ну отдельный графический объект, по сути список спрайтов с позицией, с одной стороны его можно и убрать из движка, а с другой он оказался полезен и удобен в работе.
На сколько я понял, тебе больше нравится вариант, когда движок имеет минимальный необходимый функционал для вывода графики, всё остальное уже допиливается под себя самими программистами в той или иной ситуации. Я правильно понял?
Pushkoff
>рантайм мультирендер?
Да, можно организовать приложение и так, все для этого есть в наборе:) Практически все проекты идут в двух рендерах DX8(ну как руки чешутся сделать DX9/10/11 и времени не так много надо) и OpenGL, переключение рендеров в настройках. Сборка под Linux/Mac просто отключает DX часть(ну и всего что для Win платформы) и остается только OpenGL:) Расширение движка - это написание устройства вывода(если надо) и вивера(того кто выводит обьект) графического обьекта.
Как сказал коллега, графические обьекты не зависят от рендера, на уровне игровых сцен вы оперируете логическими обьектами и графическими обьектами что вполне достаточно для написания игры практически любой сложности и не требует фундаментальных знаний аппаратной части, аппаратная часть вас заботить не должна, при условии если вы не реализуете какой - то специфический спец эффект, или не расширяете возможность движка.
Так же есть в наборе все необходимые кирпичики если надо собирать какой то новый графический обьект. Кстати тут уже упомянутый воксель(пока экспериментальный графический обьект, сейчас с ним как раз ведутся работы), все есть, что не скажешь об аппаратной части, но это совсем другая песня.
Monax-At
>когда движок имеет минимальный необходимый функционал для вывода графики
Потом все превращается в постоянное изобретение велосипедов или костылей, пока велосипедов или костылей не наберется достаточное количество (если задачи стоят на потоке и на подпил костылей дико не хватает времени, то это все грозит превратиться в огромного монстра на тонюсеньких ногах, ну с очень большим количеством подпорок). Кстати есть и такой подход:) здесь все завесит от организации процесса разработки.
Но как я уже говорил на вкус и цвет, но я за баланс всех 4 мной упомянутых направлений, есть еще 5 я о нем не упоминал, но его ни кто не отменял.
Monax-At
> На сколько я понял, тебе больше нравится вариант, когда движок имеет
> минимальный необходимый функционал для вывода графики, всё остальное уже
> допиливается под себя самими программистами в той или иной ситуации. Я
> правильно понял?
да. допустим основной рендер умеет выводить меши, если нам нужны экранные квады, то мы пишем рендер который скроет собой функционал вывода мешей, а даст нам функционал вывода квадов и назовем его UIRender и тп. то есть движок начинает делиться на слои, самый нижный просто враппер удобный или кросплатформенный враппер над GAPI, UIRender это удобный враппер над основным рендером дающий возможность выводить квады... тоесть UIRender и GUI в целом уже не являются частью core subsystem, они живут отдельно, возможно в утилитах... если мы отключаем, то отключаем полностью а не оставляем кучу неиспользуемого кода... тожесамое со сцен менеджером, он тоже должен быть отдельной частью, так как то что хорошо для одной игры плохо для другой... то есть в core subsystem останется только матлиба, файлы/потоки, списки/деревья и тп утилиты/интерфейсы (допустим ввод с клавы) и рендер (хотя и он может быть утилитой)...
в итоге вы получаете очень сильно модульную и очень слабо связанную архитектуру...
и еще посмотрите в сторону статического полиморфизма (для рендера), недавно в одной из тем где обсуждалось что линус торвальдс ненавидит С++, я привел пару шаблонов которые позволят это реализовать... допустим у нас движок запускается на десятке разных платформ и ГАПИ, и допустим команда CreateDevice( IDeviceType::D3D11 ) бессмысленна на iPhone и Андроиде но возможна...
плохо что код не открыт... так как все что я говорю опирается на то что написано в статьях, а там очень мало информации...
Pushkoff
Собственно у нас тоже можно без проблем отключить например тот же DX рендер, убрав его из кода и просто использовав GL-устройство, по сути приложение даже не заметит "потери бойца". Так же ни кто не мешает использовать только одни спрайты или только свой самописный графический объект. При этом в том или ином случае подключать только нужный функционал.
Да и система опробована уже и на крупных казуальных играх и на минииграх. И она реально работает.
У нас ядро более функционально, чем то, что у тебя описано, делалось так, что бы всё что надо есть, но ничего лишнего. Его хватит что бы создать приложение + базовый каркас для написания логики. Уже все вспомогательные системы вынесены в расширения.
Так же стараюсь делать так, что бы можно было посадить относительно малоквалифицированного работника, объяснить ключевые момент и что бы он смог писать код.
Имхо, в случае создания не правильного девайса, который не поддерживается устройством, лучше получить ошибку с описанием, чё вооще не так, чем что бы код отработал в "бессмысленном но возможном" варианте :)
Ну а код закрыт, тут уж такие обстоятельства.
Ну а статьи будут добавляться, да и уже выложенные будут редактироваться, так же думаю и пару демок добавить.
Monax-At
> что бы можно было посадить относительно малоквалифицированного работника
ну в этом случае все средства хороши))
но с другой стороны, это отнимет возможность профессионального роста работника и работа ему быстрее надоест, а в этом случае зависит от работника или начнет говнякать (причем это худший вариант) или уйдет...
если код закрыт, та какие у него условия использования??
Тема в архиве.