Conheça a iniciativa da Biblioteca dos Desenvolvedores  
Índice da Biblioteca  
Área dos Usuários  
Fórum de Discussão  
Forúm
 
  41 - Entendendo o sistema de Câmera

Este é um dos capítulos mais difíceis de se entender.
Após aprender as trasnformações do plano devemos ser capazes de modificar nosso plano de visão ( nossa câmera ).

- A câmera aponta para ( foca ) o que estamos vendo na cena.

Para movimentar a câmera devemos fazer trasnformações ( glRotate, glTranslate ). A chave destas transformações são duas matrizes da OpenGL.
As trasnformações tornam possíveis projeções 3D em coordenadas 2D de nossa tela.

A OpenGl nos fornece 3 tipos de transformações:

1 - De visão

Especifica principalmente a localização da camera.
Também é responsável por aumentar ou diminuir a área aonde pode ser desenhado.

2 - De Modelagem

Movimenta os objetos pela cena e descreve as transformações


3 - De Projeção

Especifica as rederizações e o tamanho das impressões de tela

Neste capítulo iremos aprender como modificar o sistema de coordenadas salvando o sistema de coordenadas original.
Para isto usamos o comando glPushMatrix(); e glPopMatrix();

void glPushMatrix(void); e void glPopMatrix(void);

glPushMatrix armazena a matriz atual.
glPopMatrix retira da memória a matriz e da um replace na matriz atual.

Usando esses 2 comandos podemos rotacionar ( ou transformar em qualquer sentido ) o plano sem mexer no antigo plano que já pode ter sido rotacionado( ou transformado ) de alguma maneira.

 

Transformações de Visão - Viewing Transformations

Primeiro precisamos entender nosso pontos de vista real no plano cartesiano.
Isto deve estar bem claro para a gente que já está programando em OpenGL..

Olhando para o monitor, estamos em linha reta ao eixo Z e a 90 graus do eixo X e Y.


A transformação de visualização é a primeira a ser realizada, pois ela determina a posição da cena.
A posição de origem da cena na OpenGL é ( 0,0,0 ).

Usando a transformação de visão podemos colocar o ponto de observação aonde a gente precisa que ele esteja, e apontando para a direção aonde a gente quiser ( Imagine a camera de Resident Evil ).

É determinando uma transformação de visão que inserimos uma câmera em algum ponto de nosso mundo 3D.

 

Transformações de Modelagem - Modeling Transformations

É basicamente o que fizemos no capitulo 40, onde manipulamos um objeto em particular.

Com este tipo de transformação podemos rotacionar, aumentar ou diminuir e movimentar objetos.

 

Transformações de Projeção - Projection Transformations

É a última transformação aplicada que serve para orientar a visualização da cena.

Como já vimos, existem dois tipos de projeção, a ortográfica e a perspectiva.
Na projeção ortográfica, todos os poligonos são desenhados na tela relativo ao tamanho da tela.

Na projeção perspectiva vemos os objetos como se simula-se a visão da vida real, para o horizonte...
Na projeção perspectiva, os objetos mais longe são menores do que os objetos que estão mais próximos.

Em nossos jogos com certeza iremos usar a Projeção Perspectiva.

Exemplo de Projeção Ortográfica do Blender 3D:

Na imagem abaixo vemos um plano com um cubo. Observe que as linhas de fundo do programa estão sempre no mesmo angulo.

Exemplo de Projeção Perspectiva do Blender 3D:

Observe que esta projeção é como o nosso olho vê.. voltada ao horizonte.


 

Usando a Matriz de Projeções

Podemos ir alterando as matrizes de modelagem e projeção selecionando elas antes.
Por exemplo:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

Todas as modificações serão feitas na matriz de Modelview.

Desde os primeiros capítulos sobre OpenGL vinhemos usando a projeção Ortogonal.
Isto por que a OpenGL não nos fornece os ajustes necessários para escalonamentos e perspectivas,
sendo que nós mesmos teremos que fazer isto.

