OpenGL в Delphi

Часто разработчики нуждаются в нескольких экранах




Следующий пример не имеет отношения к функциям работы с пикселами, но подготавливает к следующим примерам и сам по себе является очень полезным. В проекте из подкаталога Ех55 в окне приложения присутствует несколько экранов, в каждом из которых одна и та же сцена видна из различных точек зрения (Рисунок 4.34).
Для разбиения окна на несколько экранов пользуемся знакомым нам приемом, основанным на использовании команд glviewport и glscissor. Напомню, что вторая из них нам необходима для того, чтобы при очистке буфера кадра не закрашивался весь экран.
Для сокращения кода видовые параметры задаются одинаковыми для всех трех экранов:

procedure TfrmGL.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadldentity;
gluPerspective (60.0, ClientWidth / ClientHeight, 5.0, 70.0);
glMatrixMode (GL_MODELVIEW);
glLoadldentity;
InvalidateRect(Handle, nil, False);
end;

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

glPushMatrix;
// первый экран - левая половина окна
glviewport(0,0,round(ClientWidth/2), ClientHeight);
glScissor(0,0,round(ClientWidth/2), ClientHeight); //вырезка
glClearColor(0. 55, 0. 9, 0. 4, 0. 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
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);
glPopMatrix;
// второй экран - правый верхний угол окна
// единица - для получения разделительной линии
glViewport(round(ClientWidth/2) + l, round(ClientHeight/2) +1,
round(ClientWidth/2), round(ClientHeight/2));
glScissor(round(ClientWidth/2) + l, round(ClientHeight/2) +1,
round(ClientWidth/2), round(ClientHeight/2));
glClearColor(0. 7, 0. 7, 0. 9, 0. 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glPushMatrix;
gluLookAt(25. 0, 50. 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);
glPopMatrix;
// третий экран - левый нижний угол окна
glViewport(round(ClientWidth/2) +l, 0, round(ClientWidth/2),
round(ClientHeight/2));
glScissor(round(ClientWidth/2)+l, , round(ClientWidth/2), round(ClientHeight/2));
glClearColor(0. 0, 0. 6, 0. 7, 0. 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glPushMatrix;
gluLookAt(0. 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);
glPopMatrix;
glPopMatrix;

Стоит напомнить, что без следующей строки ничего работать не будет.

glEnable(GL_SCISSOR_TEST); // включаем режим вырезки

Два рассмотренных примера подготовили нас к тому, чтобы познакомиться со следующим проектом из подкаталога Ex56, где визуализируется содержимое буфера глубины (рис 4.35).



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