Exercício I

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

 

 Usando OpenGL

 

O objetivo desta aula é aprender a utilizar a biblioteca 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 para tentar entender o seu conteúdo.

Depois, compile e execute o programa que abrirá uma janela com fundo branco e um triângulo, conforme mostra a próxima figura.

 

Observe atentamente o código para entender o seu funcionamento,
considerando a estrutura básica de um programa OpenGL:

·       Criação de uma janela com glutCreateWindow;

·       Criação de um objeto que irá gerenciar os eventos (glutMainLoop);

·       Implementação da classe responsável pelo rendering e pelo gerenciamento dos eventos de teclado
(no exemplo, Desenha e Teclado);

 

Agora altere o código fonte conforme descrito a seguir e, a cada alteração,
execute novamente o programa para verificar os resultados obtidos.

Em caso de dúvida, consulte a professora ou o tutorial de introdução à OpenGL disponível em
http://www.inf.pucrs.br/~manssour/OpenGL/Tutorial.html.

1.   Troque a cor de fundo da janela, modificando os argumentos da chamada da função glClearColor(0.0f, 0.0f, 0.0f, 1.0f), e as cores do desenho (glColor3f(1.0f, 0.0f, 0.0f);); Deixe a cor de fundo como preto;

2.   Desenhe duas linhas que representem os eixos cartesianos do universo (use glBegin(GL_LINES) e glEnd(), acrescentando os quatro vértices necessários para o desenho dos eixos); Considere que as coordenadas mínimas e máximas são, respectivamente, -1.0 e 1.0. Importante: todas as rotinas de desenho devem ser chamadas a partir do método display (Desenha);

3.   Substitua a chamada à função glBegin(GL_TRIANGLES);....gl.glEnd(); pelo desenho de um triângulo e de um quadrado, que devem ser definidos de maneira a formar uma casinha, como mostra a próxima figura. Os comandos para desenhar o "telhado" da casinha são apresentados a seguir. Tente desenhar o resto da casinha usando GL_LINE_LOOP. Observe que quando a cor é trocada de um vértice para o outro, OpenGL faz um degrade entre as cores.


glLineWidth(3)

// Determina a espessura da linha que será desenhada
glBegin(GL.GL_TRIANGLES);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex2f(-0.2f,0.1f);
    glColor3f(1.0f, 0.0f, 0.0f);
    glVertex2f(0.0f,0.22f);
    glColor3f(0.0f, 0.0f, 1.0f);
    glVertex2f(0.2f,0.1f);
gl.glEnd();

4.   Aplique uma transformação geométrica de translação na casinha para mudá-la de lugar utilizando o método glTranslatef(float, float, float) (importante: a translação, bem como as transformações de escala e rotação, deve ser aplicada antes que a casinha seja desenhada).

 

Como fazer para interagir com o programa sem que seja necessário alterar e executar o código cada vez que o objeto, por exemplo, é trocado de lugar? Neste caso, é necessário gerenciar eventos do teclado e/ou mouse. Assim como já é feito com a tecla ESC na função Teclado, vamos tratar o evento de outras teclas para que o usuário possa interagir com a aplicação.

Declare os seguintes atributos que deverão ser inicializados, por default, com 0:
float translacaoX, translacaoY;

Agora altere os parâmetros passados para o método glTranslatef, que é chamado no método display, para que sejam passados estes atributos, da seguinte maneira:
glTranslatef(translacaoX, translacaoY, 0f);

Finalmente, para fazer o tratamento dos eventos, complemente a implementação do método Teclado de maneira a permitir transladar o objeto para cima, para baixo, para a esquerda e para a direita sempre que o usuário pressionar cada uma das teclas de setas (incremente e decremente as variáveis translacaoX e translacaoY)

Utilize glutSpecialFunc para as teclas especiais, exemplos: setas, Fs, PageUP, etc... Ao final chame a função glutPostRedisplay para criar um evento de desenho.

