Коэффициенты задаются вещественными, обычно их значения нулевые или единичные. Самой распространенной схемой является линейный закон убывания, но вы можете строить и собственный, сложный закон освещенности, а не использовать определенную схему (если задать единичными все три коэффициента, интенсивность падает по полиномиальному закону).
Давайте закрепим пройденное, познакомившись с проектом каталога Ex01, в котором на экране рисуется тор. Во внутренней области тора перемещается точечный источник света, в точке его текущего положения рисуется сфера (рис. 10.1).
При инициализации такого источника нам необходимо самим заполнить все поля структуры TD3DLight8.
procedure TfrmD3D.SetupLights;
var
Material : TD3DMaterial8;
begin
Material := InitMaterial(1, 1, 0, 0); // Материал желтого цвета
FDSDDevice.SetMaterial(Material);
ZeroMemory(@Light, SizeOf(Light));
with Light do begin
_Type := D3DLIGHT_POINT; // Тип источника - точечный
Diffuse.R := 1.0; // Цвет источника
Diffuse.G := 1.0;
Diffuse.В := 1.0;
Specular := Diffuse; // Дополнительные параметры
Ambient := Diffuse;
Position := DSDVector(0.0, 0.0, 0.0); // Позиция в пространстве
AttenuationO := 1.0; // Коэффициенты закона ослабления
Attenuationl := 1.0;
Attenuation2 := 1.0;
Range := 2.5; // Расстояние, задающее область освещенности
end;
FD3DDevice.SetLight(0, Light);
FDSDDevice.LightEnable(0, True);
end;
Первое поле записи содержит константу, задающую тип источника. Структура Diffuse определяет цветовой фильтр, накладываемый на источник. Позиция источника света будет устанавливаться в текущей системе координат, ее значение остается действующим до следующего вызова метода SetLight (не обязательно заново инициализировать все поля структуры). Чтобы сфера освещалась так, как будто источник света находится внутри нее, необходимо переместить источник света в ее систему координат:
procedure TfrmD3D.DrawScene;
var
matTranslate, matScale : TDSDMatrix;
begin
// Вычисляем текущее положение источника
Light.Position := DSDVector(0.0, cos (Angle) * 2, 0.0);
with FDSDDevice do begin
// Возвращаем мировую систему координат
SetTransform(D3DTS_WORLD, IdentityMatrix);
// Устанавливаем источник света в новом положении
SetLight(0, Light);
DrawPrimitive(D3DPT_TRIANGLELIST, 0, 864); // Вывод тора
end;
// Источник света будет внутри сферы
Light.Position := D3DVector(0.О, 0.0, 0.0);
// Матрица трансформаций для сферы
SetTranslateMatrix(matTranslate, 0.0, cos (Angle) * 2, 0.0);
SetScaleMatrix(matScale, 0.1, 0.1, 0.1);
with FDBDDevice do begin
SetTransform(D3DTS_WORLD, MatrixMul(matScale, matTranslate));
SetLight(0, Light);
DrawPrimitive(D3DPT_TRIANGLELIST, 864 * 3, 1200);
end;
end;
Позже мы подробнее поговорим о полях структуры, связанной с источником света, а сейчас попробуем построить модель комнаты, чтобы убедиться, что использование точечного источника света значительно повышает реализм изображений. В проекте каталога Ех02 рисуется комната, в ее центре находится конус, вокруг которого вращается сфера (рис. 10.2).
Матрицы трансформаций полностью заполняются один раз, в начале работы приложения:
procedure TfrmD3D.FormCreate(Sender: TObject);
var
hRet : HRESULT;
matView, matProj : TD3DMatrix;
matRotate, matTranslate, matScale : TD3DMatrix;
begin
hRet := InitDSD;
if Failed (hRet) then ErrorOut ('InitDBD', hRet);
hRet := InitVB;
if Failed (hRet) then ErrorOut ( ' InitVertex' , hRet);
// Голубоватый материал конуса
MaterialConus := InitMaterial(0, 0.5, 1, 0) ;
// Белый материал стен комнаты
MaterialWhite := InitMaterial(1, 1, I, 0);
// Светло-коричневый материал сферы
MaterialSphere := InitMaterial(1, 0.5, 0, 0) ;
// Точка зрения задается один раз
SetViewMatrix(matview, D3DVector(0, 0, 2.577), D3DVector(0, 0, -5),
D3DVector(0, 1, 0));
FD3DDevice.SetTransform(D3DTS_VIEW, matView);
// Матрица проекций
SetProjectionMatrix (matProj, 1, 1, 1, 10);
FD3DDevice.SetTransform(D3DTS_PROJECTION, matProj);
// Инициализация источников света
SetupLights;
// Поворот конуса вокруг оси X
SetRotateXMatrix(matRotate, -Pi / 2);
// Переносим конус, его вершина в центре сцены
SetTranslateMatrixfmatTranslate, 0.0, -1.0, 0.0);
// Масштабируем конус
SetScaleMatrixfmatScale, 0.25, 1.0, 0.2);
// Матрица трансформаций конуса вычисляется один раз
matCone := MatrixMul(matScale, MatrixMul(matTranslate, matRotate));
// Инициализация матрицы трансформаций сферы
matSphere := IdentityMatrix;
// Переносим сферу по оси Y
matSphere._42 := -0.5;
end;
Я ввел в сцену четыре источника света. Три точечных источника предназначены для освещения стен комнаты, конус и сфера освещаются направленным источником света:
procedure TfrmDSD.SetupLights,
var
LightO : TD3DLight8;
Lightl : TD3DLight8;
Light2 : TD3DLight8;
Light3 : TD3DLight8;
begin
ZeroMemory(@LightO, SizeOf(LightO));
with LightO do begin
Type := D3DLIGHT POINT;
Diffuse.r := 0.4; // Поскольку присутствует три источника,
Читать дальше
Конец ознакомительного отрывка
Купить книгу