Universidade Federal do Vale do São Francisco Curso de Engenharia da Computação Computação Gráfica - 04 Prof. Jorge Cavalcanti [email protected] www.univasf.edu.br/~jorge.cavalcanti www.twitter.com/jorgecav Gerenciamento de eventos: mouse e teclado • A biblioteca GLUT também contém funções para gerenciar eventos de entrada de teclado e mouse. • glutKeyboardFunc - Estabelece a função que é chamada pela GLUT cada vez que uma tecla que gera código ASCII é pressionada (por exemplo: a, b, A, b, 1, 2). • Além do valor ASCII da tecla, a posição (x,y) do mouse quando a tecla foi pressionada também é retornada. Parâmetros de entrada da função callback: (unsigned char key, int x, int y) . • Ao invés de usar o código ASCII, podemos usar o próprio caracter entre apóstrofos: ‘q’ ou ‘Q’. Página 2 Computação Gráfica – Parte 04 29/03/2017 Gerenciamento de eventos: mouse e teclado • glutSpecialFunc - Estabelece a função que é chamada pela GLUT cada vez que uma tecla que gera código não-ASCII é pressionada, tais como Home, End, PgUp, PgDn, F1 e F2. (unsigned char key, int x, int y). • Os valores válidos para o primeiro parâmetro são: GLUT_KEY_F1, GLUT_KEY_F2, GLUT_KEY_F3, GLUT_KEY_F4, GLUT_KEY_F5, GLUT_KEY_F6, GLUT_KEY_F7, GLUT_KEY_F8, GLUT_KEY_F9, GLUT_KEY_F10, GLUT_KEY_F11, GLUT_KEY_F12, GLUT_KEY_LEFT, GLUT_KEY_UP, GLUT_KEY_RIGHT, GLUT_KEY_DOWN, GLUT_KEY_PAGE_UP, GLUT_KEY_PAGE_DOWN, GLUT_KEY_HOME, GLUT_KEY_END, GLUT_KEY_INSERT. Página 3 Computação Gráfica – Parte 04 29/03/2017 Gerenciamento de eventos: mouse e teclado • glutMouseFunc- Estabelece a função que é chamada pela GLUT cada vez que ocorre um evento de mouse. Parâmetros de entrada da função callback: (int button, int state, int x, int y). • Três valores são válidos para o parâmetro button: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON e GLUT_RIGHT_BUTTON. • O parâmetro state pode ser GLUT_UP ou GLUT_DOWN. Os parâmetros x e y indicam a localização do mouse no momento que o evento ocorreu. • Código Exemplo do uso do mouse e teclado. http://migre.me/1mEUG - interação Página 4 Computação Gráfica – Parte 04 29/03/2017 Gerenciamento de janelas Redimensionamento proporcional da janela • Quando alteramos o tamanho da janela da aplicação, a área interna onde estão sendo exibidos os desenhos precisa acompanhar esse redimensionamento. • Isso deve se feito para que os eixos x e y nos quais as coordenadas dos pontos dos objetos são definidos, possam ser ajustados para esse novo tamanho da janela. • A função glutReshapeFunc faz chamada a uma função recursiva pré-definida pelo programador para tratar das dimensões da tela a cada vez que a mesma seja redimensionada. Página 5 Computação Gráfica – Parte 04 29/03/2017 Gerenciamento de janelas Redimensionamento proporcional da janela • Além disso, podemos estabelecer que a janela de visualização (viewport) dos objetos pode ser menor do que a janela da aplicação. • Isso pode ser útil quando queremos destinar parte da janela para menus, instruções etc.. • glViewport( int x, int y, width, height) Seus parâmetros especificam o canto inferior esquerdo da viewport (x,y) dentro da janela, e a sua largura e altura em pixels (width e height). • Geralmente x e y são zero, mas é possível usar a viewport para fazer o render de mais de uma cena em diferentes áreas da janela. Página 6 Computação Gráfica – Parte 04 29/03/2017 Gerenciamento de janelas Redimensionamento proporcional da janela • Em outras palavras, a viewport define a área dentro janela, em coordenadas de tela, que a OpenGL pode usar para fazer o desenho. O volume de visualização é, então, mapeado para a nova viewport. • Código exemplo: http://migre.me/1mWXW (quadrado) • Observar a chamada de redimensionamento. • Para usar mais de uma viewport na mesma aplicação, basta fazer quantas chamadas glViewport necessárias. • Código exemplo: http://migre.me/1mXFZ (DuasViewport) Página 7 Computação Gráfica – Parte 04 29/03/2017 Gerenciamento de janelas Redimensionamento proporcional da janela Página 8 Computação Gráfica – Parte 04 29/03/2017 Gerenciamento de janelas Redimensionamento proporcional da janela • Podemos alterar os parâmetros da janela da aplicação para controlarmos o zoom da imagem. • Altera-se somente o tamanho da janela. Não usa a escala para alterar o tamanho dos objetos. • Código exemplo: http://migre.me/1mY1z - (Casa com zoom) • Usar as setas para cima/para baixo para aplicar o zoom. Atividade Prática – Valendo 3 pontos Página 9 Computação Gráfica – Parte 04 29/03/2017 Animação • É possível criar um laço que continuamente altera as coordenadas do objeto antes de chamar a função "Desenha". • Isto daria a impressão de que o quadrado se move na janela. Porém, a biblioteca GLUT fornece a possibilidade de registrar uma função que torna mais fácil o processo de fazer uma simples animação. • A função glutTimerFunc pega o nome da função que deve ser chamada e o tempo que ela deve esperar antes de chamar a função. Página 10 Computação Gráfica – Parte 04 29/03/2017 Animação • glutTimerFunc(unsigned int msecs, void (*func)(int value), int value)- estabelece a função Timer previamente definida como a função de animação. • Esta função faz a GLUT esperar msecs milisegundos antes de chamar a função func. • Como esta função é "disparada" apenas uma vez, para se ter uma animação contínua é necessário reinicializar o timer novamente na função Timer. • void Timer(int value)- é a função chamada pela glutTimerFunc. • Código Exemplo: http://migre.me/1mYLK Página 11 Computação Gráfica – Parte 04 29/03/2017 Animação • Observar que no código-fonte exemplo da animação, foi trocado o modo de exibição da janela para double. • O double-buffering é uma das características mais importantes em qualquer pacote gráfico que está disponível na GLUT. Ele permite que um desenho seja exibido na tela enquanto está sendo realizado o rendering em um offscreen buffer. • Então, um comando de swap coloca a imagem na tela assim que a imagem seguinte é formada. • Isto é útil, principalmente, por dois motivos: -Alguns desenhos complexos podem levar um certo tempo para serem feitos, e não é desejado que cada passo da composição da imagem seja visível; - É possível compor uma imagem e exibi-la somente depois de completa, de maneira que o usuário nunca vê uma imagem parcial, pois ela é exibida somente quando está pronta. Página 12 Computação Gráfica – Parte 04 29/03/2017 Animação • No caso de uma animação, cada quadro (ou frame) é desenhado no offscreen buffer e é exibido (swapped) rapidamente depois de pronto. • glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB), foi usada para trocar o modo de exibição de GLUT_SINGLE para GLUT_DOUBLE. • Isto faz com que todo o rendering seja feito em um offscreen buffer. • glutSwapBuffers()- é usada no lugar da glFlush porque quando é feita a troca (ou swap) de buffers, é realizada implicitamente uma operação de flush. Página 13 Computação Gráfica – Parte 04 29/03/2017