OpenGL в Delphi

Содержимое буфера глубины доступно для визуализации




Окно приложения не изменяется в размерах, для хранения содержимого буфера глубины введен массив с размерностью, подогнанной под размеры окна:

Zbuf: Array [0.. WIN_WIDTH - 1, 0.. WIN HEIGHT - 1] of GLfloat;

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

glViewport(0, 0, round(ClientWidth/2), ClientHeight);
glScissor(0, 0, round(ClientWidth/2), ClientHeight);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
// для правого экрана задается перспективная проекция
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(60. 0, ClientWidth / ClientHeight, 5. 0, 70. 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glPushMatrix;
gluLookAt(25. 0, 25. 0, 50. 0, 25. 0, 25. 0, 20. 0, 0. 0, 1. 0, 0. 0);
glTranslatef(25. 0, 25. 0, 10. 0);
glRotatef (Angle, 1. 0, 0. 0, 0. 0);
glCallList(Torus);
// копируем в массив содержимое буфера глубины
glReadPixels(0, 0, WIN_WIDTH, WIN_HEIGHT, GL_DEPTH_COMPONENT, GL FLOAT,
Zbuf);
glPopMatrix;
// левый экран
glViewport(round(ClientWidth/2) +1, 0, round(ClientWidth/2), ClientHeight);
glScissor(round(ClientWidth/2) + 1, 0, round(ClientWidth/2), ClientHeight);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glPushMatrix;
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glRasterPos2i (-1, -1) ; // позиция вывода в координатах экрана
// вывод содержимого массива
glDrawPixels(WIN_WIDTH, WIN_HEIGHT, GL_LUMINANCE, GL_FLOAT, @Zbuf);
glPopMatrix;

Содержимое массива (буфера глубины) выводится оттенками серого, пикселы, наиболее близко расположенные к наблюдателю, выглядят темнее, глубина максимальна для наиболее удаленных точек.
Если третий аргумент команды glDrawPixels изменить, например, на GL_GREEN, получим ту же самую картинку в оттенках зеленого. Комбинируя значения пятого аргумента команды glReadPixels и третьего параметра команды glDrawPixels, можно получать различные видеоэффекты (посмотрите мою пробу на эту тему в подкаталоге Ех57).
Возможно, вам потребуется, чтобы на экране присутствовало только одно трансформированное изображение. Двойная буферизация будет здесь как никогда кстати.
В проекте из подкаталога Ех57 демонстрируется, как это можно сделать (Рисунок 4.36).



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