Processamento Gráfico - UFPE - Prof. Marcelo Walter
Programando a Interação com o Mouse em GLUT
Esta nota objetiva explicar como utilizar o mouse nos programas escritos em GLUT. Existem 3 rotinas em GLUT que monitoram o estado do mouse (tanto movimento quanto clicks). Para entender melhor esta explicação, é necessário que você saiba conceitos básicos de programação orientada a eventos e as rotinas associadas aos eventos, denominadas de callbacks. No caso dos eventos relacionados ao mouse estas rotinas são:
glutMouseFunc()
Esta rotina é chamada sempre que um botão do mouse for pressionado
glutMotionFunc()
Esta rotina é chamada sempre que o mouse se move AO MESMO TEMPO em que um botão está sendo pressionado
glutPassiveMotionFunc()
Esta rotina é chamada sempre que o mouse se move
Veremos cada uma delas em maiores detalhes.
glutMouseFunc()
Os parâmetros desta função são:
* O botão que foi pressionado (uma das seguintes possibilidades: GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON). Lembre-se que nas nossas máquinas, a maioria dos mouses têm apenas 2 botões que correspondem ao GLUT_LEFT_BUTTON e GLUT_RIGHT_BUTTON
* O estado do mouse (uma das seguintes possibilidades: GLUT_DOWN ou GLUT_UP)
* As coordenadas x e y da posição do mouse no momento em que o botão foi pressionado. Estas coordenadas são relativas ao tamanho em pixels da janela
Segue um exemplo onde primeiro registramos a rotina de callback e após definimos a rotina propriamente dita. A rotina associada é extremamente simples neste exemplo, ela encerra a execução do programa quando o usuário pressionar o botão esquerdo do mouse.
glutMouseFunc( mouseCB );
void mouseCB( int botao, int estado, int x, int y)
{
if ( estado == GLUT_DOWN ) {
switch ( botao ) {
case GLUT_LEFT_BUTTON:
exit( 0 );
default:
break;
}
}
}
glutMotionFunc()
A rotina de movimento é disparada sempre que o mouse está se movendo dentro da janela enquanto um ou mais botões do mouse estão sendo pressionados. Nós normalmente utilizamos esta rotina em conjunto com a rotina definida para a glutMouseFunc() da seguinte forma: Primeiro glutMouseFunc() detecta que um botão do mouse foi pressionado; após este evento nós podemos monitorar a quantidade de movimento do mouse enquanto o botão está sendo pressionado. Com estas duas rotinas trabalhando em conjunto, nós podemos mapear o espaço percorrido pelo mouse dentro da janela para um valor numérico que irá controlar alguns atributos do programa.
Um exemplo típico seria utilizar a distância percorrida pelo mouse enquanto o botão está sendo pressionado para controlar a rotação de um objeto na tela. Poderíamos, por exemplo, dizer que movimentos do mouse para a esquerda rotacionam o objeto no sentido horário enquanto que movimentos do mouse para a direita rotacionam o objeto no sentido anti-horário.
Abaixo um trecho de código que armazena numa variável chamada quantMovimentoEmX a distância percorrida pelo mouse na direção horizontal enquanto o botão esquerdo estiver sendo pressionado.
glutMouseFunc( mouseCB );
glutMotionFunc( mouseMovCB );
int velhoX, quantMovimentoEmX;
void mouseCB( int botao, int estado, int x, int y )
{
if ( estado == GLUT_DOWN ) {
switch ( botao ) {
case GLUT_LEFT_BUTTON:
velhoX = x; // armazena a posicao x do mouse
default: // no momento em que o botao foi pressionado
break;
}
}
}
void mouseMovCB( int x, int y)
{
quantMovimentoEmX = velhoX - x; // a diferenca entre o valor antigo
// do mouse e o novo nos fornece
// a distancia percorrida pelo mouse
velhoX = x;
}
glutPassiveMotionFunc()
A rotina de movimento passivo, como o nome indica, é disparada sempre que o mouse estiver se movendo dentro da janela, MESMO SEM NENHUM BOTÃO SENDO PRESSIONADO! Os argumentos recebidos são os mesmos da rotina glutMouseFunc, ou seja, a posição x e y do mouse relativa dentro da janela.
Uma aplicação típica de uso desta rotina é ajudar o usuário a selecionar objetos na tela. Poderíamos imaginar uma aplicação onde são apresentados diversos objetos ao usuário e ele deve selecionar um deles com o mouse. A posição do mouse neste caso é importante para decidirmos se o mouse está próximo ou em cima de um determinado objeto.
Abaixo uma ilustração dos pontos principais relacionados à utilização do mouse. A ilustração exemplifica uma janela com h pixels de altura e w pixels de largura. O mouse movimentou-se do ponto A ao ponto B. Neste deslocamento ele andou dx pixels na direção x e dy pixels na direção y. Observe que estes valores são relativos à origem da janela, cujas coordenadas (0,0) estão associadas ao canto superior esquerdo da janela.
Para maiores informações sobre esta rotinas você pode consultar o glut-3.spec.pdf ou o livro "vermelho" de OpenGL.