Освещенность и материалы. Построения объектов
Функция построения тора:
D3DXCreateTorus( ссылка на устройство, внутренний радиус тора, внешний радиус тора, количество разбиений в поперечном сечении, количество разбиений по кругу, результат, указатель на смежные треугольники);
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-файлах. Х-файл – файл, содержащий в себе данные о трехмерном объекте (координаты вершин, материалы, нормали, текстуры и анимацию). Вначале необходимо объявить нужные переменные.
Для загрузки трехмерного объекта (модели) из Х-файла предназначена функция
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, где в качестве параметра передается номер выводимой группы (подмножества) модели. Если модель не разбита на группы, то параметр метода равен нулю.
Для того чтобы трехмерная модель выглядела более реалистично, можно добавить в сцену источники света и определить материалы.