Читаем Графика DirectX в Delphi полностью

Vertices.X := -0.5;

Vertices.Y := -0.5;

Vertices.Z := -0.5;

Vertices.nX := -1.0;

Inc(Vertices);

При инициализации графической системы вызывается процедура, задающая свойства материала и включающая источник света:

procedure TfrmD3D.SetupLights;

var

Material : TD3DMaterial8;

Light : TD3DLight8;

begin

// Инициализация материала, желтый цвет

Material := InitMaterial(1, 1, 0, 0) ;

// Устанавливаем материал в объекте устройства

FD3DDevice.SetMaterial(Material);

// Инициализация направленного источника, белый свет

Light := InitDirectionalLight(DSDVector(0, 0, 1), 1, 1, 1, 0) ;

// Устанавливаем источник света

FDSDDevice.SetLight(0, Light);

// Включаем источник света

FD3DDevice.LightEnable(0, True);

end;

Материал и источник света являются записями (не СОМ-объекты) и имеют тип TD3DMateriais и TD3DLight8 соответственно. Пользовательская функция InitMaterial заполняет поля структуры материала и получает в качестве аргументов значения ARGB. Отличает эти параметры от привычного их использования, помимо порядка, в котором они перечисляются, то, что это вещественные числа, единица соответствует максимальному значению аргумента.

В примере материал задается желтым, для того, чтобы установить его. При этом используется метод SetMaterial объекта устройства.

Функция InitDirectionalLight заполняет поля структуры, описывающей направленный источник света. Первым аргументом передается вектор, задающий направление лучей света. Напоминаю, что мы наблюдаем сцену с отрицательной стороны оси Z. Чтобы лучи света были параллельны нашему взору, вектор направления задается (0, 0, 1). Следующие три аргумента описывают цветовой фильтр, накладываемый на источник света, обычно источник задается белым. Эти числа также вещественны. Значение последнего аргумента для направленного источника безразлично.

Метод setLight объекта устройства устанавливает источник света на сцене. Первый аргумент, целое число, основанное на нуле, является индексом, идентификатором источника света. Метод только задает источник света, включается же он с помощью отдельного метода, LightEnabie, первый аргумент которого - индекс нужного источника, второй аргумент - булево выражение.

Как я уже говорил, отключается воспроизведение задних сторон треугольников, т. е. тех, чьи вершины перечисляются против часовой стрелки:

SetRenderState(D3DRS__CULLMODE, D3DCULL_CCW);

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

Есть и еще один важный аспект, который нам необходимо учитывать: DirectSD не может окрашивать примитивы с двух сторон. Замените последний аргумент метода Drawprimitive на 2 и установите значение для режима D3DRs_CULLMODE в D3DCULL_NONE. Теперь будет выводиться только одна сторона куба, отсечение задней стороны примитивов не производится. Обратите внимание, что когда квадрат поворачивается к зрителю задней стороной, он выводится черным, т. е. совершенно не окрашиваемым.

Кубик в нашем примере вращается вокруг двух осей одновременно:

SetRotateXMatrix(matRotateX, Angle);

SetRotateYMatrix(matRotateY, Angle);

FD3DDevice.SetTransform(D3DTS_WORLD, MatrixMul(matRotateX, matRotateY));

FD3DDevice.DrawPrimitive(D3DPT__TRIANGLELIST, 0, 12);

На рисунке куб получился крупнее, чем при работе приложения. Для того, чтобы увеличить изображение, можно просто "приблизить" глаз наблюдателя:

SetViewMatrixfmatView, D3DVector(0, 0, -2),

D3DVector(0, 0, 0), D3DVector(0, I, 0));

Есть и другой способ: действительно увеличить объект. Для этого в матрицу трансформаций надо добавить матрицу масштабирования, по главной диагонали которой стоят числа, отличные от единицы и равные масштабным множителям по трем осям отдельно. Попробуйте сейчас увеличить кубик в два раза:

procedure TfrmD3D.DrawScene;

var

matView, matProj : TD3DMatrix;

matRotateX, matRotateY : TD3DMatrix;

niatScale : TD3DMatrix; // Добавилась матрица масштабирования

begin

SetRotateXMatrix(matRotateX, Angle);

SetRotateYMatrix(matRotateY, Angle);

SetScaleMatrix(matScale, 2.0, 2.0, 2.0); // Увеличиваем в 2 раза

// Добавляем матрицу масштабирования

FD3DDevice.SetTransform(D3DTS_WORLD, MatrixMul(matScale,

MatrixMul(matRotateX, matRotateY)));

Обязательно это сделайте, чтобы увидеть, что куб действительно увеличился. Однако освещение его тоже изменилось. Связано это с тем, что векторы нормалей к вершинам вслед за масштабированием стали увеличенными, и требуется их нормализация. В таких случаях необходимо включить режим автоматической нормализации этих векторов:

SetRenderState(D3DRS NORMALIZENORMALS, DWORD (True));

Буфер глубины

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных