Conheça a iniciativa da Biblioteca dos Desenvolvedores  
Índice da Biblioteca  
Área dos Usuários  
Fórum de Discussão  
Forúm
 
  38 - Extruturando um Objeto 3D

Até aqui estivemos aprendendo como desenhar pontos, um triângulo e um quadrado nas 3 coordenadas do mundo 3D.
Apartir deste tutorial, iremos demonstrar como criar realmente a extrutura de um objeto 3D.

Iremos aprender como, a partir de um triangulo, criar uma Tetraedro 3D ( a pirâmide é um poliedro ) e como, a partir de um quadrado, criar um cubo 3D.

A primeira coisa que precisamos ter em mente é, como é um objeto em 3D.

Um cubo em 3D tem a seguinte representação gráfica:

Os pontos rosas, são os nossos conhecidos pontos, ou vértices.
Em programas de modelagem 3D esses pontos também podem ser chamados de Meshes ou Vertex.

Como estudamos no capítulo 34 o parâmetro GL_QUADS imprime um quadrado na tela sempre que o quarto ponto é desenhado.
Esse quadrado que é mostrado pela OpenGL é chamado de Face.

Na figura acima, precisamos conseguir identificar, quantas faces tem um cubo:

 

 

Com isto, chegamos a conclusão de que, teremos que imprimir 6 quadrados, sendo que cada um deles vai ter 4 pontos.
Agora, vamos tentar identificar quantas faces tem um Tetraedro:


 

Como estudamos no capítulo 34 o parâmetro GL_TRIANGLES imprime um triangulo na tela sempre que o terceiro ponto é desenhado.
Esse triangulo que é mostrado pela OpenGL é chamado também de Face.

Agora precisamos identificar em quais coordenadas iremos imprimir cada ponto. E isso não é muito fácil.
No caso do Cubo 3D é mais fácil, já que as coordenas são exatas.
Agora, entender as coordenadas do triangulo é uma tarefa um pouco complicada.

Para escrever o Cubo eu irei criar uma primeira face da mesma forma que vinhemos criando até aqui:

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 );

Observe que os pontos estão posicionados a 0.30 pontos de distancia entre si.
Certo, esta é a face da frente, para fazer a face de traz, basta adicionar 0.30 para a coordenada Z também.

// face de traz
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 );

Beleza, acredito que tenha ficado fácil de entender agora. Mais esta é a primeira vez que usamos a coordenada Z.
Estamos tentando apresentar os pontos bases da OpenGL separadamente para que você não se confunda na leitura.

Usando o programa base, para fazer o cubo 3d, teremos o seguinte programa abaixo:

 


CÓDIGO...
// Exemplo de Cubo3D usando Allegro e AllegroGL - exemplo não completo
// Autor: Adriano Waltrick
// BDJogos
// Data: 09/10/2007

