Universidade Federal do Vale do São Francisco Curso de Engenharia da Computação Computação Gráfica - 04 Prof. Jorge Cavalcanti jorge.cavalcanti@univasf.edu.br 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
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
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
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
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
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
Gerenciamento de janelas Redimensionamento proporcional da janela Página 8
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. Página 9
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
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
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
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