Para criar um sistema de projeção perspectiva, precisamos usar um Frustum ( A área em que a câmera está apontando ( no caso, visualizando ) é conhecida como frustum )...

Imagem do Frustum:

A função que contrala o frustum nós já conhecemos:

void glFrustum( left, right, bottom, top, nearVal, farVal);

Com a AllegroGL podemos controlar apenas o glFrustum.

No AllegroGL não existe função de controle de ângulo de câmera, só existe a função glFrustum do OpenGL.. então,
em AllegroGL podemos mexer a câmera, mais não podemos alterar o ângulo de visão.

Na própria OpenGL não existe essa função.


Com o GLUT temos 2 outras funções muito interessantes para trabalhar com a câmera:

void gluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
Observe que tem quase os mesmos parametros do glFrustum.
Esse comando posiciona a camera perspectivamente ao angulo definido em fovy

void gluLookAt( GLdouble eyeX, GLdouble eyeY, GLdouble eyeZ, GLdouble centerX, GLdouble centerY, GLdouble centerZ, GLdouble upX, GLdouble upY, GLdouble upZ);
Define uma transformação da Câmera.
Transformando a camera, posicionamos ela mais fácilmente.

No exemplo abaixo temos um programa relativamente simples.
Neste programa em AllegroGL criei uma struct CAMERA que terá todos os valores de configuração da câmera para o próximo exemplo.

Eu iniciei a câmera com os seguintes valores.. é muito importante observar isto muito bem:

   cam.left = -01.0f;
   cam.right = 01.0f;
   cam.top = 01.0f;
   cam.bottom = -01.0f;
   cam.vnear = 01.0f;
   cam.vfar = 10.0f;

Observe que a câmera está olhando exatamente para os eixos iniciais da OpenGL.
Apenas vnear e vfar está com valores diferentes pois eles indicam a profundidade da cena.

Nossa profundidade começará em 1.0f ( Inicio da tela ) e terminará em 10.0f ( Fundo da tela );

Usando as Teclas A e Z o objeto é translocado para a nova posição criando um sistema de zoom perfeito.

Observe que para fazer isto também tivemos que alterar nossa iniciação da câmera:

Ao invez de iniciar a câmera com Modelview, iniciamos ela com Projection

glMatrixMode(GL_PROJECTION);
glLoadIdentity();


CÓDIGO...
// Exemplo de Zoom com AllegroGL sem funções especiais do GLUT
// Autor: Adriano Waltrick
// BDJogos
// Data: 22/11/2007

#include <allegro.h>
#include <alleggl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

struct CAMERA
{
   GLfloat left, right;
   GLfloat top, bottom;
   GLfloat vnear, vfar;
};

