Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
комп графика Лекции.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
200.48 Кб
Скачать

6.2 Логические операции с графическими объектами

Для выполнения логических операций над графическими объектами, можно воспользоваться функциями, находящимися в модуле Unit2.pas (лаб4).

type

proctype = procedure;

procedure one(a : proctype); // вывод графического объекта а

procedure procOR (a, b : proctype); // объединение графического объекта а с объектом b

procedure procAND (a, b : proctype); // пересечение графического объекта а с объектом b

procedure sub (a, b : proctype); // вычитание графического объекта а из объекта b

Процедурами, используемыми в вышеописанных функциях, могут быть процедуры удовлетворяющие следующим требованиям:

- процедуры должны иметь прототипы;

- процедуры не могут иметь формальных параметров. (Все параметры описываются в самих процедурах).

Например.

procedure procSphere;

procedure procCube;

procedure procCone;

procedure procCylinder;

Для реализации той или иной логической операции достаточно в FormPaint вызвать нужную функцию

Например.

sub (procCube, procSphere);

Но, разумеется эти процедуры, предварительно должны быть описаны в модуле Unit2.

procedure procCube;

begin

glLoadName(1);

glPushMatrix;

glTranslatef(cube_x, cube_y, cube_z);

glColor3f(1.0, 0.0, 0.0);

glutSolidCube(4);

glPopMatrix;

end;

procedure procSphere;

begin

glLoadName(2);

glPushMatrix();

glTranslatef(sphere_x, sphere_y, sphere_z);

glColor3f(1.0, 1.0, 0.0);

glutSolidSphere(2.5, 16, 16);

glPopMatrix();

end;

где

cube_x, cube_y, cube_z и

sphere_x, sphere_y, sphere_z координаты куба и сферы описанные, как глобальные переменные.

6.2.1 Описание метода вычитания графических объектов

Общая идея метода вырезания шаровой поверхности из куба:

- из тыльной поверхности шара вырезаем отверстия в местах пересечения с поверхностью куба;

- выводим лицевую поверхность куба с отверстиями в местах пересечения с поверхностью шара.

Что бы реализовать первую задачу (вывести поверхность шара), выполняем следующие действия:

- отключаем запись в буфер кадра;

- отбросить лицевую часть сферы;

- не отображая шар, записываем его в буфер глубины;

- отключаем буфер глубины

- лицевую часть куба помещаем в буфер трафарета, записав в туда 1, а тыльную часть отбрасываем;

- тыльную часть куба помещаем в буфер трафарета, записав в туда 0, а лицевую часть отбрасываем;

- включаем запись в буфер кадра;

- Тыльную часть шара рисуем там, где в буфере трафарета не 0.

Поясним описанный выше метод: В описанном выше методе отображается только тыльная (внутренняя) часть шара, и то только там где она выше тыльной части куба и видна через лицевые грани кубе.

Аналогичным образом поступаем с кубом:

- отключаем запись в буфер кадра;

- отбросить тыльную часть куба;

- не отображая куб, записываем его в буфер глубины;

- отключаем буфер глубины

- тыльную часть шара помещаем в буфер трафарета, записав в туда 1, а лицевую часть отбрасываем;

- лицевую часть шара помещаем в буфер трафарета, записав в туда 0, а тыльную часть отбрасываем;

- включаем запись в буфер кадра;

- Лицевую часть куба рисуем там, где в буфере трафарета 0.

Поясним метод: В описанном выше методе отображается только внешняя часть куба, и то только там где она выше лицевой части шара там, где ниже – будет отверстие.

Для выполнения этих функций используется команда:

inside(a, b, GL_FRONT, GL_NOTEQUAL); - для отображения внутренней поверхности а вписанной

в объект b.

inside(b, a, GL_BACK, GL_EQUAL); для отображения внутренней поверхности а описанной

вокруг объекта b.

procedure sub (a, b : proctype);

begin

inside(a, b, GL_FRONT, GL_NOTEQUAL);

fixup(b);

inside(b, a, GL_BACK, GL_EQUAL);

end;

//---

procedure inside(a, b : proctype; face, test : GLenum);

begin

glEnable(GL_DEPTH_TEST);

glColorMask(FALSE, FALSE, FALSE, FALSE);

glCullFace(face);

a;

glDepthMask(FALSE);

glEnable(GL_STENCIL_TEST);

glStencilFunc(GL_ALWAYS, 1, 0);

glStencilOp(GL_KEEP, GL_KEEP, GL_replace);

glCullFace(GL_back);

b;

glStencilOp(GL_keep, GL_keep, GL_decr);

glCullFace(GL_front);

b;

glDepthMask(TRUE);

glColorMask(TRUE, TRUE, TRUE, TRUE);

glStencilFunc(test, 0, 1);

glDisable(GL_DEPTH_TEST);

glCullFace(face);

a;

glDisable(GL_STENCIL_TEST);

end;

//---

procedure fixup (a : proctype);

begin

glColorMask(FALSE, FALSE, FALSE, FALSE);

glEnable(GL_DEPTH_TEST);

glDisable(GL_STENCIL_TEST);

glDepthFunc(GL_ALWAYS);

a;

glDepthFunc(GL_LESS);

end;