OpenGL в Delphi

Кривая Безье, построенная с помощью функций библиотеки OpenGL




В обработчике создания формы задаются параметры так называемого одномерного вычислителя, и включается этот самый вычислитель:

glMaplf (GL_MAPl_VERTEX_3, 0. 0, 1. 0, 3, 4, @ctrlpoints);
glEnable (GL_MAPl_VERTEX_3);

Первый параметр команды glMapl - символическая константа, значение GL_MAPI_VERTEX_3 соответствует случаю, когда каждая контрольная точка представляет собой набор трех вещественных чисел одинарной точности, т. e. координаты точки Значения второго и третьего аргументов команды определяют конечные точки интервала предварительного образа рассчитываемой кривой. Величины ноль и один для них являются обычно используемыми, подробнее мы рассмотрим эти аргументы чуть ниже.
Четвертый параметр команды, "большой шаг", задает, сколько чисел содержится в считываемой порции данных. Как говорится в документации, контрольные точки могут содержаться в произвольных структурах данных, лишь бы их значения располагались в памяти друг за другом.
Последние два параметра команды - число опорных точек и указатель на массив опорных точек.
Для построения кривой можно использовать точки или отрезки' вместо команды, задающей вершину, вызывается команда glEvalcoord, возвращающая координаты рассчитанной кривой"

glBegin(GL__LINE_STRIP);
For i: = 0 to 30 do
glEvalCoordlf (i / 30. 0);
glEnd;

Аргумент команды - значение координаты u. В данном примере соединяются отрезками тридцать точек, равномерно расположенных на кривой Теперь выясним правила отображения интервала Если в этом примере третий параметр команды glMaplf задать равным двум, то на экране получим половину первоначальной кривой. Для получения полной кривой надо при воспроизведении взять интервал в два раза больший:

glBegin(GL_LINE_STRIP); For i: = 0 to 60 do
glEvalCoordlf(i / 30. 0); glEnd;

Если же этот параметр задать равным 0. 5, то при отображении интервала с u в пределах от нуля до единицы получаемая кривая не будет останавливаться на последней опорной точке, а экстраполироваться дальше. Если в этом нет необходимости, конечное значение параметра цикла надо взять равным 15 Чтобы действительно разобраться в подобных вопросах, надо обязательно попрактиковаться, посмотреть, какие кривые строятся для различных наборов опорных точек. Здесь вам поможет проект из подкаталога Ex42, где cpeди четырех опорных точек имеется одна выделенная. Клавишами управления курсором можно менять положение выделенной точки, при нажатии на Пробел выделенной становится следующая точка набора. Выделенная точка Рисуется красным Обратите внимание, что простой перерисовки окна при изменении в массиве опорных точек недостаточно, необходимо заново обратиться к командам, "заряжающим" вычислитель, чтобы пересчитать кривую:

If Key = VK_SPACE then begin
// выделенной становится следующая точка набора
selpoint: = selpoint + 1;
If selpoint > High (selpoint) then selpoint: = Low (selpoint);
InvalidateRect(Handle, nil, False);
end;
If Key = VK_LEFT then begin
// сдвигаем выделенную точку влево
ctrlpoints [selpoint, 0]: = ctrlpoints [selpoint, 0] - 0. 1;
// пересчитываем кривую по измененному массиву опорных точек
glMaplf(GL_MAPl_VERTEX_3, 0. 0, 1. 0, 3, 4, @ctrlpoints);
glEnable (GL_MAPl_VERTEX__3);
InvalidateRect(Handle, nil, False); // перерисовка окна
end;

С помощью этого примитивного редактора можно построить замысловатые фигуры и заодно получить представление о кривых Безье.

Замечание
Не получится расположить все четыре точки на кривой, если только это не линейная функция.

С помощью команды glGetMapfv в любой момент можно получить полную информацию о текущих параметрах вычислителя. Не думаю, что вы часто будете обращаться к этой команде, но на всякий случай приведу пример на ее использование (проект из подкаталога Ex43). Клавишами <Insert> и <Delete> можно менять текущее значение параметра вычислителя u2, в заголовке окна выводятся значения u1 и u2. Эти значения приложение получает от OpenGL:

wrk: Array [0.. 1] of GLfloat;
begin
glGetMapfv (GL_MAPl_VERTEX_3, Caption: = FloatToStr (wrk[0]
GL_DOMAIN, @wrk); + ', ' + FloatToStr(wrk[l]);

Из файла справки вы можете узнать, как получить значения всех остальных параметров вычислителя.
Построить кривую можно и другим способом. Посмотрим пример из подкаталога Ex44, отличающийся от предыдущего примера на кривые Безье следующим: сразу после включения вычислителя вызывается команда, строящая одномерную сетку, т. e. рассчитывающая координаты набора точек на интервале:

glMapGridlf (30, 0, 1);

Первый аргумент - количество подинтервалов, далее задается интервал по координате u. После того как сетка построена, вывод ее осуществляется одной командой:

glEvalMeshl (GL_LINE, 0, 30);

Первый аргумент - режим воспроизведения, отрезками или точками, остальные аргументы задают номера первой и последней точек рассчитанной сетки.
Получив представление о кривых, мы можем перейти к поверхностям Безье. Соответствующий пример располагается в подкаталоге Ex45, а результат работы программы показан на Рисунок 3. 29.



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