int main()
{
   // Iniciações básicas da Allegro
   allegro_init();
   install_keyboard();
   
   // Iniciação da AllegroGL
   install_allegro_gl();
   
   allegro_gl_set(AGL_Z_DEPTH, 8);
   allegro_gl_set(AGL_COLOR_DEPTH, 16);
   allegro_gl_set(AGL_SUGGEST, AGL_Z_DEPTH | AGL_COLOR_DEPTH);
   
   // Setando o Modo Gráfico
   set_gfx_mode(GFX_OPENGL_WINDOWED, 640, 480, 0, 0);
   
   
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
   // Iniciando a camera
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   
   CAMERA cam;
   cam.left    = -01.0f;
   cam.right   = 01.0f;
   cam.top     = 01.0f;
   cam.bottom  = -01.0f;
   cam.vnear   = 01.0f;
   cam.vfar    = 10.0f;
   
   glFrustum( cam.left, cam.right, cam.bottom, cam.top, cam.vnear, cam.vfar );
   
   
   glShadeModel( GL_SMOOTH );
   glClearDepth( 1.0f );
   glEnable( GL_DEPTH_TEST );
   glDepthFunc(GL_LEQUAL);
   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
   
   
   // Iniciando matrix de objetos
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   
   glEnable(GL_TEXTURE_2D);
   FONT *agl_font = NULL;
   agl_font = allegro_gl_convert_allegro_font(font, AGL_FONT_TYPE_TEXTURED, 250.0f);
   
   // Aplicação do Zoom
   int Buffer_teclado = 0;
   GLfloat posicao_z = -1.0f;
   
   // para o quadrado girar
   GLfloat angulo;
   angulo = 0.0f;
   
   
   // Laço principal
   while( !key[KEY_ESC] )
   {
   
      if (Buffer_teclado == 0)
      {
      
         // Aumenta zoom
         if ( key[KEY_A] )
         {
            posicao_z += 0.1f;
            Buffer_teclado = 20;
         }
         
         // Diminui zoom
         if ( key[KEY_Z] )
         {
            posicao_z -= 0.1f;
            Buffer_teclado = 20;
         }          
         
      }
      else
      {
         Buffer_teclado -= 1;
      }
      
      
      
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
      glLoadIdentity();
      
      glLoadIdentity();
      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      allegro_gl_printf(agl_font, 0, 0.50, -1.01f, makecol( 000, 255, 000), "Valor %f", posicao_z );
      
      
      
      // Adiciona posição Z ao objeto
      glTranslatef( 0, 0, posicao_z );
      
      // função de rotação, estamos rotacionando em todos os ângulos
      glRotatef(angulo, 1.0f, 1.0f, 1.0f );
      
      
      glBegin(GL_QUADS);
      
      // face da frente
      glColor3f( 255, 0 , 0 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.00, 0.30, 0.00 );
      glVertex3f( 0.30, 0.30, 0.00 );
      glVertex3f( 0.30, 0.00, 0.00 );
      
      
      // face de traz
      glColor3f( 0, 255 , 0 );
      glVertex3f( 0.00, 0.00, 0.30 );
      glVertex3f( 0.00, 0.30, 0.30 );
      glVertex3f( 0.30, 0.30, 0.30 );
      glVertex3f( 0.30, 0.00, 0.30 );
      
      // face de cima
      glColor3f( 255, 255 , 255 );
      glVertex3f( 0.00, 0.30, 0.00 );
      glVertex3f( 0.00, 0.30, 0.30 );
      glVertex3f( 0.30, 0.30, 0.30 );
      glVertex3f( 0.30, 0.30, 0.00 );
      
      // face de baixo
      glColor3f( 255, 255 , 0 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.00, 0.00, 0.30 );
      glVertex3f( 0.30, 0.00, 0.30 );
      glVertex3f( 0.30, 0.00, 0.00 );
      
      // face da esquerda
      glColor3f( 0, 0, 255 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.00, 0.30, 0.00 );
      glVertex3f( 0.00, 0.30, 0.30 );
      glVertex3f( 0.00, 0.00, 0.30 );
      
      // face da direita
      glColor3f( 255, 0, 255 );
      glVertex3f( 0.30, 0.00, 0.00 );
      glVertex3f( 0.30, 0.30, 0.00 );
      glVertex3f( 0.30, 0.30, 0.30 );
      glVertex3f( 0.30, 0.00, 0.30 );
      
      
      glEnd();
      
      // imprime tudo
      allegro_gl_flip();
      
      angulo += 0.2f;
   
   }
   
   allegro_exit();
   
   return 0;
}
END_OF_MAIN();


FIM DE CÓDIGO...

Execute o programa acima.

Agora preste muita atenção a alguns resultados:

1 - Quando iniciamos o programa, a imagem que aparece é a seguinte:

Isto está acontecendo por que o quadrado está posicionado da seguinte maneira:

Observe que a visão da camera começa em 1.0, e por isso ela não consegue mostrar todo o quadrado

2 - Se precionarmos Z, o Zoom será diminuido:

Neste ponto, o quadrado está dentro da visão de nossa camera

Se precionarmos muito a tecla Z até o valor chegar a -10.1 , o quadrado não irá mais aparecer na tela, pois ele chegou no limite da visão especificado para nossa câmera.

 

No código abaixo, vamos fazer a movimentação da visão da câmera.
Quando forem apertadas as teclas direcionais, a câmera irá se mover ( observe que, não é o quadrado que se move );

