Забавно, куда порой могут привести несколько экспериментов. Вроде бы план был простой — посмотреть, что там такого интересного в этом вот вашем вулкане, что за хайп такой. Ну, нарисую что-нибудь. Нет, не треугольник, что-то посложнее, чем треугольник. Ручное выделение и освобождение дескрипторов? Ну уж нет, стрелять себе по ногам я не хочу, мне на них ещё ходить.
Дальше — веселее. Жонглировать фреймбуферами в OpenGL – не сказать, что очень приятное занятие, а здесь вся логика намекает на такой подход. Попробую-ка я реализовать отложенное освещение. Фреймбуферы, значит, и рисовать хочется что-то посложнее треугольника? Пора изобрести меши и техники рисования… И чем дальше, тем больше вопросов, тем интереснее задачи, и тем веселее эксперименты. Сначала это был полигон для экспериментов с вулканом, потом — полигон для архитектурных экспериментов. А потом стало понятно, что появляется что-то самостоятельное. Доработаем немного напильником, и, пожалуй, можно показать людям. Вдруг кому пригодится.
Итак, знакомьтесь - mtt.
Mtt – это набор библиотек c++, который может помочь вам на старте, если вы хотите написать приложение, работающее с 3d графикой. Он распространяется под MIT лицензией, так что фактически можете использовать mtt как хотите.
Игровой движок? Нет конечно. Вы можете попробовать написать на нем игру, но, честное слово, есть куда более достойные варианты, которые отнимут у вас гораздо меньше сил и времени. Mtt развивался как лаборатория для экспериментов и получился довольно гибким. Так что стоит обратить на него внимание, если вы хотите сделать что-то нестандартное, имеющее собственную систему отрисовки.
Прежде всего стоит рассматривать mtt как довольно тонкую обертку вокруг вулкана, которой он изначально и создавался. Собирать и настраивать шейдерные программы, подключать к ним сэмплеры и вершинные буферы, передавать данные через униформы. Если вам знакомы эти слова, то, вероятно, вам стоит взглянуть на mtt. Он сильно упрощает работу. Вот так, например, можно создать и заполнить вершинный буфер:
mtt::Buffer positionBuffer(displayDevice, mtt::Buffer::VERTEX_BUFFER);
std::vector<glm::vec3> positionsData ={ glm::vec3(-1.f, -1.f, 0.f),
glm::vec3(-1.f, 1.f, 0.f),
glm::vec3( 1.f, -1.f, 0.f)};
positionBuffer.setData( positionsData.data(),
positionsData.size() * sizeof(positionsData[0]));
А вот так - подключить его к пайплайну:
VertexAttribute& positionAttribute =
pipeline.getOrCreateAttribute("positionLocation");
positionAttribute.adjustDataType(VertexAttribute::FLOAT_VEC3_TYPE);
positionAttribute.attachBuffer(&positionBuffer);
Естественно, что со временем mtt оброс и более высокоуровневыми возможностями. Первая из них — это, конечно, работа с графом сцены и построение по нему плана рендера. То есть mtt берёт на себя большую часть рутины, когда нужно обойти видимые объекты сцены, выбрать техники рисования, отсортировать команды отрисовки по проходам и по расстоянию до камеры. Вы можете сосредоточиться только на данных и способах их отрисовки. Меши и техники рисования служат именно для этого. В сущности, это надстройка над буферами и пайплайнами, автоматизирующая многие типовые задачи.
Библиотека mtt::clPipeline – это реализация конкретной рендер-ситемы, то есть техник рисования и последовательности проходов отрисовки. Вам вовсе не обязательно использовать именно её, большая часть mtt к ней не привязана. Скорее, это быстрый старт, который поможет на начальных этапах, или прототип, на основе которого можно сделать свою систему.
Вторая важная часть – это набор часто используемых примитивов. Mtt развивался в основном в сторону инструменталки, поэтому тут вы можете найти манипуляторы, команды редактирования и undo/redo стек, асинхронные задачи, типовые виджеты и т.д. Это тоже своего рода быстрый старт, который должен помочь на первых порах.
Посмотрите на приложения ObjectEditor и ParticlesEditor. Оба они входят в состав mtt, и оба построены на общих компонентах. Хотя они и похожи друг на друга больше чем братья, но выполняют при этом совершенно разную работу. Если ObjectEditor – это простенький, в общем-то, редактор моделей, то ParticlesEditor – это флюид-симулятор.
Если посмотреть в исходный код этих редакторов, то можно заметить, что он практически полностью состоит из классов, описывающих обрабатываемые данные, а также из виджетов, управляющих этими данными. Унификация творит чудеса, и для написания двух разных редакторов потребовалось лишь описать предметные области и добавить немного кастомного GUI.
Вместо заключения
Что же, думаю, что я тут уже достаточно понаписал для привлечение внимания к mtt. В репозитории вы найдете intoduction.md и примеры. Этого, по моим прикидкам, должно хватить для начала. Если библиотека вызовет интерес, то займусь документацией более основательно. Главный вопрос в том, интересно ли это ещё кому-нибудь?
Благодарности
Модель баобаба(лицензия CC-BY-SA 4.0), получена с opengameart.org. Предоставлена Skodvirr, Screaming Brain Studio, YouriNikolai.
Скейбокс(лицензия CC BY 3.0) получен из humus.name, создан Emil Persson, aka Humus.
Материал камня предоставлен Nobiax, получен с opengameart.org
Большое спасибо авторам этих работ.