#include <allegro.h>
#include <alleggl.h>

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_MODELVIEW);
   glLoadIdentity();
   glFrustum(-1.0, 1.0, -1.0, 1.0, 1, 60.0);


   glLoadIdentity();

   // Angulo para fazer o quadrado girar
   GLfloat   angulo;   
   angulo = 0.0f;
   
   // Laço principal
   while( !key[KEY_ESC] )
   {

      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
      glLoadIdentity();
      
      // 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...

Você vai perceber que o resultado do programa é meio estranho..
É meio que um cubo 3D renderizado errado, mostrando cores de fundo sobrepostas pelas cores de cima,
e outra horas como se as cores de cima fossem incolor. Um resultado bem estranho.

Isto está acontecendo por que precisamos configurar o OpenGL para aceitar as declarações de profundidade.

Os comandos que usaremos para configurar a OpenGL serão estes:

void glShadeModel(GLenum mode);

Especifica a técnica de sombreamento usada na hora da renderização.

Por padrão, a OpenGL interpola as cores dos objetos primitivos na hora da impressão na tela.
Por isso aconteceu o resultado da imagem acima.

Este modo pode habilitar duas opções:

GL_FLAT
Este modo escolhe a cor de uma vértice e traibui a todos os pixels ao seu lado.

GL_SMOOTH
É praticamente a mesma coisa que o Flat, porém mais suavisado.

Independente do modo escolhido, as cores podem ser alteradas dependendo do tipo de iluminação ( ainda não estamos usando );


 

void glClearDepth(GLclampd depth);

Especifica um valor que será usado pela função glClear para limpar o buffer de profundidade ( depth buffer ).
Os valores podem ser 0 e 1



 

void glEnable(GLenum cap);

Esta função serve para habilitar várias funcionalidades da OpenGL

GL_DEPTH_TEST

Quando ativamos este parâmetro, a OpenGL poderá fazer comparações de profundade,
atualizando assim o buffer de profundidade ( depth buffer ).

No manual da OpenGL está escrito que,
mesmo tentando dizer que a profundidade é maior que zero,
o sistema de profundidade não vai funcionar se o parâmetro GL_DEPTH_TEST não estiver habilitado.



 

void glDepthFunc(GLenum func);

Esta função espeficica qual será a função de comparação usada para especificar o sistema de profundidade.
As funções que podem ser escolhidas são:

GL_NEVER
Nunca será comparado

GL_LESS
Sera comparado somente se o valor passado for menor que o valor antigo

GL_EQUAL
Sera comparado somente se o valor passado for igual ao valor antigo

GL_LEQUAL
Sera comparado se o valor passado for igual ou menor que o valor antigo

GL_GREATER
Sera comparado se o valor de profundidade passado for maior que o valor de profundidade antigo

GL_NOTEQUAL
Compara qualquer valor que não for igual ao valor antigo

GL_GEQUAL
Compara se o valor for maior ou igual ao antigo

GL_ALWAYS
Sempre compara



 

void glHint(GLenum target, GLenum mode);

Especifica o modo de comportamento de alguma função/objeto ( no prototipo da função, é o Glenum target ).

Esta função será usada no nosso exemplo para melhorar a forma de renderização.

Iremos passar o seguinte parâmetro para a função:

GL_PERSPECTIVE_CORRECTION_HINT

Indica qual a qualidade das cores, texturas e nublado ( fumaça ).

Quanto maior a qualidade, mais lento será a aplicação.
Iremos usar a qualidade GL_NICEST.

GL_NICEST
A melhor qualidade de gráficos do OpenGL.



 

Com todas essas funções e parâmetros, teremos definido as seguintes linhas no nosso programa:

glShadeModel( GL_SMOOTH );

// Faz a OpenGL aceitar profunidade
glClearDepth( 1.0f );
glEnable( GL_DEPTH_TEST );
glDepthFunc(GL_LEQUAL);

// Maior qualidade nos gráficos
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

 

Veja o código acima implementado no novo programa e seu resultado:


CÓDIGO...
// Exemplo de Cubo3D usando Allegro e AllegroGL - exemplo completo
// Autor: Adriano Waltrick
// BDJogos
// Data: 09/10/2007

#include <allegro.h>
#include <alleggl.h>

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_MODELVIEW);
   glLoadIdentity();
   glFrustum(-1.0, 1.0, -1.0, 1.0, 1, 60.0);


   glShadeModel( GL_SMOOTH );

   // Faz a OpenGL aceitar profunidade
   glClearDepth( 1.0f );
   glEnable( GL_DEPTH_TEST );
   glDepthFunc(GL_LEQUAL);

   // Maior qualidade nos gráficos
   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

   glLoadIdentity();

   // Angulo para fazer o quadrado girar
   GLfloat   angulo;   
   angulo = 0.0f;
   
   // Laço principal
   while( !key[KEY_ESC] )
   {

      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
      glLoadIdentity();
      
      // 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...

Tá ai.. o Cubo Perfeito..e girando ( por favor, compilem o exemplo ).

Agora, vamos configurar e executar o mesmo programa usando o glut!


CÓDIGO...

// Exemplo de Cubo3D usando GLUT - exemplo completo
// Autor: Adriano Waltrick
// BDJogos
// Data: 09/10/2007

#include <GL/glut.h>
#include <stdlib.h>

// Prototipos das funções que serão chamadas pela Glut ( Callback )
static void display(void);
static void key(unsigned char key, int x, int y);
static void idle(void);
static void resize(int width, int height);

// Angulo para fazer o quadrado girar
GLfloat angulo;
// Main padrão, o programa inicia aqui

int main(int argc, char *argv[])
{
   glutInit(&argc, argv);
   glutInitWindowSize(640,480);
   glutInitWindowPosition(10,10);
   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
   
   glutCreateWindow("Programa Base");
   
   ::angulo = 0.0f;
   
   // callbacks
   glutReshapeFunc(resize);
   glutDisplayFunc(display);
   glutKeyboardFunc(key);
   glutIdleFunc(idle);
   
   
   glClearColor(0,0,0,0);
   glutMainLoop();
   
   return EXIT_SUCCESS;
}

// Função que é chamada quando a janela é redimencionada
static void resize(int width, int height)
{
   const float ar = (float) width / (float) height;
   
   glViewport(0, 0, width, height);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
   
      
   
   glShadeModel( GL_SMOOTH );
   
   // Faz a OpenGL aceitar profunidade
   glClearDepth( 1.0f );
   glEnable( GL_DEPTH_TEST );
   glDepthFunc(GL_LEQUAL);
   
   // Maior qualidade nos gráficos
   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
   
   glLoadIdentity();
}

// Função que é chamada quando for preciso mostrar ou atualizar a tela
static void display(void)
{
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   
   glLoadIdentity();
   
   // 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();
   
   ::angulo += 0.2f;
   
   glutSwapBuffers();
}

// Função que é chamada quando uma tecla é apertada
static void key(unsigned char key, int x, int y)
{
   switch (key)
   {
      // caso aperte ESC
      case 27 :
      exit(0);
      break;
   }
   
   glutPostRedisplay();
}
   
// Função que executa rotinas padrões da Glut
static void idle(void)
{
   glutPostRedisplay();
}

FIM DE CÓDIGO...

 

Certo.. conseguimos fazer o quadrado.
Para fazer o Tetraedo, funciona da mesma maneira.

O único problema é, achar os pontos 3D do Tetraedo, o que pode dificultar um pouco.

A primeira coisa que devemos fazer é criar um triângulo no chão e achar o seu centro.
O centro dele será o topo do poliedro. E nós sabemos que o centro está na metade dos 2 pontos de baixo.

Eu optei por iniciar como nos outros programas antigos, tendo a frente como referência para a primeira face.

Observe que eu usei muito como referencia o ponto mais alto do triângulo da primeira face que é 0.15.
Tende desenhar no papel para tentar visualizar o triangulo em 3D.. Desenhando um triangulo, crie um ponto bem no centro dele, ele será o
ponto mais alto do Tetraedo.

Use o código abaixo nos displays para ver o resultado:

 

glBegin(GL_TRIANGLES);

// Face da Frente do triângulo, que acaba se tornando a base
glColor3f( 255, 0 , 0 );
glVertex3f( 0.00, 0.00, 0.00 );
glVertex3f( 0.30, 0.00, 0.00 );
glVertex3f( 0.15, 0.30, 0.00 );

// Face de baixo baixo
glColor3f( 0, 255 , 0 );
glVertex3f( 0.00, 0.00, 0.00 );
glVertex3f( 0.30, 0.00, 0.00 );
glVertex3f( 0.15, 0.15, 0.30 );

// Face da Esquerda
glColor3f( 0, 0 , 255 );
glVertex3f( 0.00, 0.00, 0.00 );
glVertex3f( 0.15, 0.30, 0.00 );
glVertex3f( 0.15, 0.15, 0.30 );

// Face da Direita
glColor3f( 255, 255 , 255 );
glVertex3f( 0.30, 0.00, 0.00 );
glVertex3f( 0.15, 0.30, 0.00 );
glVertex3f( 0.15, 0.15, 0.30 );

glEnd();

 

DICA...

Para deixar o código mais fácil de ler e de forma organizada, estou usando 2 cadas após a virgula.
Da seguinte forma "0.00" quando estivermos trabalhando com valores do estilo 0.10 ou 0.35.

Isto faz com que o código não fique desorganizado.
Quanto mais organizado o código, melhor será para lê-lo e alterá-lo.

 

 

Exemplo aplicado no AllegroGL


CÓDIGO...
// Exemplo de Tetraedro usando Allegro e AllegroGL - exemplo completo
// Autor: Adriano Waltrick
// BDJogos
// Data: 09/10/2007

#include <allegro.h>
#include <alleggl.h>

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_MODELVIEW);
   glLoadIdentity();
   glFrustum(-1.0, 1.0, -1.0, 1.0, 1, 60.0);


   glShadeModel( GL_SMOOTH );

   // Faz a OpenGL aceitar profunidade
   glClearDepth( 1.0f );
   glEnable( GL_DEPTH_TEST );
   glDepthFunc(GL_LEQUAL);

   // Maior qualidade nos gráficos
   glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

   glLoadIdentity();

   // Angulo para fazer o quadrado girar
   GLfloat   angulo;   
   angulo = 0.0f;
   
   // Laço principal
   while( !key[KEY_ESC] )
   {

      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      
      glLoadIdentity();
      
      // função de rotação, estamos rotacionando em todos os ângulos
      glRotatef(angulo, 1.0f, 1.0f, 1.0f );               
      
      
      

      glBegin(GL_TRIANGLES);       

      // Face da Frente do triângulo, que acaba se tornando a base
      glColor3f( 255, 0 , 0 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.30, 0.00, 0.00 );
      glVertex3f( 0.15, 0.30, 0.00 );

      // Face de baixo baixo
      glColor3f( 0, 255 , 0 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.30, 0.00, 0.00 );
      glVertex3f( 0.15, 0.15, 0.30 );

      // Face da Esquerda
      glColor3f( 0, 0 , 255 );
      glVertex3f( 0.00, 0.00, 0.00 );
      glVertex3f( 0.15, 0.30, 0.00 );
      glVertex3f( 0.15, 0.15, 0.30 );

      // Face da Direita
      glColor3f( 255, 255 , 255 );
      glVertex3f( 0.30, 0.00, 0.00 );
      glVertex3f( 0.15, 0.30, 0.00 );
      glVertex3f( 0.15, 0.15, 0.30 );
      
      glEnd();



      // imprime tudo
     allegro_gl_flip();
   
     angulo += 0.2f;

  }

  allegro_exit();

  return 0;
}
END_OF_MAIN();

FIM DE CÓDIGO...

Uma das possíveis saídas do programa:

Download do exemplo 1 - Allegro - Clique Aqui

Download do exemplo 1 - Glut - Clique Aqui

Download do exemplo 2 - Allegro - Clique Aqui

Download do exemplo 3 - Allegro - Clique Aqui

 


Contribuidor
Adriano Waltrick
09/10/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.