Para isso, temos que novamente voltar a trabalhar com a matrix de projeção.


CÓDIGO...

// Exemplo de Zoom com AllegroGL sem funções especiais do GLUT
// Autor: Adriano Waltrick
// BDJogos
// Data: 22/11/2007

#include <allegro.h>
#include <alleggl.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

struct CAMERA
{
   GLfloat left, right;
   GLfloat top, bottom;
   GLfloat vnear, vfar;
};

int main()
{
   // Iniciações básicas da Allegro
   allegro_init();
   install_keyboard();
   
   // Iniciação da AllegroGL
   install_allegro_gl();
   
   allegro_gl_set(AGL_Z_DEPTH, 8);
   allegro_gl_set(AGL_COLOR_DEPTH, 16);
   allegro_gl_set(AGL_SUGGEST, AGL_Z_DEPTH | AGL_COLOR_DEPTH);
   
   // Setando o Modo Gráfico
   set_gfx_mode(GFX_OPENGL_WINDOWED, 640, 480, 0, 0);
   
   
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
   // Iniciando a camera
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   
   CAMERA cam;
   cam.left = -01.0f;
   cam.right = 01.0f;
   cam.top = 01.0f;
   cam.bottom = -01.0f;
   cam.vnear = 01.0f;
   cam.vfar = 10.0f;
   
   glFrustum( cam.left, cam.right, cam.bottom, cam.top, cam.vnear, cam.vfar );
   
   // Iniciando matrix de objetos
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glShadeModel( GL_SMOOTH );
   glClearDepth( 1.0f );
   glEnable( GL_DEPTH_TEST );
   glDepthFunc(GL_LEQUAL);
   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
   
   glEnable(GL_TEXTURE_2D);
   FONT *agl_font = NULL;
   agl_font = allegro_gl_convert_allegro_font(font, AGL_FONT_TYPE_TEXTURED, 250.0f);
   
   // Aplicação do Zoom
   int buffer_teclado = 0;
   GLfloat posicao_z = -3.0f;
   
   // para o quadrado girar
   GLfloat angulo;
   angulo = 0.0f;
   
   
   // Laço principal
   while( !key[KEY_ESC] )
   {
   
      if (buffer_teclado == 0)
      {
      
         // Aumenta zoom
         if ( key[KEY_A] )
         {
            posicao_z += 0.1f;
            buffer_teclado = 20;
         }
   
         // Diminui zoom
         if ( key[KEY_Z] )
         {
            posicao_z -= 0.1f;
            buffer_teclado = 20;
         }
   
         if ( key[KEY_UP] )
         {
            cam.top -= 0.1f;
            cam.bottom -= 0.1f;
            buffer_teclado = 10;
         }
   
         if ( key[KEY_DOWN] )
         {
            cam.top += 0.1f;
            cam.bottom += 0.1f;
            buffer_teclado = 10;
         }
   
         if ( key[KEY_LEFT] )
         {
            cam.left += 0.1f;
            cam.right += 0.1f;
            buffer_teclado = 10;
         }
   
         if ( key[KEY_RIGHT] )
         {
            cam.left -= 0.1f;
            cam.right -= 0.1f;
            buffer_teclado = 10;
         }
   
         if ( buffer_teclado == 10 )
         {
            // Iniciando a camera
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glFrustum( cam.left, cam.right, cam.bottom, cam.top, cam.vnear, cam.vfar );
            
            
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
         }
      }
      else
      {
         buffer_teclado -= 1;
      }
   
   
   
   
      
      
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
      glLoadIdentity();
      
      glLoadIdentity();
      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      allegro_gl_printf(agl_font, 0, 0.50, -1.01f, makecol( 000, 255, 000), "Valor %f", posicao_z );
      
      
      
      // Adiciona posição Z ao objeto
      glTranslatef( 0, 0, posicao_z );
      
      // função de rotação, estamos rotacionando em todos os ângulos
      glRotatef(angulo, 1.0f, 1.0f, 1.0f );
      
      
      glBegin(GL_QUADS);
      
      // face da frente
      glColor3f( 255, 0 , 0 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.00, 0.30, 0.00 );
      glVertex3f( 0.30, 0.30, 0.00 );
      glVertex3f( 0.30, 0.00, 0.00 );
      
      
      // face de traz
      glColor3f( 0, 255 , 0 );
      glVertex3f( 0.00, 0.00, 0.30 );
      glVertex3f( 0.00, 0.30, 0.30 );
      glVertex3f( 0.30, 0.30, 0.30 );
      glVertex3f( 0.30, 0.00, 0.30 );
      
      // face de cima
      glColor3f( 255, 255 , 255 );
      glVertex3f( 0.00, 0.30, 0.00 );
      glVertex3f( 0.00, 0.30, 0.30 );
      glVertex3f( 0.30, 0.30, 0.30 );
      glVertex3f( 0.30, 0.30, 0.00 );
      
      // face de baixo
      glColor3f( 255, 255 , 0 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.00, 0.00, 0.30 );
      glVertex3f( 0.30, 0.00, 0.30 );
      glVertex3f( 0.30, 0.00, 0.00 );
      
      // face da esquerda
      glColor3f( 0, 0, 255 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.00, 0.30, 0.00 );
      glVertex3f( 0.00, 0.30, 0.30 );
      glVertex3f( 0.00, 0.00, 0.30 );
      
      // face da direita
      glColor3f( 255, 0, 255 );
      glVertex3f( 0.30, 0.00, 0.00 );
      glVertex3f( 0.30, 0.30, 0.00 );
      glVertex3f( 0.30, 0.30, 0.30 );
      glVertex3f( 0.30, 0.00, 0.30 );
      
      
      glEnd();
      
      // imprime tudo
      allegro_gl_flip();
      
      angulo += 0.2f;
   
   }
   
allegro_exit();

return 0;
}
END_OF_MAIN();


