Conheça a iniciativa da Biblioteca dos Desenvolvedores
Índice da Biblioteca
Área dos Usuários
Fórum de Discussão
Visualização bidimensional na prática (Viewports) Para entender a visualização bidimensional em OPEN GL precisamos conhecer o conceito “universo”, que pode ser definido como sendo a região, plano ou espaço de uma aplicação. Como qualquer objeto pelo qual devemos representar na tela envolve coordenadas geométricas é necessário adotar um sistema de referência que irá definir uma posição a qual todos os objetos estarão desenhados.
O sistema de referência do universo (SRU) em Open GL consiste em definir as coordenadas através do plano cartesiano normal em dois eixos (x e y).
Sendo x orientado para a direita e y orientado para cima.
Conforme a figura abaixo:
Entretanto o monitor adota o sistema de referência da tela (SRT) que possui algumas diferenças ao sistema SRU.
No SRT a origem fica no canto superior esquerdo do monitor.
Conforme abaixo:
Portanto, para mostrar a correta visualização de um sistema para o outro é necessário fazer uma conversão ou mapeamento das coordenadas.
Veja a ilustração abaixo:
Resumindo iremos sempre desenhar nossos objetos com base no sistema SRU, plano cartesiano normal com eixos x e y.
Depois disso será feita o mapeamento para a tela independente do dispositivo ou resolução da tela.
Como o universo é infinito é preciso especificar qual porção queremos mapear na tela.
A essa área que delimita a área de interessa do usuário chamamos de window ou janela de seleção.
Uma window é delimitada através das coordenadas de seus cantos (esquerdo, direito, superior, inferior) no sistema SRU.
De forma análoga também é necessário definir em que parte desejamos exibir o conteúdo na window no monitor.
Essa região é chamada de viewport ou janela de exibição, uma viewport normalmente é delimitada pelo tamanho da janela GLUT correspondente ao tamanho da resolução do monitor.
Segue abaixo uma ilustração simples para entendimento:
Para mapear o objeto do sistema SRU para o sistema SRT é necessário apenas especificar a viewport e a window, utilizando as funções abaixo:
void glViewport( GLint x, GLint y, GLsizei width, GLsizei height);
Os valores especificadoes nos dois primeiros parâmetros x e y definem a posição da janela na tela enquanto os dois últimos definem a largura e a altura dessa tela.
Se você não especificar viewports no seu programa, o OpenGL assume o viewport default e cria uma para trabalhar com toda a tela. Seria o mesmo que fazer:
Exemplo:
glViewport(0, 0, fLargura/2, fAltura/2);
int glutGet(GLenum state);
Função responsável por pegar informações sobre os estados internos do GLUT. No exemplo, ela foi usada para pegar a largura e altura atual da janela do programa.
Essa função aceita muitos outros argumentos, para mais detalhe consulte o manual de referência do GLUT.
Exemplo:
glutGet(GLUT_WINDOW_WIDTH); // Pega a largura da janela ...
glutGet(GLUT_WINDOW_HEIGHT); // Pega a altura da janela
Essa função serve para definir a window quando se está trabalhando com desenhos 2D. Seus parâmetros correspondem especificamente cada borda da window. Isto é: x mínimo (borda esquerda - left) – x máximo (borda direita - right) – y mínimo (borda inferior - bottom) – y máximo (borda superior - top).
Praticamente já trabalhamos em um viewport só que muitas vezes não declarado explicitamente e sim por default do GLUT.
Entendido o que é um viewport vamos ver como criar mais de um em um mesmo ambiente. Basicamente, o procedimento é:
- Definir viewport1
- Desenhar conteúdo na viewport1
- Definir viewport2
- Desenhar conteúdo na viewport2
if (HabilitaViewport)
{ //Canto superior direito
glViewport(440, 280, 200, 200);
DesenhaQuadrado();
DesenhaBorda();
}
glutSwapBuffers();
}
// Função que é chamada quando uma tecla é apertada
static void TecladoNormal(unsigned char key, int x, int y)
{
switch (key)
{
case 27 : // ESC sai do programa
exit(0);
break;
case 32 : // Barra de espaço Habilita/Desabilita Viewport
if (HabilitaViewport)
HabilitaViewport = false;
else
HabilitaViewport = true;
break;
}
}
// Função que executa rotinas padrões do GLUT
static void idle(void)
{
glutPostRedisplay();
}
void AlteraTamanhoJanela(GLsizei w, GLsizei h)
{ // Evita a divisao por zero
if(h == 0) h = 1;
ratio = 1.0f * w / h; // Atualiza as variáveis
iLargura = w;
iAltura = h;
aspecto = (iLargura / iAltura);
//Seleciona o sistema de coordenadas do tipo Projeção
glMatrixMode(GL_PROJECTION); //Carrega a matriz inicial do sistema de coordenadas selecionado
glLoadIdentity();
FIM DE CÓDIGO...Executando o código acima você verá duas viewports.
São elas: a default que fica de fundo e uma no canto superior direito da tela que possui os mesmos objetos só que de forma reduzida.
// Função que é chamada quando uma tecla é apertada
static void TecladoNormal(unsigned char key, int x, int y)
{
switch (key)
{ // caso aperte ESC sai do programa
case 27 :
exit(0);
break;
}
}
// Função que executa rotinas padrões do GLUT
static void idle(void)
{
glutPostRedisplay();
}
void AlteraTamanhoJanela(GLsizei w, GLsizei h)
{ // Evita a divisao por zero
if(h == 0) h = 1;
// Atualiza as variáveis
fLargura = w;
fAltura = h;
aspecto = (float) fLargura/fAltura;
// Inicializa o sistema de coordenadas
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// e Define Janela de visualização 2D
gluOrtho2D (-win*aspecto, win*aspecto, -win, win);
}
Executando o código acima você verá a viewport principal dividida em 4.
Em cada uma tem um desenho geométrico diferente. Dessa forma fica claro a forma de trabalhar com várias janelas de exibição ao mesmo tempo.
Com essa técnica de viewports podemos incrementar em nosso jogo um espelho retrovisor, mini-mapa, radar, janela...etc. A imaginação e as aplicações são infinitas...
Se houver alguma dúvida vamos movimentar o fórum.