Figura 22
– Cena em Múltiplas telas
Em OpenGL, para gerar este tipo de imagem usa-se a função glFrustum que define o View Frustum ou “volume de visualização” a ser usado para projetar uma cena da tela. Na Figura 23 pode-se observar o “volume de visualização” e sua relação com a posição do observador e do alvo.
Figura 23
– Volume de Visualização
Na Figura 24
este mesmo “volume de
visualização” é apresentado
com
suas respectivas dimensões.
Figura 24 – Volume
de
Visualização (com dimensões)
Na Figura 24, os valores DF e DN
são, respectivamente as distâncias
máximas e mínimas do volume visível
pelo
observador e L (de Left) e R (de Right) definem o quanto o observador
vê
à esquerda e à direita de seu ponto central de
visão, exatamente na distância
do plano NEAR. Para definir um volume de
visualização é necessário
ainda
definir os limites verticais (inferior e superior) da visão
do observador na
distância do plano NEAR. Para efeito de exemplo estas medidas
serão chamadas B
(de Bottom) e T (de Top), respectivamente.
Os
valores
de NEAR e FAR são fornecidos, em geral, pela
aplicação. Os valores de L e R
podem ser calculados a partir do ângulo de visão
pelas fórmulas:
L = -Near *
tan(ViewAngleRad/2)
R = Near *
tan(ViewAngleRad/2)
Se
considerarmos o Plano NEAR como um quadrado, teremos B igual a L e T
igual a R.
A partir destes valores é possível
definir o volume de visualização,
através da função glFrustum. O código da Figura
25
apresenta um exemplo deste procedimento.
Para
exibir uma cena
em múltiplas telas, deve-se dividir o “volume de
visualização”
de forma que cada janela exiba uma parte
dele. Na Figura 26
pode-se observar 3 volumes de visualização
distintos.
//
************************************************
// void SetViewFrustum()
//
************************************************
void SetViewFrustum()
{
float Near, Left, Right, Bottom, Top;
float ViewAngleRad;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
ViewAngleRad = ViewAngle * 3.14f/180;
Near = 1; // definido na
aplicação
Far = 100; // definido na
aplicação
// Calcula os limites horizontais do View
// Frustum
Left = -Near * tan(ViewAngleRad/2);
Right = Near * tan(ViewAngleRad/2);
// Calcula os limites verticais do View
// Frustum
Bottom = -Near * tan(ViewAngleRad/2);
Top = Near * tan(ViewAngleRad/2);
// Seta o Frustum
glFrustum(Left, Right, Bottom, Top, Near, Far);
glMatrixMode(GL_MODELVIEW);
SetObs();
// posiciona o
observador
}
Figura 25 – Setando
o
Volume de Visualização
Figura 26 –
Dividindo o
Volume de Visualização
Em OpenGL, para recalcular o View
Frustum, toma-se o ângulo de visão e
divide-se pelo número de janelas nas
quais se deseja exibir a imagem. Note que se deve dividir separadamente
o
volume na horizontal e na vertical pois o número de telas
nestas duas direções
pode ser diferente.
No código apresentado na Figura 27 pode-se
observar um exemplo que um “volume de
visualização” é dividido
horizontalmente
em 3 janelas e verticalmente em duas. A Figura 28
apresenta o resultado visual deste programa.
// *************************************************
// void SetViewFrustum()
// *************************************************
void SetViewFrustum()
{
float Near, Left, Bottom, Top, Right, TileWidth, TileHeight;
float ViewAngleRad;
glMatrixMode(GL_PROJECTION); glLoadIdentity();
Near = 1; // definido na
aplicação
Far = 100; // definido na
aplicação
// Calcula os limites horizontais do View
// Frustum
Left = -Near * tan(ViewAngleRad/2);
Right = Near * tan(ViewAngleRad/2);
// Calcula os limites verticais
do View Frustum
Bottom = -Near * tan(ViewAngleRad/2);
Top = Near * tan(ViewAngleRad/2);
// Calcula a largura e a
altura de cada janela
TileWidth = (Right - Left)/3;
TileHeight = (Top - Bottom)/2;
// Seta o Frustum de cada
janela
if (glutGetWindow()==jan1)// Inferior Esquerda
glFrustum(Left, Left+TileWidth,
Bottom, Bottom+TileHeight, Near, Far);
if (glutGetWindow()==jan2) // Inferior Central
glFrustum(Left+TileWidth, Left+TileWidth*2,
Bottom, Bottom+TileHeight, Near, Far);
if (glutGetWindow()==jan3) // Inferior Direita
glFrustum(Left+TileWidth*2,
Left+TileWidth*3,
Bottom, Bottom+TileHeight, Near, Far);
if (glutGetWindow()==jan4) // Superior Esquerda
glFrustum(Left, Left+TileWidth,
Bottom+TileHeight, Top, Near, Far);
if (glutGetWindow() == jan5) // Superior Central
glFrustum(Left+TileWidth, Left+TileWidth*2,
Bottom+TileHeight, Top, Near, Far);
if (glutGetWindow() == jan6) // Superior Direita
glFrustum(Left+TileWidth*2,
Left+TileWidth*3,
Bottom+TileHeight, Top, Near, 100);
glMatrixMode(GL_MODELVIEW);
SetObs();
}
Figura
27 –
Código de Divisão do View
Frustum
Figura 28 – “Telão 3 x
2”
Altere o programa a fim de exibir QUATRO janelas, numa composição de duas linhas e duas colunas.
No caso de usar o DEV CPP, lembre-se de colocar as
opções
-lopengl32 -lglu32 -lglut32 no projeto. Para baixar as
bibliotecas a serem usdas no DEVCPP clique
aqui.