OpenGL в Delphi

       

В этом примере содержимое экрана запоминается в массиве




Фиолетовая сфера надвигается на наблюдателя и "растворяется" После того как сфера ушла из поля зрения, на сцене остается только фоновая картинка
Трюк заключается в следующем: при самом первом воспроизведении кадра рисуется только площадка, служащая фоном Содержимое экрана сразу же после этого запоминается в массиве, делается как бы слепок экрана:

If first then begin // сделать только один раз
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glCallList(walls); // нарисовать площадку фона
// делаем снимок с экрана
glReadPixels(О, О, 255, 255, GL_RGBA, GL_UNSIGNED_BYTE, @pixels);
first := FALSE; // устанавливаем флаг
Makelmage; // подготовка списка фона
end
else glCallList(zaplmage); // вызов списка фона glPushMatrix;
// рисуем фиолетовую сферу
glTranslatef (20.0, 5.0, 5.0 + dz);
glCallList (sphere);
glPopMatrix;

Если не использовать особых приемов, то либо на экране останутся следы от сферы, либо фоновая картинка не будет объемной.
Для простоты массив, хранящий снимок с экрана, взят постоянных размеров, под клиентскую область экрана 255x255:

Pixels : Array [0..254, 0..254, 0..3] of GLUbyte;

Из-за этого упрощения при изменении размеров окна картинка портится и даже возможно аварийное завершение работы приложения

Замечание
Можно либо запретить изменять размеры окна, либо менять размерность массива при их изменении.

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

procedure TfrmGL.Makelmage;
begin
glNewList(zapImage,GL_COMPILE);
glDisable(GL_LIGHTING);
glClear(GL_DEPTH_BUFFER_BIT or GL_COLOR_BUFFER BIT);
glMatrixMode(GL_PROJECTION);
glPushMatrix; glLoadldentity;
glOrthof(0.0, ClientWidth, 0.0, ClientHeight, -5.0, 50.0);
glMatrixMode(GLJMODELVIEW);
glPushMatrix; glLoadldentity;
glRasterPos2i(0,0);
glPopMatrix;
glMatrixMode(GL_PROJECTION);
glPopMatrix;
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DEPTH_TEST); // буфер глубины - только для чтения
// вывод на экран массива пикселов
glDrawPixels(ClientWidth, ClientHeight, GL RGBA, GL UNSIGNED BYTE,
@pixels);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEndList;
end;



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