FIM DE CÓDIGO...

Observe que a câmera sempre está apontando para frente!

 

A situação "A" e "B" indicam como seria a movimentação da câmera....


 

Criando uma Projeção com ângulo de câmera diferenciado

Nosso próximo desafio é entender como fazer isto:

 

 


CÓDIGO...

// Exemplo de Câmera Simples com AllegroGL COM funções especiais do GLUT
// Autor: Adriano Waltrick
// BDJogos
// Data: 22/11/2007

#include <allegro.h>
#include <alleggl.h>
#include <GL/Glut.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

struct CAMERA
{
   GLfloat left, right;
   GLfloat top, bottom;
   GLfloat vnear, vfar;
   
   GLfloat x, y, z;
   GLfloat lookx, looky, lookz;
};

int main()
{
   // Iniciações básicas da Allegro
   allegro_init();
   install_keyboard();
   
   // Iniciação da AllegroGL
   install_allegro_gl();
   
   allegro_gl_set(AGL_Z_DEPTH, 8);
   allegro_gl_set(AGL_COLOR_DEPTH, 16);
   allegro_gl_set(AGL_SUGGEST, AGL_Z_DEPTH | AGL_COLOR_DEPTH);
   
   // Setando o Modo Gráfico
   set_gfx_mode(GFX_OPENGL_WINDOWED, 640, 480, 0, 0);
   
   
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
   // Iniciando a camera
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   
   CAMERA cam;
   cam.left = -01.0f;
   cam.right = 01.0f;
   cam.top = 01.0f;
   cam.bottom = -01.0f;
   cam.vnear = 01.0f;
   cam.vfar = 10.0f;
   
   glFrustum( cam.left, cam.right, cam.bottom, cam.top, cam.vnear, cam.vfar );
   
   
   // Iniciando matrix de objetos
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   
   
// isto irá fazer nosso efeito de perspectiva inicial
   cam.x = 0;
   cam.y = 5;
   cam.z = 5;
   
   cam.lookx = 0;
   cam.looky = 0;
   cam.lookz = 0;
   
   
   
   
   glShadeModel( GL_SMOOTH );
   glClearDepth( 1.0f );
   glEnable( GL_DEPTH_TEST );
   glDepthFunc(GL_LEQUAL);
   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
   
   
   
   glEnable(GL_TEXTURE_2D);
   FONT *agl_font = NULL;
   agl_font = allegro_gl_convert_allegro_font(font, AGL_FONT_TYPE_TEXTURED, 250.0f);
   
   // Aplicação do Zoom
   int buffer_teclado = 0;
   GLfloat posicao_z = -2.0f;
   
   // para o quadrado girar
   GLfloat angulo;
   angulo = 0.0f;
   
   
   
   // Laço principal
   while( !key[KEY_ESC] )
   {
   
      if (buffer_teclado == 0)
      {
         // move posição do olho da camera pelo eixo Z
         if ( key[KEY_Z] )
         {
            cam.z += 0.1f;
            buffer_teclado = 10;         
         }
         
         // move posição do olho da camera pelo eixo Z
         if ( key[KEY_X] )
         {
            cam.z -= 0.1f;
            buffer_teclado = 10;
         }
   
         // move posição do olho da camera pelo eixo X
         if ( key[KEY_A] )
         {
            cam.x -= 0.1f;
            buffer_teclado = 10;
         }
         
         // move posição do olho da camera pelo eixo X
         if ( key[KEY_D] )
         {
            cam.x += 0.1f;
            buffer_teclado = 10;
         }
   
         // move posição do olho da camera pelo eixo Y
         if ( key[KEY_W] )
         {
            cam.y -= 0.1f;
            buffer_teclado = 10;
         }
         
         // move posição do olho da camera pelo eixo Y
         if ( key[KEY_S] )
         {
            cam.y += 0.1f;
            buffer_teclado = 10;
         }
   
   
   
         // Aumenta Zoom
         if ( key[KEY_Z] )
         {
            posicao_z += 0.1f;
            buffer_teclado = 20;
         }
   
         // Diminui zoom
         if ( key[KEY_X] )
         {
            posicao_z -= 0.1f;
            buffer_teclado = 20;
         }
   
         // move a camera
         if ( key[KEY_UP] )
         {
            cam.top -= 0.1f;
            cam.bottom -= 0.1f;
            buffer_teclado = 10;
         }
   
         if ( key[KEY_DOWN] )
         {
            cam.top += 0.1f;
            cam.bottom += 0.1f;
            buffer_teclado = 10;
         }
   
         if ( key[KEY_LEFT] )
         {
            cam.left += 0.1f;
            cam.right += 0.1f;
            buffer_teclado = 10;
         }
   
         if ( key[KEY_RIGHT] )
         {
            cam.left -= 0.1f;
            cam.right -= 0.1f;
            buffer_teclado = 10;
         }
   
         if ( buffer_teclado == 10 )
         {
            // atualizando a camera
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glFrustum( cam.left, cam.right, cam.bottom, cam.top, cam.vnear, cam.vfar );
            
            
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
         }
      }
      else
      {
         buffer_teclado -= 1;
      }
   
      
      
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
      glLoadIdentity();
      
      gluLookAt( cam.x, cam.y, cam.z, cam.lookx, cam.looky, cam.lookz, 0.0f, 1.0f, 0.0f);
      
      
      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      //allegro_gl_printf(agl_font, 0, 0.50, -1.01f, makecol( 000, 255, 000), "Valor %f", posicao_z );
      allegro_gl_printf(agl_font, cam.x, cam.y+1.00, cam.z-1.0f, makecol( 000, 255, 000), "Valor %f", posicao_z );
      
      
      glPushMatrix();
      // Adiciona posição Z ao objeto
      glTranslatef( 0, 0, posicao_z );
      
      
      glBegin(GL_QUADS);
      
      // face da frente
      glColor3f( 255, 0 , 0 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.00, 1.00, 0.00 );
      glVertex3f( 1.00, 1.00, 0.00 );
      glVertex3f( 1.00, 0.00, 0.00 );
      
      // face de traz
      glColor3f( 0, 255 , 0 );
      glVertex3f( 0.00, 0.00, 1.00 );
      glVertex3f( 0.00, 1.00, 1.00 );
      glVertex3f( 1.00, 1.00, 1.00 );
      glVertex3f( 1.00, 0.00, 1.00 );
      
      // face de cima
      glColor3f( 0, 0 , 255 );
      glVertex3f( 0.00, 1.00, 0.00 );
      glVertex3f( 0.00, 1.00, 1.00 );
      glVertex3f( 1.00, 1.00, 1.00 );
      glVertex3f( 1.00, 1.00, 0.00 );
      
      // face de baixo
      glColor3f( 255, 255 , 0 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.00, 0.00, 1.00 );
      glVertex3f( 1.00, 0.00, 1.00 );
      glVertex3f( 1.00, 0.00, 0.00 );
      
      // face da esquerda
      glColor3f( 0, 0, 255 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.00, 1.00, 0.00 );
      glVertex3f( 0.00, 1.00, 1.00 );
      glVertex3f( 0.00, 0.00, 1.00 );
      
      // face da direita
      glColor3f( 255, 0, 255 );
      glVertex3f( 1.00, 0.00, 0.00 );
      glVertex3f( 1.00, 1.00, 0.00 );
      glVertex3f( 1.00, 1.00, 1.00 );
      glVertex3f( 1.00, 0.00, 1.00 );
      
      
      glEnd();
      
      
      glBegin(GL_QUADS);
      
      // face de baixo
      glColor3f( 255, 255 , 0 );
      glVertex3f( -3.00, 0.00, -3.00 );
      glVertex3f( -3.00, 0.00, 3.00 );
      glVertex3f( 3.00, 0.00, 3.00 );
      glVertex3f( 3.00, 0.00, -3.00 );
      glEnd();
      
      glPopMatrix();
             
      
      
      // imprime tudo
      allegro_gl_flip();
      
      angulo += 0.2f;
   
   }
   
   allegro_exit();
   
   return 0;
}
END_OF_MAIN();


