OpenGL в Delphi

       

Каждый патч поверхности можно перекрасить




Модель выводится в красном цвете, при щелчке на любой точке модели соответствующий патч перекрашивается в зеленый цвет.
Для хранения модели в этом примере используется не список, а динамический массив. Формат файла, хранящего данные модели, здесь немного другой: первая строка содержит количество патчей в модели, далее каждое число записывается с новой строки.
Помимо массива патчей введен массив цвета каждого патча:

type
PPointArray = ^TPointArray; // динамический массив модели
TPointArray = Array [0..0] of AVector;
ColorArray = Array [0..2] of GLfloat; // массив цвета патча
PColorArray = ^TColorArray; // указатель на массив
TColorArray = Array [0..0] of ColorArray; // собственно массив

При считывании модели создаем массив цвета патчей, массив цвета для каждого патча заполняем красным:

procedure TfrmGL.Init_Surface;
var
f : TextFile;
i, j : Integer;
begin
AssignFile (f, 'Eye.txt');
ReSet (f);
ReadLn (f, numpoint); // количество патчей в модели
GetMem (Model, (numpoint + 1) * SizeOf (AVector)); // выделяем память
// создаем динамический массив цвета патчей
GetMem (PatchColor, (numpoint + 1) * SizeOf (ColorArray));
For i := 0 to numpoint do begin
For j := 0 to 15 do begin // считываем очередной патч модели
ReadLn (f. Model [i][j].x); // каждое число с новой строки
ReadLn (f, Model [i] [3].у);
ReadLn (f, Model [i][]].z);
end;
// массив цвета очередного патча
PatchColor [i][0] := 1.0; // красный
PatchColor [i][1] := 0.0;
PatchColor [i][2] := 0.0;
end;
CloseFile (f);
end;

Вывод собственно модели вынесен в отдельную процедуру, при обращении к которой с аргументом GL_SELECT каждый патч именуется, в качестве имени берется его порядковый номер:

procedure TfrmGL.Render (Mode : GLEnum);
var
i : Integer;
begin
glPushMatrix; glScalef (2.5, 2.5, 2.5);
For i := 0 to numpoint do begin
If mode = GL_SELECT
then glLoadName (i) // именование воспроизводимого патча
else glColor3fv(@PatchColor[i]); // при выборе цвет безразличен
// построение очередного патча
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 4, 4, 0, 1, 16, 4, @model[i]);
glEvalMesh2(GL_FILL, 0, 4, 0, 4);
end;
glPopMatrix;
end;

Как я подчеркнул в комментарии, при обращении к этой процедуре с воспроизведением в режиме выбора объектов можно не тратить время на установку текущего цвета. Для обычного режима воспроизведения перед собственно воспроизведением очередного патча задаем текущий цвет, воспользовавшись вызовом команды glColor в векторной форме с аргументом - указателем на массив цвета. При нажатии кнопки мыши осуществляется выбор объекта под курсором

hits := Deselect (X, Y) ;

И если номер объекта больше либо равен нулю, меняем цвет соответствующего патча и перерисовываем экран

PatchColor [hits][0] := 0.0;
PatchColor [hits][1] := 1.0;
PatchColor [hits][2] := 0.0;
InvalidateRect(Handle, nil, False);

Если же нажимать кнопку на пустом месте, то при движении курсора модель вращается, так что легко убедиться, что выбор осуществляется при любом положении точки зрения в пространстве
Обратите внимание, что размер буфера выбора я задал сравнительно большим, 128. Если брать его, как в предыдущих примерах, равным четырем, то приложение работает устойчиво, но при выходе из него появляется сообщение об ошибке, знакомое каждому программисту (рис 6 3).



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