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

Урок 4. Освещение сцены

В этом уроке у нас чёрный прямоугольник из предыдущего урока окрасится в бежевый цвет. Мы начнём настраивать сцену: добавим освещение и фон.

  1. Сцену мы будем делать в отдельном модуле. Создайте в каталоге src файл scena.d, и, начните его наполнять:

module scena;
  1. Нам требуется проимпортировать несколько модулей из библиотеки:

import ddd, ddd.mesto, ddd.lamp, ddd.vector, ddd.quaternion;
  1. Создадим в этом модуле функцию сцена:

void сцена() {
}

И теперь будем её заполнять.

    1. Давайте зададим цвет фона окна:

менеджер.визуализатор.задать_цвет_фона([0.9, 0.85, 0.8, 1]); // Бежевый цвет

Объект менеджер присутствует в модуле ddd, и он отвечает за многое в библиотеке DDD: через него можно получить ресурсы, управлять камерой, получить доступ к начальному (или, иначе, корневому) Месту или, как мы это сделали сейчас, получить доступ к объекту Визуализатор. В большинстве случаев прямой доступ к визуализатору в программе не требуется, в этом смысле установка цвета фона является, скорее, исключением. Цвет задаётся в виде массива в формате RGBA.

Позднее (в уроке 13) мы установим фоновую текстуру окружения, но пока будем довольствоваться простым равномерным фоновым цветом.

    1. Для создания светильника нам нужно создать объект Лампа, настроить её параметры, и «встроить её в сцену», т. е. прикрепить её к объекту Место, находящемуся в иерархии сцены. Всего OpenGL позволяет создать до 8-ми ламп с номерами 0-7. Этот номер надо передавать вторым параметром при создании светильника, первым передаём его имя. Сейчас мы создаём нулевой светильник:

auto лампа0 = new Лампа("свет0", 0);

Мы задаём для этого светильника белое диффузное освещение.

лампа0.задать_диффузный_свет([1,1,1,1]);   // Белый цвет

Далее мы создадим для этого светильника отдельное Место, которое будет ребёнком начального Места (т. е. встроим его в иерархию сцены). Второй параметр, в данном случае, Вектор3(-2,-2,6)) определяет местоположение нашего светильника, а третий – его направление. В DDD светильники не имеют направления, и можно задавать любое, в данном случае используется направление без поворота.

auto место_лампы0 = менеджер.начальное_место.создать_ребёнка("Место лампы0", 
                                                       (Вектор3(-2,-2,6)),
                                                       Кватернион.НОЛЬ);

В последней строке мы мы присоединим наш светильник к Месту:

место_лампы0.присоединить_объект(лампа0);
    1. Создадим ещё один (теперь уже фиолетовый) светильник в другом месте:

auto лампа1 = new Лампа("свет1", 1); 
лампа1.задать_диффузный_свет([1,0.2,1,1]);   // Фиолетовый цвет
auto место_лампы1 = менеджер.начальное_место.создать_ребёнка("Место лампы1", 
                                                       (Вектор3(2,2,6)),
                                                       Кватернион.НОЛЬ);
место_лампы1.присоединить_объект(лампа1);

Действия светильников мы пока что, к сожалению, не увидим, т. к. для этого нужны 3D-объекты, которые они освещают,

  1. Полный текст модуля scena.d на данный момент:

scena.d
module scena;

import ddd, ddd.mesto, ddd.lamp, ddd.vector, ddd.quaternion;

void сцена() {
    менеджер.визуализатор.задать_цвет_фона([0.8, 1, 1, 1]); // Бежевый цвет
    
    auto лампа0 = new Лампа("свет0", 0);
    лампа0.задать_диффузный_свет([1,1,1,1]);   // Белый цвет
    auto место_лампы0 = менеджер.начальное_место.создать_ребёнка("Место лампы0", 
                                                       (Вектор3(-2,-2,6)),
                                                       Кватернион.НОЛЬ);
    место_лампы0.присоединить_объект(лампа0);
    
    auto лампа1 = new Лампа("свет1", 0);
    лампа0.задать_диффузный_свет([1,0.2,1,1]);   // Фиолетовый цвет
    auto место_лампы1 = менеджер.начальное_место.создать_ребёнка("Место лампы1", 
                                                       (Вектор3(2,2,6)),
                                                       Кватернион.НОЛЬ);
    место_лампы1.присоединить_объект(лампа1);
}
  1. Нам требуется вызвать эту функцию из функции main нашего проекта. Давайте откроем модуль urok.d, и добавим туда пару строк.

    1. После строки с импортом пакета ddd добавьте 4-ю строку с импортом нашего нового модуля:

import scena;
    1. В функции main после строки инициализации добавьте вызов нашей функции сцена (у меня это получилась 9-я строка):

сцена();
  1. Компиляция и запуск нашего проекта должны выдать вот такую картинку: