Клавишами управления курсором можно регулировать, как глубоко распространяется это отражение, нажатием на клавишу 'Н' можно менять точку зрения, при взгляде сверху демонстрируются ложные дубликаты объектов.
Главной в этом примере является процедура 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).