Первые 13 строк такого файла необходимо удалить. Также удаляются последние строки кода, начиная со строки GLint GenSoobjectListо. В оставшемся файле убираются все символы f, предшествующие запятой и фигурной скобке. Далее все фигурные скобки заменяются на обычные.
Последнее, что необходимо сделать - изменить синтаксис описания массиюв. Например, такая строка
tatic GLint face_indicies[1200][9]
заменяется следующей:
ace_indicies : array [0..1199, 0..8] of integer
Тип GLfloat заменяется типом single, остальные типы соответствуют целому.
Толученный файл с директивой include подключается к головному модулю роекта (в секцию const), а код функции инициализации буфера становится рактически универсальным, в зависимости от модели меняется только чисо, задающее размер буфера. Впрочем, и это число можно заменить выражением, опирающемся на размер массива normals. Также, возможно, потре-уется исправить и масштабный множитель:
unction TfrmD3D.InitVBEagle : HRESULT;
var
Vertices : ~TCustomVertexEagle;
hRet : HRESULT;
i, j : Integer;
vi : Integer; // Индекс вершин треугольников
ni : Integer; // Индекс нормалей треугольников
begin
hRet := FDSDDevice.CreateVertexBuffer(10500 *
SizeOf(TCustomVertexEagle), 0, D3DFVF_CUSTOMVERTEXEagle, D3DPOOL_DEFAULT, FD3DVBEagle);
if Failed(hRet) then begin
Result := hRet;
Exit;
end;
hRet := FD3DVBEagle.Lock(0, 10500 * SizeOf(TCustomVertexEagle),
PByte(Vertices), 0) ;
if Failed(hRet) then begin
Result := hRet;
Exit;
end;
// Цикл заполнения буфера данными из массивов
for i := 0 to sizeof(face_indicies) div sizeof(face__indicies[0]) - 1 do for j := 0 to 2 do begin
vi := face_indicies[i][j]; // Индекс фасета
ni := face_indicies[i] [j+3]; // Индекс нормали фасета
// Исходные данные масштабируем, умножая на 5
Vertices.X := Avertices[vi][0] * 5;
Vertices.Y := Avertices[vi][1] * 5;
Vertices.Z := Avertices[vi][2] * 5;
Vertices.normVector.X := normals[ni] [0] ;
Vertices.normVector.Y := normals[ni][1];
Vertices.normVector.Z := normals[ni][2];
Inc(Vertices);
end;
Result := FDSDVBEagle.Unlock;
end;
При инициализации работы один раз устанавливается материал, а при воспроизведении необходимо указывать, окрашивание производится исходя из цветовой составляющей вершины, либо используется установленный материал:
with FDSDDevice do begin
SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
// Для ландшафта цвет примитивов задается цветовой составляющей вершин
SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
SetTransform(D3DTS_WORLD, IdentityMatrix); // Выключаем третий источник,
// предназначенный для освещения только модели
LightEnable(2, False);
SetStreamSource(0, FD3DVBLand, SizeOf(TCustomVertexLand));
SetVertexShader(D3DFVF_CUSTOMVERTEXLand);
end;
// Вывод треугольников ландшафта
for j := 2 to NumZ - 1 do
for i := 1 to NumX - 5 do
DrawAreafi, j);
with FDSDDevice do begin
SetTransform(D3DTS_WORLD, matEagle);
LightEnable(2, True); // Включаем дополнительный источник
SetStreamSource(0, FD3DVBEagle, SizeOf(TCustomVertexEagle));
SetVertexShader(D3DFVF_CUSTOMVERTEXEagle) ;
// Окрашивание осуществляется исходя из свойств материала
SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
DrawPrimitive{D3DPT_TRIANGLELIST, 0, 10500 div 3);
end;
По умолчанию для режима D3DRS_DiFFUSEMATERlALSoracE устанавливается значение D3DMCS_COLOR1. Здесь же мы восстанавливаем это значение, потерянное после воспроизведения модели орла.
Закончу главу небольшими замечаниями по поводу моделей. Конечно, совсем не обязательно, чтобы используемые вами модели были однотонными, как в моих примерах. Импортирующая программа, рекомендованная мной, позволяет записывать в DXF-файлах (или в другом формате) отдельные части моделей. Вы можете разбить модель на части, считывать данные на них по отдельности и окрашивать фрагменты в различные цвета, меняя текущий материал, или задавать нужный цвет вершин.
Если данные модели заполняются так же, как в последнем примере, в виде массивов констант, и без расчета нормалей, то массивы могут храниться в отдельных файлах внутреннего формата или загружаться из библиотек. В этом случае размер главного модуля станет меньше. Также мне необходимо уточнить, что модель строится группой несвязанных треугольников.
Что вы узнали в этой главе
Глава посвятила нас в премудрости матричных операций, что позволило нам перенести построения в пространство. Мы узнали, как с помощью несложных средств можно создавать составные объекты. Хотя примеры главы крайне просты, усердные читатели смогут легко развить их до совершенных и серьезных программ.
ГЛАВА 10 Визуальные эффекты