Чтение онлайн

ЖАНРЫ

Графика DirectX в Delphi

Краснов Михаил

Шрифт:

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

Итак, мы бросили беглый взгляд на сухой теоретический материал, из которого вынесли тяжелое подозрение, что впереди нас ожидает бурелом кодирования математических формул. Отчасти это

правда. Direct3D оставил программисту тяготы перемножения матриц, ожидая от него три результирующие матрицы трансформаций. Однако мы воспользуемся модулем Dxcutiis, который содержит набор полезных функций. Автор переноса на Delphi кода этих функций указан в заголовке модуля.

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

Чтобы при вращении примитивов мы могли видеть обе их стороны, режим отсечения отключается, а для использования окрашенных примитивов запрещена работа с источником света:

with FDBDDevice do begin

SetRenderState(D3DRS_CULLMODE, D3DCULL_HONE);

SetRenderState(D3DRS_LIGHTING, DWORD (False)); end;

Буфер вершин запирается один раз. Семь вершин содержат координаты треугольника и квадрата. Если бы они выводились не трансформируемыми, то накладывались бы друг на друга:

Vertices.X := 0.0; // Первая вершина треугольника

Vertices.Y := 1.0;

Vertices.Z := 0.0;

Vertices.Color := $00FF0000;

Inc(Vertices);

Vertices.X := 1.0; // Вторая вершина треугольника

Vertices.Y := -1.0;

Vertices.Z := 0.0;

Vertices.Color := $0000FF00;

Inc(Vertices);

Vertices.X := -1.0; // Третья вершина треугольника

Vertices.Y := -1.0;

Vertices.Z := 0.0;

Vertices.Color := $000000FF;

Inc(Vertices);

Vertices.X := -1.0; // Первая вершина квадрата

Vertices.Y := -1.0;

Vertices.Z := 0.0;

Vertices.Color := $00FFFF00;

Inc(Vertices);

Vertices.X := -1.0; // Вторая вершина квадрата

Vertices.Y := 1.0;

Vertices.Z := 0.0;

Vertices.Color := $00FFFF00;

Inc(Vertices);

Vertices.X := 1.0; // Третья вершина квадрата

Vertices.Y := -1.0;

Vertices.Z := 0.0;

Vertices.Color := $00FFFF00;

Inc(Vertices);

Vertices.X := 1.0; // Четвертая вершина квадрата

Vertices.Y := 1.0;

Vertices.Z := 0.0;

Vertices.Color := $00FFFF00;

При каждой перерисовке кадра вызывается процедура:

procedure TfrmD3D.DrawScene;

var

matView, matProj : TDSDMatrix; // Матрицы 4x4

matRotate, matTranslate : TDSDMatrix;

begin

// Получить матрицу поворота вокруг оси X

SetRotateXMatrix(matRotate, Angle); //

Матрица сдвига по оси X, на единицу влево

SetTranslateMatrix(matTranslate, -1.0, 0.0, 0.0); // Устанавливаем мировую матрицу трансформаций FDSDDevice.SetTransform(D3DTS_WORLD,

MatrixMul(matRotate, matTranslate)); // Выводится треугольник

FD3DDevice.DrawPrimiti.ve(D3DPTJTRIANGLELIST, 0, 1); // Квадрат вращается по оси Y в 2 раза быстрее треугольника SetRotateYMatrix(matRotate, 2 * Angle); // Квадрат сдвигается на единицу вправо

SetTranslateMatrix(matTranslate, 1.0, 0.0, 0.0); // Матрица трансформаций для квадрата

FD3DDevice.SetTransform(D3DTS_WORLD,

MatrixMul(matTranslate, matRotate)); // Вывод квадрата

FD3DDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 3, 2); // Задаем видовую матрицу

SetViewMatrix(matView, D3DVector(0, 0, -5),

D3DVector(0, 0, 0), D3DVector(0, 1, 0)); // Устанавливаем видовую матрицу

FD3DDevice.SetTransform(D3DTS_VIEW, matView); // Задаем матрицу проекций

SetProjectionMatrix(matProj, I, 1, 1, 10); // Устанавливаем матрицу проекций

FD3DDevice.SetTransform(D3DTS_PROJECTION, matProj);

end;

Тип TD3DMatrix, массив 4x4 вещественных чисел, определен в модуле DirectxGraphics, а все функции операций с матрицами - в модуле DXGUtils. Эти функции возвращают величину типа HRESULT, значение которой мы, для простоты, анализировать не будем.

Функция D3DVector этого же модуля возвращает сформированный по трем аргументам вектор, тройку вещественных чисел, величину типа TD3DVector.

Функция SetRotateXMatrix первым аргументом получает переменную, в которую помещается результат, матрицу поворота вокруг оси X. Второй аргумент - угол, в радианах, на который осуществляется поворот. Функция SetTranslateMatrix первым аргументом получает переменную, в которую помещается заполненная матрица сдвига. Одновременно можно сдвинуть по нескольким осям.

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

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

Квадрат в этом примере вначале сдвигается вправо, затем поворачивается вокруг оси Y (собственной оси, а не мировой). Измените порядок перемножения матриц, чтобы убедиться, что результат будет отличаться от предыдущего.

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

Поделиться с друзьями: