Baixe o app para aproveitar ainda mais
Prévia do material em texto
Computação Gráfica I1 Computação Gráfica I aula 07 Eventos Teclado e Mouse Duplo Buffer e Timer Computação Gráfica I2 Em OpenGL é possível tratar as entradas via teclado dos usuários através de duas funções callback. A primeira função trata as teclas comuns e deve ser definida pela função glutKeyboardFunc(). A segunda trata as teclas especiais (F1..F12, PageUp, PageDn, Up, Down, Home, End, Left, Right, etc.) e é definida pela funçao glutSpecialFunc(). int main(void) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutCreateWindow(“Teclado”); glutDisplayFunc(desenha); glutKeyboardFunc(teclado); glutSpecialFunc(tecladoEspecial); inicializa(); glutMainLoop(); } OpenGL – Teclado Avisa ao OpenGL que a função responsável por tratar as teclas comuns digitadas pelo usuário é a função teclado() e que a função responsável pelas teclas especiais é a função tecladoEspecial(). Computação Gráfica I3 A função que trata as teclas comuns recebe os seguintes parâmetros: bool preenche = true; void teclado(unsigned char tecla, int x, int y) { // Se o usuário digitou barra de espaco // desenha um poligono preenchido ou nao if (tecla == ‘ ‘) preenche = ! preenche; glutPostRedisplay(); } OpenGL – Teclado o parâmetro tecla recebe o caracter digitado pelo usuário, enquanto os parâmetros (x, y) recebem a posição do mouse quando o usuário efetuou a digitação. Por último deve ser chamada a função glutPostRedisplay() para avisar ao OpenGL que a tela precisa ser redesenhada para que o usuário visualize o efeito desejado. Internamente o OpenGL chama a função responsável por desenhar a tela. Computação Gráfica I4 A função que trata as teclas especiais recebe os seguintes parâmetros: Glint espessura = 1; void tecladoEspecial(int tecla, int x, int y) { // Se o usuário digitou UP aumenta a espessura // da linha, se digitou Down diminui a espessura // da linha if (tecla == GLUT_KEY_UP) espessura++; else if (tecla == GLUT_KEY_DOWN) espessura--; if (espessura < 0) espessura = 0; glutPostRedisplay(); } OpenGL – Teclado o parâmetro tecla recebe o código do caracter especial digitado pelo usuário, enquanto os parâmetros (x, y) recebem a posição do mouse quando o usuário efetuou a digitação. Para facilitar a identificação da tecla digitada o OpenGL possui uma série de constantes que definem essas teclas: GLUT_KEY_F1... 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 Computação Gráfica I5 Em OpenGL é possível capturar os cliques do mouse definindo uma função callback através de glutMouseFunc(): int main(void) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(400,400); glutInitWindowPosition(10,10); glutCreateWindow(“Mouse"); glutDisplayFunc(desenha); glutMouseFunc(mouse); glutReshapeFunc(redimensiona); inicializa(); glutMainLoop(); } OpenGL – Mouse Basta definir o nome da função, que é mouse nesse caso. Computação Gráfica I6 A função que trata os cliques do mouse recebe os seguintes parâmetros: int xm, ym; int largura_vp, altura_vp; void mouse(int botao, int estado, int x, int y) { // Transforma as coordenadas da tela // nas coordenadas do plano xm = ((2 * MAXX * x) / largura_vp) - MAXX; ym = (((2 * MAXY) * (y - altura_vp)) / - altura_vp) - MAXY; glutPostRedisplay(); } OpenGL – Mouse o parâmetro botao recebe: - GLUT_LEFT_BUTTON - GLUT_MIDDLE_BUTTON - GLUT_RIGHT_BUTTON O parâmetro estado recebe: - GLUT_DOWN - GLUT_UP indicando se o mouse foi pressionado ou solto MAXX e MAXY são a largura e altura do plano cartesiano largura_vp e altura_vp são a largura e altura da viewport Computação Gráfica I7 Repare que, em muitos casos, ao fazermos animações com o OpenGL temos o efeito de flicker. Para eliminar ou diminuir esse efeito trabalhamos com um recurso chamado double buffer ou duplo buffer. Esse efeito consiste em desenhar a imagem em um buffer secundário de memória e, depois, renderizar esse buffer na memória de vídeo. Dessa forma, evitamos que o desenho seja feito diretamente no buffer primário da memória de vídeo. Para usar esse recurso, precisamos alterar dois pontos nos nossos programas: OpenGL – Duplo Buffer Computação Gráfica I8 Ao iniciar o modo do display avisamos que vamos usar um buffer duplo: int main(void) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(400,400); glutInitWindowPosition(10,10); glutCreateWindow(“Buffer"); glutDisplayFunc(desenha); glutReshapeFunc(redimensiona); inicializa(); glutMainLoop(); } OpenGL – Duplo Buffer Mudamos de GLUT_SINGLE para GLUT_DOUBLE Computação Gráfica I9 Ao final da renderização, ao invés de usar glFlush() usamos glutSwapBuffers(): void desenha(void) { //Limpa a janela de visualização com a cor de fundo especificada glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_LINE_LOOP); glVertex2i( 10, 10); glVertex2i(-10, 10); glVertex2i(-10, -10); glVertex2i( 0, -20); glVertex2i( 10, -10); glEnd(); glutSwapBuffers(); } OpenGL – Duplo Buffer Troca o glFlush() pelo glutSwapBuffers() Computação Gráfica I10 Em OpenGL também é possível fazer animaçoes usando uma função callback de timer, ou seja, uma função que é chamada automaticamente pelo OpenGL em intervalos de tempo. Para definir a função de timer usamos glutTimerFunc(): int main(void) { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(400,400); glutInitWindowPosition(10,10); glutCreateWindow("Timer"); glutDisplayFunc(desenha); glutTimerFunc(500, move, 0); glutReshapeFunc(redimensiona); inicializa(); glutMainLoop(); } OpenGL – Timer Vamos usar um outro tipo de buffer, chamado double buffer, que é mais adequado para animações. • O primeiro parâmetro define em quanto tempo a função será chamada (em milisegundos). • O segundo parâmetro é o nome da função callback de timer. • O terceiro parâmetro é um valor numérico que nós definimos e que será passado automaticamente para a função de timer. Computação Gráfica I11 A função de timer tem as seguintes características: void move(int valor) { angulo += 5; if (angulo >= 360) angulo = 0; glutPostRedisplay(); glutTimerFunc(500, move, 0); } OpenGL – Timer O valor recebido como parâmetro é o mesmo que definimos em glutTimerFunc(). Rodamos o desenho em 5º (sentido anti- horário). Quando chegamos a 360º, voltamos para 0º Avisamos ao OpenGL que ele precisa redesenhar a tela. Ao final da função de timer precisamos avisar ao OpenGL para ele chamar novamente essa função daqui a 500 milisegundos, pois Computação Gráfica I12 A função de desenha() fica da seguinte forma: void desenha(void) { // Limpa a janela de visualização // com a cor de fundo especificada glClear(GL_COLOR_BUFFER_BIT); // Desenha o circulo glLoadIdentity(); glRotatef(angulo, 0.0f, 0.0f, 1.0f); glColor3f(1.0f, 0.0f, 0.0f); poligono(); //Executa os comandos OpenGL // com double buffer glutSwapBuffers(); } OpenGL – Timer Informamos ao OpenGL para rotacionar todas as renderização usando a variável angulo, que é alterada a cada 500 milisegundos. Dessa forma obtemos a animação Como estamos usando um double buffer, ao invés de usar glFlush(), devemos usar glutSwapBuffers(). Slide 1 OpenGL – Teclado OpenGL – Teclado OpenGL – Teclado OpenGL – Mouse OpenGL – Mouse OpenGL – Duplo Buffer OpenGL – DuploBuffer OpenGL – Duplo Buffer OpenGL – Timer OpenGL – Timer OpenGL – Timer
Compartilhar