OpenGL в Delphi

       

Простейший пример на операции с буфером трафарета




Инициализация работы приложения начинается с задания характеристик буфера трафарета

glClearStencil(0); // значение заполнения буфера трафарета при очистке
glStencilMask(l); // число битов, задающее маску
glEnable(GL_STENCIL_TEST); // включаем тест буфера трафарета

Первые две команды вызываются с аргументами, имеющими значение, принятое по умолчанию, поэтому могут быть удалены

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

Первая команда задает фоновое значение, которым будет заполнен буфер при выполнении команды glclear с аргументом GL_STENCIL_BUFFER_BIT вторая команда разрешает или запрещает перезапись битов в плоскости трафарета
Теперь разберем код перерисовки кадра:

// очищаются буфер цвета и буфер трафарета
glClearf GL_COLOR_BUFFER_BIT or GL_STENCIL_BUFFER_BIT);
// треугольник
// тест всегда завершается положительно
glstencilFunc(GL_ALWAYS, 1, I);
// значение буфера устанавливается в 1 для всех точек треугольника
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glColor3ub(200, 0, 0); // цвет - красный
glBegin(GL_POLYGON);
glVertex3i(-4, -4, 0);
glVertex3i( 4, -4, 0);
glVertex3i( 0, 4, 0) ;
glEnd;
// зеленый квадрат
// только для точек, где в буфере записана единица
glStencilFunc(GL_EQUAL, 1, 1),
// для точек, не подпадающих в тест, значение буфера установить в
// максимальное значение;
// если тест завершился удачно, но в буфере глубины меньшее значение,
// сохранить текущее значение буфера трафарета;
// если в буфере глубины большее значение, задать значение нулевым
glStencilOp(GL_INCR, GLJKEEP, GL_DECR);
glColor3ub(0, 200, 0); glBegin(GL_POLYGON);
glVertex3i(3, 3, 0};
glVertex3i(-3, 3, 0);
glVertex3i(-3, -3, 0);
glVertex3i(3, -3, 0); glEnd;
// синий квадрат
// только для точек, где в буфере записана единица
glstencilFunc(GL_EQUAL, I, 1);
// для всех точек сохранить текущее значение в буфере трафарета
glStencilOp (GLJCEEP, GL_KEEP, GL_KEEP) ;
glColor3ub(0, 0, 200);
glBegin(GL_POLYGON);
glVertex3i(3, 3, 0) ;
glVertex3i(-3, 3, 0);
glVertex3i(-3, -3, 0);
glVertex3i(3, -3, 0);
glEnd;

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

glStencilOp(GL_INCR, GL_KEEP, GLJ3ECR);

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

Замечание
Наверное этот раздел покажется поначалу сложным для понимания но хочу вас успокоить тем, что совсем не обязательно сразу же уяснить все тонкости работы с буфером трафарета Вы можете пока пробежаться по примерам чтобы затем вернуться к ним в случае необходимости и еще раз хорошенько все повторить. Сейчас мы попробуем решить одну и ту же задачу двумя немного различными способами Задача состоит в том, чтобы проделать отверстие в квадратной площадке.
На рис 4.22 представлен результат работы проекта из подкаталога Ех33 квадратная площадка с просверленным отверстием в виде кольца (на экране она вращается), сквозь которое видно красную сферу, расположенную позади площадки.



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