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.