Опубликован: 08.07.2007 | Доступ: свободный | Студентов: 1431 / 183 | Оценка: 4.43 / 4.02 | Длительность: 13:47:00
Специальности: Программист
Лекция 7:

Освещенность и материалы. Построения объектов

Функция построения тора:

D3DXCreateTorus(
ссылка на устройство,
внутренний радиус тора,
внешний радиус тора,
количество разбиений в поперечном сечении,
количество разбиений по кругу,
результат,
указатель на смежные треугольники);
Разбиений в сечение = 6

Разбиений по кругу = 32

Разбиений в сечение = 32

Разбиений по кругу = 6



C++
LPD3DXMESH torus;
D3DXCreateTorus(device, 0.2f, 0.8f, 32, 6, &torus, NULL);
torus->DrawSubset(0);
Pascal
var torus: ID3DXMesh;
D3DXCreateTorus(device, 0.2, 0.8, 32, 6, torus, nil);

torus.DrawSubset(0);

Функция построения чайника:

D3DXCreateTeapot(
ссылка на устройство,
результат,
указатель на смежные треугольники);

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


C++
LPD3DXMESH teapot;
D3DXCreateTeapot(device, &teapot, NULL);
teapot->DrawSubset(0);
Pascal
var teapot: ID3DXMesh;
D3DXCreateTeapot(device, teapot, nil);

teapot.DrawSubset(0);

Ниже приведены примеры освещения трехмерного объекта точечным источником света с различными характеристиками.

light.Ambient = D3DXCOLOR(0.3f, 0,0,0);

light.Diffuse = D3DXCOLOR(0.5f, 0.0, 0,0);
light.Ambient = D3DXCOLOR(0.2f, 0,0,0);

light.Diffuse = D3DXCOLOR(0.5, 0.0, 0,0);
light.Ambient = D3DXCOLOR(0.2, 0,0,0);
light.Specular = D3DXCOLOR(0.3,0,0.0,0);

Следует заметить, что зеркальное освещение требует больших вычислений, чем другие типы освещения, поэтому библиотека Direct3DM предоставляет возможность отключать его (по умолчанию оно выключено). Для включения зеркального освещения необходимо установить константу состояния D3DRS_SPECULARENABLE в значение "истина".

C++ device->SetRenderState( D3DRS_SPECULARENABLE, TRUE );
Pascal device.SetRenderState(D3DRS_SPECULARENABLE, 1);

Как мы уже говорили, библиотека Direct3D позволяет одновременно использовать (обсчитывать) в сцене до восьми источников света. Программно использование нескольких источников света в сцене накладывает на программиста дополнительные "обязанности" по созданию и заполнению полей структуры для каждого источника. Ниже приведен пример использования трех разноцветных точечных источников света в сцене, которые расположены на координатных осях системы координат.

C++
D3DMATERIAL9 material;
D3DLIGHT9 light0, light1, light2;

ZeroMemory( &material, sizeof(D3DMATERIAL9) );
material.Diffuse=D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.0f);

ZeroMemory( &light0, sizeof(D3DLIGHT9) );
light0.Type = D3DLIGHT_POINT;
light0.Diffuse = D3DXCOLOR(0.5f, 0.0f, 0.0f, 0.0f);
light0.Position = D3DXVECTOR3(4.0f, 0.0f, 0.0f);
…
ZeroMemory( &light1, sizeof(D3DLIGHT9) );
light1.Type = D3DLIGHT_POINT;
light1.Diffuse = D3DXCOLOR(0.0f, 0.5f, 0.0f, 0.0f);
light1.Position = D3DXVECTOR3(0.0f, 0.0f, -4.0f);
…
ZeroMemory( &light2, sizeof(D3DLIGHT9) );
light2.Type = D3DLIGHT_POINT;
light2.Diffuse = D3DXCOLOR(0.0f, 0.0f, 0.5f, 0.0f);
light2.Position = D3DXVECTOR3(-4.0f, 0.0f, 0.0f);

device->SetRenderState( D3DRS_LIGHTING, TRUE );
...
// процедура рендеринга
device->SetLight( 0, &light0 );
device->LightEnable( 0, TRUE );
device->SetLight( 1, &light1 );
device->LightEnable( 1, TRUE );
device->SetLight( 2, &light2 );
device->LightEnable( 2, TRUE );
Pascal
var
  material: TD3DMaterial9;
  light0, light1, light2: TD3DLight9;

ZeroMemory(@material,SizeOf(TD3DMaterial9));
material.Diffuse:=D3DXColor(1,1,1,0);

light0._Type:=D3DLIGHT_POINT;
light0.Diffuse:=D3DXColor(0.5, 0.0, 0, 0);
light0.Position:=D3DXVector3(4,0,0);
…
light1._Type:=D3DLIGHT_POINT;
light1.Diffuse:=D3DXColor(0.0, 0.5, 0, 0);
light1.Position:=D3DXVector3(0,0,-4);
…
light2._Type:=D3DLIGHT_POINT;
light2.Diffuse:=D3DXColor(0.0, 0.0, 0.5, 0);
light2.Position:=D3DXVector3(-4,0,0);
…
device.SetRenderState(D3DRS_LIGHTING, 1);

// процедура рендеринга
device.SetLight(0,light0);
device.LightEnable(0,true);
device.SetLight(1,light1);
device.LightEnable(1,true);
device.SetLight(2,light2);
device.LightEnable(2,true);

Сложные (содержащие десятки тысяч вершин) объекты, как правило, создаются в профессиональных трехмерных редакторах (3D Studio, Maya, LightWave, и т.п.). Библиотека Direct3D содержит средства для загрузки и визуализации моделей, содержащихся в x-файлах. Х-файлфайл, содержащий в себе данные о трехмерном объекте (координаты вершин, материалы, нормали, текстуры и анимацию). Вначале необходимо объявить нужные переменные.

C++ LPD3DXMESH mesh;
Pascal var mesh: ID3DXMesh;

Для загрузки трехмерного объекта (модели) из Х-файла предназначена функция

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

В простейшем случае (если модель не содержит информации о материалах, текстурах, смежности граней) параметры с четвертого по седьмой включительно выставляют в NULL. Ниже приведен пример загрузки модели из Х-файла.

C++
D3DXLoadMeshFromX("ship.x", D3DXMESH_MANAGED, 
                  device, NULL, NULL, NULL, NULL, &mesh);
Pascal
D3DXLoadMeshFromX('ship.x', D3DXMESH_MANAGED, 
                  device, nil, nil, nil, nil, mesh);

Для визуализации трехмерной модели из Х-файла необходимо вызвать метод DrawSubset интерфейса ID3DXMesh, где в качестве параметра передается номер выводимой группы (подмножества) модели. Если модель не разбита на группы, то параметр метода равен нулю.

C++ mesh->DrawSubset(0);
Pascal mesh.DrawSubset(0);

Для того чтобы трехмерная модель выглядела более реалистично, можно добавить в сцену источники света и определить материалы.