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

ЖАНРЫ

Графика DirectX в Delphi

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

Шрифт:

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

procedure TfrmDSD.MoveMan;

begin

// Поворот глобальной системы координат,

// вращение всей модели вокруг своей

оси

SetRotateZMatrix (matRot, Angle);

// Переменная, задающая вращение конечностей

AngleFoot := AngleFoot + StepFoot;

if (AngleFoot > Pi / 4) or (AngleFoot < -Pi / 4}

then StepFoot := -StepFoot; // Ноги вращаются в противофазе

SetRotateXMatrix (rotLeftFoot, AngleFoot);

SetRotateXMatrix (rotRightFoot, -AngleFoot); // Поворот левой ноги, в три этапа

matLeftFoot := MatrixMul(matRot,

MatrixMul(transFoot2, MatrixMul(rotLeftFoot, transFootl))); // Поворот правой ноги

matRightFoot := MatrixMul(matRot,

MatrixMul(transFoot2,

MatrixMul(rotRightFoot, transFootl))); // Поворот левой руки

matLeftHand := MatrixMul(matRot,

MatrixMul(transHand2,

MatrixMul(rotRightFoot, transHandl))); // Поворот правой руки

matRightHand := MatrixMul(matRot,

MatrixMul(transHand2, MatrixMul(rotLeftFoot, transHandl)));

end;

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

SetTranslateMatrix(transFootl, О, О, 0.25);

SetTranslateMatrix(transFoot2, О, О, -0.25);

SetTranslateMatrix(transHandl, 0.25, 0.0, -0.23);

SetTranslateMatrix(transHand2, -0.25, 0.0, 0.23);

Этот пример я подготовил для использования в дальнейшем в расчете на то, что человечком можно будет легко управлять, перемещая его в пространстве. Но если на сцене присутствует только одна модель, для оптимизации можно сократить количество операций с матрицами. В самом деле, в этом примере матрица matRot, связанная с глобальной системой координат, может вообще не использоваться: модель можно не вращать и оставить неподвижной, а перемещать точку зрения наблюдателя. Эффект вращения модели останется, а количество операций существенно уменьшится.

И теперь мы можем перейти к разбору заключительного примера - проекта каталога Ех21. Как я уже говорил, это заготовка трехмерной игры: игрок попадает внутрь комнаты, населенной движущимися человечками .

Окружение игрока построено из текстур, накладываемых на треугольники, описание окружающего мира загружается из текстового файла.DirectX.

type

// Формат вершин для треугольников окружения

TNormDiffTextVertex = packed record

X, Y, Z : Single;

nX, nY, nZ : Single;

DColor : DWORD;

U, V : Single;

end;

// Формат вершин для треугольников человечков

TNormVertex = packed record

X, Y, Z : Single;

nX, nY, nZ : Single;

end;

// Отдельный треугольник

описания окружения

TTriangle '= record

NumTexture : Integer; // Номер текстуры

DIFFUSE : DWORD; // Диффузная составляющая треугольника

end;

const

// FVF-флаг для треугольников окружения

D3DFVF_NORMDIFFTEXTVERTEX = D3DFVF_XYZ or D3DFVF_NORMAL or

D3DFVF_DIFFUSE or D3DFVFJTEX1; // FVF-флаг для треугольников человечков

D3DFVFJSIORMVERTEX = D3DFVF_XYZ or D3DFVFJTORMAL;

// Имя файла с описанием мира

WorldFile = 'Data/World.txt';

// Имя файла с треугольниками символов, для вывода FPS

NumbersFile = 'Data/Numbers.txt';

// Количество треугольников в описании окружения

NumTriangles = 58;

($1 legoman.pas) // Данные модели

var

frmD3D: TfrmD3D;

Frames : Integer =0; // Счетчик кадров

FpsOut : String = ''; // Значение FPS

// Вспомогательная матрица, для вывода символов FPS

LetTrans : TDSDMatrix;

// Используется как вспомогательный массив для хранения образа текстуры

TexPointer : Pointer;

// Характеристики образа текстуры

wrkTexWidth, wrkTexHeight :

Integer;

// Флаг, выводить ли FPS

flgFPS : BOOL = True;

// Угол зрения по вертикали

Lookupdown : Single = 0.0;

// Вспомогательный вектор для оптимизации

ZVector : TD3DVector;

// Угол зрения по горизонтали и положение игрока

RotY, XPos, ZPos : Single;

// Массив описания мира

World : Array [0..NumTriangles - 1] of TTriangle;

// Переменные для обработки устройств ввода

DInput : IDIRECTINPUT8 = nil;

DIMouse : IDIRECTINPUTDEVICE8 = nil;

DIKeyboard : IDirectlnputDeviceS;

KeyBuffer : TDIKeyboardState;

// Угол поворота красного человечка

Angle : Single = 0.0;

// Угол поворота конечностей человечков

AngleFoot : Single = 0.0;

StepFoot : Single = 0.1;

// Тестовая точка для определения столкновений с препятствиями

TestPointX, TestPointY : DWORD;

В файле описания окружения данных идут в следующем порядке:

строка комментария; номер текстуры; цвет треугольника; три строки описания вершин треугольника, которые включают координаты в пространстве; нормаль и текстовые координаты каждой вершины треугольника.

*

Вот что записано в текстовом файле для первого треугольника:

// Потолок

4

$00FF0000

– 3.0 1.0 3.0 0.0 -1.0 0.0 0.0 0.0

– 3.0 1.0 -3.0 0.0 -1.0 0.0 0.0 12.0

1.0 3.0 0.0 -1.0 0.0 12.0 0.0

Пол и потолок комнаты представляют собой квадраты с координатами точек углов по диагонали (-3; -3) и (3; 3). Координата Y для всех вершин пола нулевая, для вершин потолка - единичная. При считывании данных предусматриваем обработку исключений на случай отсутствия файла данных или присутствия ошибки при описании треугольников:

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