OpenGL в Delphi

Пример на создание многократного отражения




Клавишами управления курсором можно регулировать, как глубоко распространяется это отражение, нажатием на клавишу 'Н' можно менять точку зрения, при взгляде сверху демонстрируются ложные дубликаты объектов.
Главной в этом примере является процедура draw_scene, используемая рекурсивно для многократного воспроизведения объектов сцены:

const
stencilmask : longint = $FFFFFFFF;
procedure TfrmGL.draw_scene(passes:GLint; cullFace:GLenum;
stencilVal:GLuint; mirror: GLint);
var
newCullFace : GLenum;
passesPerMirror, passesPerMirrorRem, i : GLint;
curMirror, drawMirrors : GLUint;
begin
// один проход, чтобы сделать реальную сцену
passes := passes - 1;
// рисуем только в определенных пикселах
glStencilFunc(GL_EQUAL, stencilVal, stencilmask);
// рисуем вещи, которые могут закрыть первые зеркала
draw_sphere;
draw_cone;
// определяем номер отражений зеркала
If mirror о -1 then begin
passesPerMirror := round(passes / (nMirrors - 1));
passesPerMirrorRem := passes mod (nMirrors - 1) ;
If passes > nMirrors - 1
then drawMirrors := nMirrors - 1
else drawMirrors := passes;
end
else begin
// mirror == -1 означает, что это - начальная сцена (не было
// никаких зеркал)
passesPerMirror := roundfpasses / nMirrors);
passesPerMirrorRem := passes mod nMirrors;
If passes > nMirrors
then drawMirrors := nMirrors
else drawMirrors := passes;
end;
i := 0;
While drawMirrors > 0 do begin
curMirror := i mod nMirrors;
If curMirror <> mirror then begin
drawMirrors := drawMirrors - 1;
// рисуем зеркало только в буфере шаблона
glColorMask(False, False, False, False);
glDepthMask(False);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
draw_mirror(mirrors[curMirror]);
glColorMask(True, True, True, True);
glDepthMask(True) ;
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // рисуем отраженную сцену
newCullFace := reflect_through_mirror(mirrors[curMirror], cull-Face) ;
If passesPerMirrorRemoO then begin
// рекурсивное обращение самой к себе
draw_scene(passesPerMirror + 1, newCullFace, stencilVal + 1, curMirror);
passesPerMirrorRem := passesPerMirrorRem - 1;
end
else draw_scene(passesPerMirror, newCullFace, stencilVal + 1,
curMirror);
// возвращаем видовые параметры
undo_reflect_through_mirror(mirrors[curMirror], cullFace);
// обратная сторона в нашей величине шаблона
glStencilFunc(GL_EQUAL, stencilVal, stencilmask);
end;
me (i) ;
end;
draw_room;
end;

В этой главе нас ждет еще один пример с использованием эффекта зеркального отражения, так что мы не прощаемся с этой темой окончательно.
Закончу раздел примером, в котором хотя и эмулируется зеркало, однако непосредственно эффекта отражения не создается
Откройте проект из подкаталога Ех75. После запуска откомпилированного модуля на экране появляется следующая картина по кругу, в центре которого находится глаз наблюдателя, вращаются четыре цветных кубика В верхней части экрана располагается прямоугольник, в котором как в зеркальце заднего вида отражается кубик, находящийся за спиной наблюдателя (Рисунок 4.49).



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