Computação Gráfica
OpenGL 3D
O objetivo desta aula é aprender como trabalhar com a
visualização 3D em OpenGL.
Para
isto, é necessário compreender como são utilizadas as funções de projeção e
manipulação da câmera em OpenGL.
Quando estamos trabalhando em 3D, é
necessário considerar que a OpenGL trabalha com dois sistemas de coordenadas.
O primeiro deles, no qual se monta o cenário,
também chamado de SRU(Sistema de Referência do Universo) é um sistema de mão
direita, no qual o eixo X, representado pelo polegar, cresce para direita, o Y,
representado pelo indicador, cresce para cima e o eixo Z cresce alinhado com o
dedo maior, perpendicular ao plano XY.
A figura a seguir demonstra a relação dos eixos com os dedos da mão direita.
Figura - Sistema de Coordenadas de Mão Direita
O segundo sistema de coordenadas é o Sistema de Coordenadas da Câmera(SRC), que é um sistema de mão esquerda. Neste sistema
o observador está ponto (0,0,0) e está olhando na direção do eixo Z,
representado também pelo dedo maior. O eixo X é representado pelo polegar e
cresce para direita. Já o eixo Y, representado pelo indicador, cresce para
cima.
A figura a seguir demonstra a relação dos eixos com os dedos
da mão esquerda.
Figura - Sistema de Coordenadas de Mão Esquerda
Observe
a função display e veja como são posicinados dois
cubos que compõem o cenário.
glPushMatrix();
glTranslatef
( 5.0f, 0.0f, 3.0f );
glRotatef(AngY,0,1,0);
glColor3f(0.5f,0.0f,0.0f); //
Vermelho
DesenhaCubo();
glPopMatrix();
glPushMatrix();
glTranslatef
( -4.0f, 0.0f, 2.0f );
glRotatef(AngY,0,1,0);
glColor3f(0.0f,0.6f,0.0f); // Azul
DesenhaCubo();
glPopMatrix();
A imagem a seguir mostra a vista superiror
deste cenário. Procure desenhar as vistas frontal, lateral direita e superior
da cena, considerando um sistema de coordenadas de mão direita.
Figura - Vista Superior do Cenário
Para setar os parâmetros que definem o observador, veja a função
PosicUser.
Inicialmente, define-se o tipo de projeção e com ele o volume de visualização.
Para uma projeção Paralela Ortográfica, deve-se informar os limites em X,Y e Z do volume de visualização, medindo-se sempre a
partir da posição do observador. A função para esta tarefa a glOrtho. A figura a seguir demonstra a saída
do programa.
Figura - Cenário gerado com Projeção Paralela Ortográfica
Para uma projeção Perspectiva,
usa-se a função gluPerspective na qual deve-se informa:
A
figura a seguir demonstra a saída do programa.
Figura - Cenário gerado com Projeção Paralela Ortográfica
Como estes parâmetros são ligados ao processo de projeção, a matriz
ativa deve ser PROJECTION. Esta ativação é feita através da função glMatrixMode(GL_PROJECTION).
Já a posição do observador é definida pela função gluLookAt, que permite setar a posição do
observador, o alvo e o eixo vertical do universo.
//
**********************************************************************
// void PosicUser()
// **********************************************************************
void PosicUser()
{
// Define os parâmetros da projeção Perspectiva
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Define o volume de
visualização sempre a partir da posicao do
// observador
if (ModoDeProjecao
== 0)
glOrtho(-10,
10, -10, 10, 0, 20); // Projecao paralela Orthografica
else gluPerspective(90,AspectRatio,0.01,200);
// Projecao perspectiva
// Define a posição do
observador
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0,
10, // Posição do Observador
0,0,0, // Posição do Alvo
0.0f,1.0f,0.0f); // Lado de cima da câmera
}
Para exercitar, altere a posição do observador,
controlando seu movimento com teclas.
Lembre-se que o resultado que aparece na tela está o sistema
de referência da câmera, que é de mão esquerda.
Monte
um cenário com um piso e alguns objetos espalhados sobre este piso.
Remova o código que desenha o cubo coloque a chamada de uma
das funções abaixo:
void glutWireTeapot(float size)
void glutWireCube(float
size);
void glutWireSphere(double radius, int slices, int
stacks);
void glutWireCone(double
base, double height, int slices, int
stacks);
void glutWireTorus(double
innerRadius, double outerRadius, int nsides, int rings);
void glutWireIcosahedron();
void glutWireOctahedron();
void glutWireTetrahedron();
void glutSolidDodecahedron().
Veja nesta página sugestões de como mover o observador de OpenGL.
FIM.