Урок №16. Библиотека импорта 3D-моделей Assimp в OpenGL

  Дмитрий Бушуев  | 

  Обновл. 2 Июн 2020  | 

 1581

 ǀ   6 

До сих пор во всех создаваемых нами сценах присутствовал наш маленький друг — деревянный контейнер, но с течением времени уже хочется чего-то большего, правда? Большие графические приложения обычно содержат много сложных и интересных моделей, которые выглядят гораздо красивее, нежели статический контейнер. Однако, если мы в нашей программе захотим использовать более сложные объекты, вроде домов, транспортных средств или человекоподобных персонажей, то столкнемся с проблемой, что, в отличие от объекта-контейнера, мы не сможем задать для них вручную все вершины, нормали и координаты текстур из-за сложности форм вышеназванных объектов. Вместо этого мы можем импортировать в приложение данные о моделях; моделях, которые были старательно разработаны 3D-дизайнерами в таких инструментах, как Blender, 3DS Max или Maya.

Импорт 3D-моделей

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

Наша задача — проанализировать экспортированные файлы моделей и извлечь из них всю необходимую информацию, чтобы в дальнейшем представить её в том формате, который будет понятен для OpenGL. Общая проблема заключается в том, что существуют десятки различных форматов файлов моделей, каждый из которых экспортирует данные о модели своим собственным уникальным способом. Например, файл модели формата .obj содержит только данные о модели и незначительную информацию о её материалах, вроде цвета модели и диффузных/зеркальных карт, в то время, как файлы моделей формата COLLADA, построенные на использовании стандарта XML, чрезвычайно обширны и содержат информацию о модели, освещении, различных типах используемых материалов, данных анимации, камеры, полную информацию о сцене и многое другое.

В общем, существует довольно много различных форматов хранения моделей, не имеющих при этом между собой какой-либо общей структуры. Поэтому, если мы хотим импортировать модель из каких-либо файлов моделей, нам придется самим написать импортер для каждого из используемого нами формата файлов. Но к счастью для нас, для этого уже есть готовая библиотека.

Библиотека загрузки 3D-моделей


Одной из самых популярных библиотек импорта 3D-моделей является Assimp (англ. «Open Asset Import Library» = «Свободная Библиотека Импорта Ресурсов»). Assimp может импортировать информацию из десятка различных файловых форматов (и экспортировать в некоторые из них), загружая все данные о модели в свои собственные обобщенные структуры данных. Как только Assimp загрузит модель, мы сможем получить все необходимые данные из этих структур. Поскольку структура данных в Assimp остается неизменной, независимо от типа импортируемого формата файла, то она абстрагирует нас от всех существующих форматов файлов.

При импорте модели через Assimp, библиотека загружает всю модель в объект сцены, содержащий все данные импортированной модели/сцены. В результате этого Assimp создаст определенную иерархию, состоящую из узлов, в которой каждый узел содержит индексы данных, хранящихся в объекте сцены, и где каждый узел может иметь любое количество дочерних элементов. Ниже показана (упрощенная) модель структуры данных, которую организует библиотека Assimp:

Рассмотрим это детальнее:

   Scene (Сцена) — здесь содержатся все данные сцены/модели, типа материалов и mesh-ей (об этом чуть ниже). Этот объект также хранит внутри себя ссылку на корневой узел сцены.

   Root Node (Корневой узел сцены) — может содержать дочерние узлы (как и все остальные узлы) и может иметь набор индексов, указывающих на mesh-данные в массиве mMeshes объекта сцены. Массив mMeshes сцены содержит фактические Mesh-объекты, а значениями массива mMeshes выбранного узла являются индексы для массива meshes объекта сцены.

   Mesh — содержит все соответствующие данные, необходимые для рендеринга сцены, например: положение вершин, нормальные векторы, координаты текстуры, грани и материал объекта.

   Face (Грань) — представляет собой примитив визуализации (треугольники, квадраты, точки). Грань содержит индексы вершин, образующих примитив. Поскольку вершины и индексы разделены, то это облегчает нам визуализацию через буфер индексов (см. Урок №4. Рисуем наш первый треугольник в OpenGL).

   Material (Материал) — содержит несколько функций для получения информации о свойствах материала объекта. Чем-то может напоминать вам цветовые и/или текстурные карты (например, диффузные и зеркальные карты).

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

Примечание о mesh: Когда 3D-дизайнеры в своих программах моделируют какой-нибудь объект, то, обычно, его пытаются сделать не цельным, а составным. Каждая такая модель имеет несколько подмоделей/фигур, из которых она строится. При этом каждая из этих отдельных фигур называется mesh (в переводе с англ. — «сетка»). Давайте представим себе человекоподобного персонажа: дизайнеры обычно моделируют голову, конечности, одежду и оружие как отдельные компоненты, и совокупный результат всех этих mesh-ей представляет собой окончательную модель. Один mesh — это минимальный набор для того, чтобы отобразить объект в OpenGL (данные вершин, индексы и свойства материала). Модель (как правило) состоит из нескольких mesh-ей.

В следующих уроках мы создадим наши собственные классы Model и Mesh, которые загружают и хранят импортированные модели, используя структуру, описанную выше. Затем, если нам нужно будет отобразить модель, мы не будем визуализировать её как единое целое, а будем визуализировать все отдельные mesh-и, из которых состоит модель. Однако, прежде чем мы сможем начать импортировать различные модели, нам сначала нужно подключить Assimp в наш проект.

Собираем Assimp

Вы можете скачать Assimp с официального сайта, выбрав соответствующую версию. При написании данной статьи использовался Assimp версии 5.0.1. Рекомендуется компилировать библиотеки самостоятельно, так как их предварительно скомпилированные версии не всегда работают на всех системах. Если вы забыли, как самостоятельно скомпилировать библиотеку с помощью CMake, то перечитайте Урок №2. Подготовка к первому проекту OpenGL: настройка GLFW, CMake и GLAD.

Сборка Assimp под Windows

Исходные данные: Windows 10 версии 1909 + MS Visual Studio 2019 версии 16.6.0.

Распакуйте архив assimp-5.0.1.zip в какую-нибудь папку. У меня это — C:\OpenGL:

Зайдите в распакованную папку C:\OpenGL\assimp-5.0.1\ и создайте новую папку, например, build:

Запустите Cmake-GUI. В окне программы укажите путь до исходников Assimp и папку, в которой будет сохранён результат работы Cmake. После этого нажмите кнопку "Configure":

В появившемся окне нужно выбрать платформу, под которую Cmake будет собирать проект. После этого нажмите кнопку "Finish":

В результате мы получим нижеследующее окно с красным фоном. Нажмите кнопку "Configure" ещё раз:

После этого красный фон исчезнет. И мы нажимаем кнопку "Generate", чтобы сгенерировать файлы проекта:

В результате данных действий Cmake должен вывести вам следующие строчки:

А в папке C:\OpenGL\assimp-5.0.1\build\ должны появиться новые файлы, среди которых будет файл решения Assimp.sln:

Открываем его, запустится Visual Studio. Далее щёлкаем ПКМ в обозревателе решений по строке ALL_BUILD и в появившемся меню выбираем пункт "Собрать". Начнется процесс компиляции проекта:

Забегая вперед, скажу, что на моей системе с процессором AMD FX8320 3,5GHz, процесс сборки шел около 4-х минут при 100% загрузке всех ядер. Результатом должно быть следующее:

Теперь в папке C:\OpenGL\assimp-5.0.1\build\code\Debug\ вы должны увидеть следующие файлы:

Копируем файл C:\OpenGL\assimp-5.0.1\build\code\Debug\assimp-vc142-mtd.lib в папку C:\OpenGL\Lib к остальным нашим файлам OpenGL-библиотек:

Копируем папки C:\OpenGL\assimp-5.0.1\assimp-5.0.1\include\assimp и C:\OpenGL\assimp-5.0.1\build\include\assimp в C:\OpenGL\Include. На вопрос о слиянии двух папок отвечаем "Да":

И также в Visual Studio подключаем к проекту нашу библиотеку. Для этого открываем рабочий проект, выбираем из верхнего меню "Проект -> Свойства" и в появившемся окне задаём нижеследующие параметры:

Добавим ещё каталоги:

Готово! Мы только что подключили библиотеку Assimp к нашему проекту. В следующих уроках мы будем работать уже с импортированными моделями. При этом, запуская исполняемый файл проекта, может появиться нижеследующее сообщение об ошибке:

Для решения данной проблемы скопируйте файл C:\OpenGL\assimp-5.0.1\build\code\Debug\assimp-vc142-mtd.dll в Debug-папку с исполняемым файлом вашего проекта. В моем случае это папка находится здесь — C:\Users\Имя_Пользователя\source\repos\Advanced OpenGL\x64\Debug\:

И окно с ошибкой не будет больше вам докучать.

Сборка Assimp под Linux

Исходные данные: Debian + CodeBlocks.

К сожалению, под данную платформу мне не удалось заставить стабильно работать собранную из исходников библиотеку Assimp. С ней постоянно возникали какие-то проблемы. При этом, проект урока с подключенной библиотекой успешно компилировался, запускалось окно программы, подгружалась модель. Но при попытке осмотреться мышкой внутри сцены, изображение модели внутри окна полностью пропадает. Поэтому пока пользователям Linux приходится рассчитывать только на свои собственные силы. Увы…

Проблемы при построении проекта с Assimp


При построении проекта Assimp могу появляться некоторые проблемы.

Проблема №1: CMake постоянно выдает ошибки при получении списка конфигурации о пропавших библиотеках DirectX, сообщение об ошибке следующее:

Решение заключается в том, что вам нужно установить DirectX SDK, если вы этого ещё не сделали.

Проблема №2: При установке DirectX SDK может появиться код ошибки s1023. В этом случае, перед установкой DirectX SDK, вам необходимо будет удалить пакеты Visual C++ Redistributable Packages.

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (6 оценок, среднее: 5,00 из 5)
Загрузка...

Комментариев: 6

  1. Аватар Фанат:

    Классный сайт! Много полезной и нужной информации, продолжайте в том же духе!

    1. Дмитрий Бушуев Дмитрий Бушуев:

      Спасибо большое 🙂

  2. Аватар noname:

    Привет. Сделайте пожалуйста инструкцию по сборке на CodeBlocks MinGW. Когда я пытался установить assimp5.0.1(новая версия) у меня CMake ругался на старый MinGW, пришлось ставить assimp4.0.1. Однако далее при попытке собрать это дело в codeblocks возникло несколько ошибок:
    1) unrecognized option `-mbig-obj'
    2) code\CMakeFiles\assimp.dir\build.make|1686|recipe for target 'code/CMakeFiles/assimp.dir/IFCReaderGen1.cpp.obj' failed
    3) CMakeFiles\Makefile2|325|recipe for target 'code/CMakeFiles/assimp.dir/all' failed
    4) assimp-4.0.1\build\Makefile|128|recipe for target 'all' failed

    Помогите пожалуйста (VS не перевариваю)

      1. Дмитрий Бушуев Дмитрий Бушуев:

        Я пробовал собирать Assimp с помощью CodeBlocks как в Linux, так и в Windows10.
        Самый большой прогресс был в варианте с Linux — библиотека Assimp компилировалась, соединялась с проектом, даже загружала модель в сцену. Но при этом был баг — стоило чуть двинуть мышкой (чтобы осмотреться вокруг сцены), как поворот камеры происходил с какой-то чудовищной скоростью. Хотя реакция на кнопки WASD была нормальная.

        Хуже всего обстояли дела в варианте CodeBlocks + Windows10. В данном случае библиотека Assimp вообще не захотела собраться, кидаясь на выходе различными ошибками компиляции (их было около 50 штук).

        Судя по вашему комментарию со ссылкой на тикет, разработчики Assimp признали (месяц назад) проблему и попытаются что-то сделать к выходу версии 5.1. Так что как-то так…

        1. Аватар noname:

          У меня получилось собрать assimp 4.0.1 для mingw-w64 (только пришлось убрать некоторые странные импортеры в которых возникали ошибки). В итоге assimp у меня распознаёт .obj, но, когда я пытаюсь загрузить сцену с обычным кубом из блендера (в .obj), объект не отображается (он точно не чёрный, текстуры загружаются без ошибок), его просто нет. (Я пробовал с разными модельками из интернета). Пробовал выводить отладочную информацию (количество мешей, нодов) — вроде как всё правильно. Может быть assimp криво стоит, такое может быть?

Добавить комментарий

Ваш E-mail не будет опубликован. Обязательные поля помечены *