Exercício III

Disciplina: Computação Gráfica
Professora: Soraia R. Musse

 

 Aula prática – Câmera e Projeção

 

O objetivo desta aula é aprender como trabalhar com a visualização 3D em OpenGL.

Clicando aqui, você pode obter os códigos fontes que serão utilizados na aula de hoje.

 

Inicialmente, verifique o conteúdo do programa fonte fornecido.
O método gluLookAt(0.0,80.0,200.0, 0.0,0.0,0.0, 0.0,1.0,0.0); define a câmera, isto é, através dos seus argumentos
é possível indicar a posição da câmera e para onde ela está direcionada.


Sua assinatura é: void gluLookAt(double eyeX, double eyeY, double eyeZ, double centerX, double centerY, double centerZ, double upX, double upY, double upZ).
Os parâmetros: eyex, eyey e eyez são usados para definir as coordenadas x, y e z, respectivamente, da posição da câmera (ou observador);
centerx, centery e centerz são usados para definir as coordenadas x, y e z, respectivamente, da posição do alvo, isto é para onde o observador está
olhando (normalmente, o centro da cena); upx, upy e upz são as coordenadas x, y e z, que estabelecem o vetor up (indica o "lado de cima" de uma cena 3D) [Wright 2000].

Agora altere o parâmetro upy para -1 e veja o que acontece com o teapot. Depois, atribua o valor 1 para upy novamente. Em seguida, altere o parâmetro eyez para 100, compile e visualize o resultado. Depois altere este mesmo parâmetro para 300, compile e visualize o resultado novamente. Na seqüência, passe o valor 200 para este parâmetro. Altere o parâmetro centerx para 20, compile e execute o programa. Agora altere este mesmo parâmetro para -20, compile e execute o programa.

Considerando as alterações feitas, e a teoria estudada em aula, pense em que consiste alterar os parâmetros eyex, eyey, eyez, centerx, centery e centerz.

Agora crie um método TeclasEspeciais (não esqueça do callback no main) e inclua os comandos abaixo.

...

 

switch (key)

    {

        case GLUT_KEY_LEFT: obsX -=10;

                            break;

 

        case GLUT_KEY_RIGHT: obsX +=10;

                             break;

 

        case GLUT_KEY_UP: obsY +=10;

                          break;

 

        case GLUT_KEY_DOWN: obsY -=10;

                            break;

 

        case GLUT_KEY_HOME: obsZ +=10;

                            break;

 

        case GLUT_KEY_END: obsZ -=1;

                           break;

}

 

   glutPostRedisplay();

...

Para que as alterações tenham efeito, no método PosicionaObservador troque a linha de código gluLookAt(0,80,200, 0.0,0.0,0.0, 0.0,1.0,0.0); para gluLookAt(obsX,obsY,obsZ, 0.0,0.0,0.0, 0.0,1.0,0.0) e não esqueça de tirar a translação e rotação que está codificada.

 

Agora compile e execute o programa para verificar que estas alterações possibilitaram alterar a posição do observador mantendo sempre o mesmo alvo.

 

O metodo gluPerspective(angle, fAspect, 0.5, 500) estabelece os parâmetros da Projeção Perspectiva, atualizando a matriz de projeção perspectiva. Sua assinatura é: public void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);. Descrição dos parâmetros: fovy é o ângulo, em graus, na direção y (usada para determinar a "altura" do volume de visualização); aspect é a razão de aspecto que determina a área de visualização na direção x, e seu valor é a razão em x (largura) e y (altura); zNear, que sempre tem que ter um valor positivo maior do que zero, é a distância do observador até o plano de corte mais próximo (em z); zFar, que também sempre tem que ter um valor positivo maior do que zero, é a distância do observador até o plano de corte mais afastado (em z). Este método sempre deve ser chamado ANTES do método gluLookAt, e no modo GL_PROJECTION [Wright 2000].

 

Altere o parâmetro zNear do método gluPerspective para 0.2 (as vezes pode haver um problema na iluminação se o valor for muito baixo, tal como 0.1). Agora coloque 2 no lugar de fAspect, compile e execute para ver o que acontece. Troque o valor 2 por 0.5, compile e execute novamente. Coloque novamente a variável fAspect no segundo parâmetro da gluPerspective. Com estes testes, foi possível verificar as conseqüências de alterar a razão de aspecto.

 

Agora altere o parâmetro zNear da função gluPerspective para 210, compile e execute para ver o que acontece. Coloque novamente o valor 0.5 para zNear e troque o valor de zFar para 200, compile e execute. Coloque novamente o valor 500 para zFar.

 

O método glutWireTeapot(35) é usado para desenhar o wire-frame de um teapot (bule de chá). Sua assinatura é: void glutWireTeapot(double scale), onde o parâmetro scale indica o fator de escala aplicado no teapot, o que é usado para definir o seu tamanho. Assim como o método teapot, a classe GLUT também possui métodos para desenhar outros objetos 3D. Alguns métodos estão listados abaixo [Woo 1999]:


- public void glutWireCube(float size);
- public void glutWireSphere(double radius, int slices, int stacks);
- public void glutWireCone(double base, double height, int slices, int stacks);
- public void glutWireTorus(double innerRadius, double outerRadius, int nsides, int rings);
- public void glutWireIcosahedron();
- public void glutWireOctahedron();
- public void glutWireTetrahedron();
- public void glutSolidDodecahedron().

 

Os parâmetros slices e stacks que aparecem na assinatura de alguns métodos significam, respectivamente, o número de subdivisões em torno do eixo y (como se fossem linhas longitudinais) e o número de subdivisões ao longo do eixo z (como se fossem linhas latitudinais). Já rings e nsides correspondem, respectivamente, ao número de seções que serão usadas para formar o torus, e ao número de subdivisões para cada seção.

 

Agora experimente trocar o teapot pelos objetos cubo, cone, esfera e Octaedro. Coloque diferentes valores nos parâmetros para ver como fica a imagem final.

 

Na seqüência, crie e inicialize os seguintes atributos na classe Desenha
int rings = 6, nsides = 20, slices = 20, stacks = 10.
Depois, acrescente no seu código os comandos necessários para incrementar e decrementar o valor destas variáveis. Por exemplo, F1 incrementa e F2 decrementa a variável rings, F3 incrementa e F4 decrementa a variável nsides, e assim por diante.

 

Inclua no lugar do teapot um torus. Passe por parâmetro para a função glutWireTorus as variáveis rings e nsides criadas anteriormente, compile e execute o programa. Depois altere os valores destas variáveis utilizando as teclas especificadas anteriormente. Inclua também um cone e altere os valores das variáveis slices e stacks para ver o efeito.

 

Exercício: altere a implementação para que seja desenhada uma pirâmide formada por uma lista de vértices e uma lista de arestas no lugar do teapot. Dica: Faça o desenho usando GL_LINES.