← к содержанию

Урок 5. Ресурсы и меши

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

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

Ресурсы – это удобный и предпочтительный способ загрузки внешних файлов в DDD. Поддерживаются ресурсы следующих видов:

Вступительная болтовня оказалась неожиданно длинной, пора уже что-то сделать.

  1. Для целей этой серии уроков были подготовлены несколько ресурсов различных типов, которые расположены здесь: http://striver00.ru/где-то. Загрузите этот архив и разархивируйте содержимое в каталог bin.

  2. Нам надо передать в DDD информацию о расположении каталогов с нашими ресурсами. В разархивированном каталоге ресурсы находятся пять подкаталогов: инфопанели, меши, скелеты, текстуры и шрифты. В идеале нам надо передать в функцию инициализация_ddd массив с путями ко всем этим каталогам. Но мы пока ограничимся одним из них – каталогом меши, т. к. во-первых, в этом уроке всё остальное нам не понадобится, а во-вторых, и это даже важнее, в следующем уроке нам снова придётся переделать это место программы. Пока мы в файле urok.d в функции main поправим первую строку. Сейчас в функцию инициализация_ddd в качестве аргумента передаётся пустой массив. Заменим эту строку на такую:

инициализация_ddd(["ресурсы/меши"]);
  1. В этом уроке мы отобразим меш с одним из 3D-объектов, встроенных в 3D-редактор Блендер в качестве стандартного примитива – головой обезьянки Сюзанны. Файл с этим мешем называется Сюзанна.me, ресурс будет называться просто Сюзанна. Откройте файл scena.d, добавьте в конец строки импорта ещё один модуль ddd.ddd_object (он позволяет использовать класс Объект), и перейдите к концу функции сцена:

    1. Запросим меш у ddd-менеджера:

auto меш1 = менеджер.получить_меш("Сюзанна");

    1. Создадим объект Места, в котором будет находиться наш 3D-объект:

auto место1 = менеджер.начальное_место.создать_ребёнка("Место объекта1",

Вектор3.НОЛЬ,

Кватернион(0.7459,0.6661,0,0));

Не пугайтесь заранее страшных чисел в параметрах кватерниона направления — это всего лишь поворот на 90 градусов. Как вариант, можно было вместо Кватернион(0.7459,0.6661,0,0) написать Кватернион(PI/2, Вектор3(1,0,0)), но тогда надо было бы импортировать модуль стандартной библиотеки std.math для получения константы PI. Если такой поворот вообще не делать, пришлось бы любоваться головой Сюзанны снизу.

    1. Следующие две строки требуется обернуть в условный оператор if, в котором мы убедимся, что меш из файла действительно загрузился, и переменная меш1 не содержит null. Таким образом, в случае какой-либо ошибки в файле Сюзанна.me наша программа просто не выведет обезьянку на экран, а если этого не сделать, «упадёт» с ошибкой (в Linux она называется «ошибка сегментирования», в Windows – «Access violation»).

if (!(меш1 is null)) {
}
    1. Теперь (уже внутри фигурных скобок, соданных в предыдущем пункте) создадим 3D-объект с нашим мешем:

auto объект1 = new Объект("объект1", меш1);
    1. И, наконец, присоединим его к ранее созданному объекту Место:

место1.присоединить_объект(объект1);

К объекту Место можно присоединять любое количество объектов, так что мы могли бы, например, не создавать новое Место в пункте 3.b, а присоединить объект нашей обезьянки к Месту одной из ламп, созданных в предыдущем уроке. Но тогда эта лампа не смогла бы осветить наш объект, т. к. находилась бы внутри него.

  1. Компиляция и запуск нашего проекта должны отобразить нечто подобное:


  2. Попробуйте загрузить вместо Сюзанны другие меши, присутствующие к каталоге ресурсы/меши.