OpenGL в Delphi

       

Еще одна модель из отдельных кусочков




Программа написана мною, но автором модели являюсь не я, а Геннадий Обухов, адрес его страницы я указал в приложении 1.
Модель состоит из 444 патча размером 4x4, по шестнадцать точек. Для хранения данных о патчах введен пользовательский тип:

type
TVector = record
x, у, z: GLfloat; end;
TPatch = Array [0.. 15] of TVector;

Модель так же, как и в предыдущем примере, хранится в списке. Список заполняется данными, считываемыми из текстового файла, каждая строка которого содержит координаты очередной вершины. Эта программа тоже является в некотором роде универсальной: требование к файлу заключается в том, что точки должны записываться порциями по шестнадцать, каждая группа представляет собой опорные точки очередного патча.
Я не могу поместить на дискету дополнительные примеры к этой программе, текстовые файлы слишком велики, поясню только, как создаются подобные файлы данных.
Я использовал свободно распространяемый модельер sPatch, позволяющий использовать встраиваемые модули (plug-in) для экспортирования моделей, созданных в нем из патчей, в произвольный формат. В частности, этот модельер позволяет записывать и в формате dxf. Адрес, по которому можно получить sPatch, указан в приложении 1.
Ключевой процедурой разбираемого примера является процедура инициализации поверхности:

Procedure TfrmGL. Init_Surface;
var
f: TextFile;
1: Integer;
Model: TList; // список модели
wrkPatch: TPatch; // вспомогательная переменная, патч
PwrkPatch: ^TPatch; // указатель на патч 188
begin
Model := TList.Create; // создание списка модели
AssignFile (f, 'Parrot.txt'); // открытие файла
ReSet (f);
While not eof (f) do begin
For i := 0 to 15 do // точки считываются по шестнадцать
ReadLn (f, wrkPatch [i].x, wrkPatch [i].y, wrkPatch [i].z);
New (pwrkPatch); // выделение памяти под очередной элемент
pwrkPatch^ := wrkPatch, // задаем указатель на элемент
Model.Add (pwrkPatch); // собственно добавление в список
end;
CloseFile (f);
glNewList (SURFACE, GL_COMPILE);
glPushMatrix; // матрица запоминается из-за масштабирования
glScalef (2.5, 2.5, 2.5) ;
For i := 0 to Model.Count - 1 do begin // цикл построения патчей
glMap2f(GL_MAP2_VERTEX_3, 0, I, 3, 4, 0, 1, 12, 4, Model.Items[i]);
glEvalMesh2(GL_FILL, 0, 4, 0, 4);
end;
glPopMatrix;
glEndList;
Model.Free; // удаление списка
end;

Закончу рассмотрение примера двумя замечаниями:

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

Замечание
Несмотря на то, что при высоком уровне детализации разбиения поверхности на отдельные треугольники мы получим поверхность, не уступающую по качеству воспроизведения варианту со сплайнами, я настоятельно посоветую вам использовать все-таки поверхность Безье Высокая детализация приведет к огромному количеству воспроизводимых примитивов, и скорость воспроизведения заметно упадет.

Приведу еще один прекрасный пример на использование патчей, проект из подкаталога Ех31 (рис 4.20).



Содержание раздела