Михаил Краснов - Графика DirectX в Delphi
- Название:Графика DirectX в Delphi
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Михаил Краснов - Графика DirectX в Delphi краткое содержание
Графика DirectX в Delphi - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Списки, переменные типа TList, Model и Normals содержат данные о считанных вершинах и вычисленных нормалях:
// Блокировать предупреждения компилятора
//о возможно пропущенной инициализации переменных
{$WARNINGS OFF}
procedure TForml.LoadDXF (const FileName : String);
var
f : TextFile;
wrkstring : String;
group, err : Integer;
xl, x2, yl, y2, zl, z2, x3, y3, z3 : Single;
// Процедура, дополняющая список вектором procedure
AddToList (const X, Y, Z : Single);
var
pwrkVector : ^TD3DVector;
begin
New (pwrkVector);
pwrkVector^ := D3DVector (X, Y, Z) ;
Model.Add (pwrkVector);
end;
begin
AssignFile(f, FileName);
Reset(f);
// Считываем данные из DXF-файла до секции ENTITIES
repeat
ReadLn(f, wrkString);
until (wrkString = 'ENTITIES') or eof(f);
while not eof (f) do begin
ReadLn (f, group); // Нулевая группа содержит вершины треугольника
ReadLn (f, wrkString); // Идентификатор либо координата
case group of
0: begin
AddToList (хЗ, y3, z3) // Добавляем вершины в список
AddToList (х2, y2, z2)
AddToList (xl, yl, zl)
end;
10: val(wrkString, xl, err)
20: val(wrkString, yl, err)
30: val(wrkString, zl, err)
11: val(wrkString, x2, err)
21: val(wrkString, y2, err)
31: val(wrkString, z2, err)
12: val(wrkString, x3, err)
22: val(wrkString, y3, err)
32: val(wrkString, z3, err)
end;
end;
CloseFile(f);
end;
{$WARNINGS ON}
// Процедура вычисления нормалей к треугольникам списка
Model procedure TForml.CalcNormals;
var
i : Integer;
wrki, vxl, vyl, vzl, vx2, vy2, vz2 : Single;
nx, ny, nz : Single;
wrkVector : TD3DVector;
pwrkVector : ^TDSDVector;
wrkVectorl, wrkVector2, wrkVectorS : TD3DVector;
pwrkVectorl, pwrkVector2, pwrkVectorS : ATD3DVector;
begin
for i := 0 to Model.Count div 3 - 1 do begin pwrkVectorl := Model [i * 3 + 1];
wrkVectorl := pwrkVectorl^; pwrkVector2 := Model [i * 3];
wrkVector2 := pwrkVector2^-
pwrkVector3 := Model [i * 3 + 2];
wrkVectorS := pwrkVector3^;
// Приращения по координатам
vxl = wrkVectorl.X - wrkVector2.X;
vyl = wrkVectorl.Y - wrkVector2.Y;
vzl = wrkVectorl.Z - wrkVector2.Z;
vx2 = wrkVector2.X - wrkVectorS.X;
vy2 = wrkVector2.Y - wrkVectorS.Y;
vz2 = wrkVector2.Z - wrkVectorS.Z;
// Вектор, перпендикулярный центру треугольника
nx := vyl * vz2 - vzl * vy2;
ny := vzl * vx2 - vxl * vz2;
nz := vxl * vy2 - vyl * vx2;
// Получаем вектор единичной длины
wrki := sqrt (nx * nx + ny * ny + nz * nz);
if wrki = 0 then wrki := 1; // Для предотвращения деления на ноль
wrkVector.X := nx / wrki;
wrkVector.Y := ny / wrki;
wrkVector.Z := nz / wrki;
New (pwrkVector);
pwrkVector^ := wrkVector;
Normals.Add (pwrkVector);
end;
end;
procedure TForml.FormCreate(Sender: TObject);
var
i : Integer; t : TextFile;
p : ATD3DVector;
n : "TDSDVector;
begin
if OpenDialogl.Execute then begin
if SaveDialogl.Execute then begin
Model := TList.Create;
Normals := TList.Create;
LoadDxf (OpenDialogl.FileName);
CalcNormals;
Caption := 'Треугольников - ' + IntToStr(Normals.Count);
AssignFile (t, SaveDialogl.FileName);
Rewrite (t);
// Запись в текстовый файл результатов
for i := 0 to Normals.Count - 1 do begin
n := Normals.Items [i];
// Первым выводится вектор нормали к треугольнику
WriteLn (t, n.X);
WriteLn (t, n.Y);
WriteLn (t, n.Z);
// Координаты вершин треугольников
р := Model.Items [i * 3};
WriteLn (t, p.X)
WriteLn (t, p.Y)
WriteLn (t, p.Z)
p := Model.Items [i * 3 + I];
WriteLn (t, p.X)
WriteLn (t, p.Y)
WriteLn (t, p.Z)
p := Model.Items [i * 3 + 2];
WriteLn (t, p.X)
WriteLn (t, p.Y)
WriteLn (t, p.Z)
end;
CloseFile (t);
Model. Free ;
Normals.Free ;
end;
end;
end;
В заголовке окна выводится количество считанных треугольников, ведь эта информация потребуется для дальнейшего кодирования. Результирующий файл не обязательно должен быть текстовым, вы можете закодировать данные. Также с помощью небольших манипуляций вы можете масштабировать модель, чтобы потом, при ее воспроизведении, не тратить на это драгоценное время.
В Internet существует масса ресурсов, содержащих свободно распространяемые модели. Например, на сайте http://www.3dcafe.com находятся сотни DXF-файлов моделей самой разнообразной тематики, и некоторыми из этих моделей я воспользовался при подготовке примеров настоящей книги. Если же нужная вам модель записана в другом формате, вы можете воспользоваться импортирующей программой.
Таких программ существует множество, я могу порекомендовать 3D Exploration, разработанную компанией X Dimension Software. Эта программа поддерживает огромный набор форматов и поэтому заслуживает вашего внимания.
С любезного разрешения авторов программы, я поместил на компакт-диск, прилагаемый к книге, демонстрационную версию продукта, которую скачал с сайта http://www.xdsoft.com/explorer.
Должен предупредить все ваши возможные вопросы о проблемах с конкретными DXF-файлами. Прежде всего, редактор или импортирующая программа, в которых создан файл, должны уметь разбивать поверхность модели на отдельные треугольники (программа, которую я вам рекомендовал, делает это успешно). В таких файлах самая громоздкая секция следует после фразы ENTITIES, за которой обязан идти большой массив данных, а не короткие фразы.
Вершины треугольников должны перечисляться либо по часовой стрелке, либо против нее. Если по полученному текстовому файлу построить модель у вас не выходит, попробуйте начать разрешение вопросов с того, что отключите отсечение. Если вы уверены, что вершины всех треугольников перечисляются в одинаковом порядке, а вместо модели выводится черный контур, то проблема состоит в вычислении нормали. Обратите внимание, что в коде этого примера при вычислении нормали я поменял порядок перечисления вершин, подобрав такую последовательность, при которой нормали перпендикулярны треугольникам. Поскольку вершин только три, вы не потеряете много времени на поиски подходящего для конкретного DXF-файла порядка. И последнее, что, возможно, вам придется сделать, если вы получаете только черную тень модели, - это поменять направление нормали на противоположное:
wrkVector.X := - nx / wrki;
wrkVector.Y := - ny / wrki;
wrkVector.Z := - nz / wrki;
Мне пришлось столкнуться с тем, что многие корреспонденты обращаются с возникающими проблемами при обработке DXF-файлов, поэтому должен четко ограничить круг действительно серьезных проблем лишь двумя: либо файл не содержит разбиение модели по треугольникам, либо вершины треугольников перечисляются в различном порядке. Во всех остальных случаях решение получить нетрудно.
Достоинствами использования DXF-файлов является то, что это открытый формат, и поддерживается он практически всеми моделирующими программами. Недостатки таковы:
* модель строится по отдельным, независимым треугольникам, что приводит к избыточности данных; это текстовый формат, поэтому для больших моделей получаются файлы гигантских размеров.
Однако в наших примерах эти файлы нужны только при подготовке кода, непосредственно при работе приложения они не применяются, и нет необходимости распространять их вместе с приложением. Наши примеры загружают данные модели из текстового файла. Полученные текстовые файлы, конечно, тоже имеют большие размеры, но помните, что вы не обязаны использовать именно текстовые файлы. Записывайте данные в виде вещественных значений, и объем файла сразу же значительно уменьшится.
А теперь перейдем к следующему примеру, проекту каталога Ех07 - несложной заготовке увлекательной игры. Вам остается только развить программу, чтобы получить законченное произведение, со стрельбой и коварными противниками, а пока что сюжет игры совсем прост: космический корабль мчится в пространстве, наполненном сферами (рис. 9.8).
Читать дальшеИнтервал:
Закладка: