Для представления пола используется сетка кубической формы. Она загружается с помощью функции Load() интерфейса Direct3DRMMeshBuilder, а затем делается плоской с помощью функции Scale(). Для сетки разрешается перспективная коррекция и устанавливается плоский метод визуализации.
На следующем этапе осуществляется загрузка текстуры, которая будет наложена на сетку пола:
Значение, идентифицирующее текстуру, получается с помощью функции FindResource(), входящей в Win32 API. Затем текстура загружается с помощью функции LoadTextureFromResource() и связывается с созданным ранее конструктором сеток с помощью функции SetTexture(). После выполнения этих действий указатель texture освобождается.
На третьем этапе происходит создание и применение наложения текстуры для сетки пола:
D3DRMBOX box; floorbuilder->GetBox(&box); D3DVALUE w = box.max.x - box.min.x; D3DVALUE h = box.max.z - box.min.z;
Функция GetBox() интерфейса Direct3DRMMeshBuilder используется для получения размеров сетки пола. Размеры сетки (и ряд других значений) используются при создании плоского наложения текстуры. Наложение текстуры используется чтобы применить привязанную ранее текстуру к сетке пола с помощью функции Apply() интерфейса Direct3DRMWrap. Затем указатель wrap освобождается. Подробное описание функции CreateWrap() приведено в разделе главы 5, посвященном описанию приложения Wraps.
Фрейм создается функцией CreateFrame() интерфейса Direct3DRM. Функция AddVisual() применяется для присоединения конструктора сеток к новому фрейму. После этого указатель floorframe освобожлается поскольку он больше нам не потребуется.
Файл сетки вилки является частью ресурсов программы (также как и сетка пола и текстура пола). Сетка загружается функцией Load() интерфейса Direct3DRMMeshBuilder. Для сетки задается плоский метод визуализации. Обратите внимание, что мы не включаем перспективную коррекцию, поскольку на сетку вилки текстура не накладывается.
Теперь пришло время создать фрейм для сетки вилки и настроить его параметры:
Новому фрейму присваиваются атрибуты вращения, но это является временной мерой, поскольку вскоре функция обратного вызова AdjustSpin() перезапишет эти параметры. Фрейм вилки размещается на шесть единиц выше начала координат (сетка пола размещена в начале координат).
Сетка вилки присоединяется к своему фрейму с помощью функции AddVisual(). Затем с помощью функции AddMoveCallback() интерфейса Direct3DRMFrame устанавливается функция обратного вызова AdjustSpin().
На седьмом этапе создается источник рассеянного света:
Ранее в этой главе, когда мы изучали способы работы с источником рассеянного света, мы присоединяли источник света непосредственно к корневому фрейму сцены. Здесь мы тоже не будем тратить силы на создание фреймов и воспользуемся корневым фреймом сцены (scene).
Восьмым шагом является создание точечного источника света. Это тот источник света, который будет создавать тень от вилки. Код его создания выглядит так:
Тень создается с помощью функции CreateShadow() интерфейса Direct3DRM, которая получает девять аргументов. Первый аргумент — это указатель на объект, который будет отбрасывать тень. Второй аргумент — указатель на источник света, который будет использоваться при вычислении формы тени. Следующие шесть аргументов определяют плоскость, на которую будет отбрасываться тень (первые три аргумента задают точку плоскости, а следующие три определяют перпендикулярный плоскости вектор). Последний аргумент, передаваемый функции CreateShadow() интерфейса Direct3DRM, — адрес инициализируемого функцией указателя. По непонятным причинам в качестве последнего аргумента функция CreateShadow() ожидает указатель на интерфейс Direct3DRMVisual, а не указатель на интерфейс Direct3DRMShadow. Поэтому для корректной компиляции программы необходимо указать явное преобразование типа указателя.
На заключительном этапе работы функция CreateScene() создает порт просмотра:
Фрейм camera инициализируется функцией CreateFrame() интерфейса Direct3DRM, перемещается вверх и вперед от начала координат, и направляется на начало координат.Функция CreateViewport() применяется для инициализации указателя viewport.
Завершая свою работу, функция CreateScene() возвращает TRUE, чтобы сообщить об успешном завершении создания сцены.