FIM DE CÓDIGO...

Saída básica do programa:

O programa acima é relativamente básico.
Usamos a função gluLookAt que possiciona a câmera e indica para aonde a câmera vai apontar.

Com as teclas ( A, W, S, D ) podemos alterar a posição da câmera.
Observe que, mesmo alterando a posição da câmera, sempre estamos olhando para o ponto 0,0,0 ( a não ser quando atualizamos o Frustum ).

É muito importante entender isto.
Por exemplo, se você manter precionado a tecla A, a cena vai vir cade vez mais próxima da tela, até se inverter.

Isto acontece por que a camera nunca para de olhar para o mesmo ponto, e é ela quem está se movendo. E ela inverte por que possívelmente seus pontos ficaram negativos.

O exemplo acima pode ser fácilmente aplicado ao GLUT.

VOCÊ PRECISA SABER...

Como no exemplo, a função gluLookAt não deve ser aplicada na matrix projetiva!!!

Preste muita atenção na forma de iniciação da câmera, isto é muito importante:

   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
       
   
   glFrustum( cam.left, cam.right, cam.bottom, cam.top, cam.vnear, cam.vfar );
       
   
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   

    // Demais alterações no mundo 3D, gluLookAt trabalha aqui

Observe que fizemos também uso das funções glPushMatrix(); e glPopMatrix();
Usamos essas funções para que as alterações de câmera não interferisem diretamente em nosso posicionamento de objetos.

Ainda não aprendemos tudo sobre câmeras em OpenGL :)

 

Download do exemplo 1 - Allegro - Clique Aqui

Download do exemplo 2 - Allegro - Clique Aqui

Download do exemplo 3 - Allegro - Clique Aqui


Contribuidor
Adriano Waltrick
23/11/2007


 

« Anterior

 

Próximo »

 
 

01/06/2007 (C) Copyright. Todos os Direitos Reservados. Leia a política de privacidade do portal.
É proibida a cópia de conteúdo deste site de acordo com a Lei Brasileira de Direitos Autorais.