Agora, pressionando as teclas de setas é possível transladar a casinha, ou seja, deslocá-la para cima, para baixo, para direita e para esquerda.

Para implementar as operações de zoom e pan, altere o código fonte conforme descrito a seguir. O zoom consiste no aumento ou redução do
tamanho da window no sistema de referência do universo. Portanto, para aplicá-lo basta alterar as coordenadas do método gluOrtho2D
sempre que o usuário, por exemplo, pressionar as teclas Home e End. Veja nas figuras abaixo um exemplo de zoom in e outro de zoom out.

http://www.inf.pucrs.br/%7Emanssour/CG/pJava-Mapeamento/zoom1.jpghttp://www.inf.pucrs.br/%7Emanssour/CG/pJava-Mapeamento/zoom2.jpg

Para tanto, altere o código do método Teclado que é responsável por gerenciar eventos do teclado, acrescentando o tratamento para as teclas GLUT_KEY_HOME e GLUT_KEY_END.

Em seguida, declare quatro atributos do tipo double, chamados left, right, bottom e top, e os inicialize no método inicializa, conforme mostram os trechos de código abaixo.

 

        private double left, right, bottom, top;

        ...

        void Inicializa()

        {

               left = -1.0;

               right = 1.0;

               bottom = -1.0;

               top = 1.0;

               ...

         }

Isso definirá uma área de trabalho, ou janela de seleção (window) com os limites -1 até 1, tanto para x como para y.

Agora, altere a chamada para o método gluOrtho2D para que use estes novos atributos ao invés de colocar diretamente os valores 1.0 e -1.0, como mostra o exemplo abaixo.

 

...

               gluOrtho2D (left, right, bottom, top);

...

Em seguida, complemente a implementação do método keyPressed, de forma que estes atributos sejam alterados para implementar o zoom-in e o zoom-out (incremente e decremente os atributos usando valores entre 0.0 e 0.5). Como cada vez que estes atributos forem alterados deve-se chamar os métodos listados abaixo, acrescente-os bem no início do método display.

 

void Desenha() {

              glMatrixMode(GL.GL_PROJECTION);

              glLoadIdentity();

              gluOrtho2D (left, right, bottom, top);

              glMatrixMode(GL.GL_MODELVIEW);    

...

Execute o programa e verifique o que acontece cada vez que as teclas Home e End são pressionadas. Observe o efeito visual que ocorre quando essas teclas são pressionadas muitas vezes e coloque um limite para o incremento e decremento dos atributos (tente imaginar os valores para esse limite).

Executando o programa também é possível notar que as linhas que representam os eixos diminuem e aumentam de tamanho. Entretanto, é interessante que elas sempre fiquem dentro do limite da janela, de ponta a ponta. Para que isto aconteça, altere o método desenhaEixos para usar os atributos left, right, bottom e top no lugar dos valores fixos -1.0 e 1.0.

Para implementar o pan, que consiste, basicamente, no deslocamento da window no sistema de referência do universo, o procedimento é semelhante ao zoom, porém os parâmetros do método glu.gluOrtho2D devem ser alterados de maneira que a window seja deslocada para cima, para baixo, para esquerda e para direita. Veja na figura abaixo o resultado de um pan para a direita.

http://www.inf.pucrs.br/%7Emanssour/CG/pJava-Mapeamento/panright.jpg

Para implementar esta operação, vamos precisar de dois atributos que armazenem este deslocamento. Estes atributos devem ser declarados e inicializados conforme ilustram os trechos de código a seguir.

                         ...

        private float panX, panY;

        ...

       void Inicializa()

        {

               panX = panY = 0;

               ...

 

Depois, altere todas as chamadas do método gluOrtho2D da seguinte maneira:

gluOrtho2D(left+panX, right+panX, bottom+panY, top+panY);

Agora basta definir quais teclas irão deslocar a window, ou seja, que irão alterar os valores destes atributos. Sugestão: use F9 (desloca para a direita), F10 (para a esquerda), F11 (baixo) e F12 (cima).