DirectX Графика в проектах Delphi


Буфер глубины - часть 3


Цилиндр радиуса 0.1 и высотой 2 строится вокруг оси Y, а конус единичной высоты - вокруг оси Z. О том, как получены точки модели, мы поговорим чуть позже, сейчас же я должен сообщить, что вершины треугольников модели перечисляются против часовой стрелки.

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

FromX, FromY, FromZ : Single;
AtX, AtY, AtZ : Single;
WorldUpX, WorldUpY, WorldUpZ : Single;
fFOV, fAspect, fNearPlane, fFarPlane : Single;

Инициализируются эти переменные значениями, такими же, как в предыдущих примерах, лишь точка зрения отодвинута на единицу:

procedure TfrmDSD.FormCreate(Sender: TObject);
var
hRet : HRESULT;
begin
hRet := InitD3D;
if Failed (hRet) then ErrorOut (4nitD3D'f hRet);
hRet := InitVB;
if Failed (hRet) then ErrorOut ('InitVertex', hRet);
// Включаем источники света и инициализируем материалы
SetupLights;
MaterialRed := InitMaterial(1, 0, 0, 1);
MaterialBlue := InitMaterial(0, 0,1, 1);
MaterialGreen := InitMaterial(0, 1, 0, 1) ;
MaterialYellow := InitMaterial(1, 1, 0, 1);
FromX := 0.0; // Вектор "From"
FromY := 0.0;
FromZ := -6.0;
AtX := 0.0; // Вектор "At"
AtY := 0.0;
AtZ := 0.0;
WorldUpX := 0.0; // Вектор "WorldUp"
WorldUpY := 1.0;
WorldUpZ := 0.0;
fFOV := 1.0; // Угол обзора по оси Y
fAspect := 1.0; // Угол обзора по оси X
fNearPlane := 1.0; // Передняя плоскость отсечения
fFarPlane := 20; // Задняя плоскость отсечения
end;

Для повышения красочности на сцене присутствует два источника света:

procedure TfrmDSD.SetupLights;
var
LightO : TD3DLight8;
Lightl : TD3DLight8;
begin
LightO := InitDirectionalLight(D3DVector(-1, -1, -1), 1, 1, 1, 0);
FDSDDevice.SetLight (0, LightO);
Lightl := InitDirectionalLight(D3DVector(0, 0, 1), 1, 1, 1, 0);
FDSDDevice.SetLight (1, Lightl);
FD3DDevice.LightEnable (0, True);
FD3DDevice.LightEnable (1, True);
end;

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

procedure TfrmDSD.DrawScene;
var
matView, matProj : TD3DMatrix;
matRotate, matTranslate : TDSDMatrix;
matRotateX, matRotateY : TD3DMatrix;
matScale : TD3DMatrix;
begin
// Цилиндр по оси X
SetRotateZMatrix(matRotate, Pi / 2);
SetTranslateMatrix(matTranslate, 1.0, 0.0, 0.0);
with FD3DDevice do begin
SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
SetTransform(D3DTS_WORLD, MatrixMul(matTranslate, matRotate));
SetMaterial(MaterialRed); // Красного цвета
DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 50 * 2 - 2);
end;
// Конус стрелки по оси Z
SetRotateYMatrix(matRotate, Pi / 2);
SetTranslateMatrix(matTranslate, 2.0, 0.0, 0.0);
SetScaleMatrix(matScale, 1.0, 0.5, 0.5);
with FDSDDevice do begin
SetTransform(D3DTS_WORLD, MatrixMul(matScale,
MatrixMul(matTranslate, matRotate)));
DrawPrimitive(D3DPT_TRIANGLEFAN, 100, 49); // Сам конус
DrawPrimitive(D3DPT_TRIANGLEFAN, 151, 50); // Донышко конуса
end;
// Цилиндр по оси Y
SetTranslateMatrix(matTranslate, 0.0, 1.0, 0.0);
with FDSDDevice do begin
SetTransform(D3DTS__WORLD, matTranslate);
SetMaterial(MaterialGreen); // Цвет - зеленый
DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 50 * 2 - 2);
end;
// Конус стрелки по оси Y SetRotateXMatrix(matRotate, -Pi / 2);
SetTranslateMatrix(matTranslate, 0.0, 2.0, 0.0);
SetScaleMatrix(matScale, 0.5, 1.0, 0.5);
with FD3DDevice do begin
SetTransform(D3DTS_WORLD, MatrixMul(matScale,
MatrixMul(matTranslate, matRotate)));
DrawPrimitive(D3DPT_TRIANGLEFAN, 100, 49);
DrawPrimitive(D3DPT_TRIANGLEFAN, 151, 50);
end;
// Цилиндр по оси Z
SetRotateXMatrix(matRotate, Pi / 2) ;
SetTranslateMatrix(matTranslate, 0.0, 0.0, 1.0);
with FD3DDevice do begin
SetTransform(D3DTS_WORLD, MatrixMul(matTranslate, matRotate));
SetMaterial(MaterialBlue); // Синего цвета
DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 50 * 2 - 2);
end;
// Конус стрелки по оси Z
SetTranslateMatrix(matTranslate, 0.0, 0.0, 2.0);
SetScaleMatrix(matScale, 0.5, 0.5, 1.0); with FD3DDevice do begin
SetTransform(D3DTS_WORLD, MatrixMul(matScale, matTranslate));
DrawPrimitive(D3DPT_TRIANGLEFAN, 100, 49);
DrawPrimitive(D3DPT_TRIANGLEFAN, 151, 50);
end;
// Чайник, вращающийся вокруг осей X и Y
SetRotateXMatrix(matRotateX, Angle);
SetRotateYMatrixfmatRotateY, Angle);
SetTranslateMatrix(matTranslate, 0.0, -1.5, 0.0);
SetScaleMatrix(matScale, 0.5, 0.5, 0.5); // Уменьшаем в два раза
with FD3DDevice do begin
SetTransform(D3DTS_WORLD, MatrixMul(matRotateX, MatrixMul(matRotateY, MatrixMul(matScale, matTranslate))));
SetMaterial(MaterialYellow);
// Вершины модели перечисляются против часовой стрелки
SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
DrawPrimitive(D3DPT_TRIANGLELIST, 100 + 51 * 2, 6322);
end;
// Матрица вида
SetViewMatrix(matView, DSDVector(FromX, FromY, FromZ),
D3DVector(AtX, AtY, AtZ), DSDVector(WorldUpX, WorldUpY, WorldUpZ));
FD3DDevice.SetTransform(D3DTS_VIEW, matView); // Матрица проекций
SetProjectionMatrix(matProj, fFOV, fAspect, fNearPlane, fFarPlane);
FD3DDevice.SetTransform(D3DTS_PROJECTION, matProj);
end;




Начало  Назад  Вперед