|
Introdução à OpenGL Professora Isabel Harb Manssour |
|
11. Animação com OpenGL e GLUTPara exemplificar como fazer uma animação, como por exemplo mover ou girar objetos, será retomado o exemplo do capítulo 8, que desenha um quadrado numa janela com fundo preto. Agora, o quadrado será movido numa direção até bater em uma das bordas da janela e então mudar de direçã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 callback que torna mais fácil o processo de fazer uma simples animação. A função glutTimerFunc pega o nome da função callback que deve ser chamada e o tempo que ela deve esperar antes de chamar a função. A seguir é apresentado o código do exemplo de animação, e na seqüência as novas funções utilizadas são descritas [Wright 2000].
// Anima.c - Isabel H. Manssour
// Um programa OpenGL simples que mostra a animação
// de quadrado em uma janela GLUT.
// Este código está baseado no Bounce.c, exemplo
// disponível no livro "OpenGL SuperBible",
// 2nd Edition, de Richard S. e Wright Jr.
#include <windows.h>
#include <gl/glut.h>
// Tamanho e posição inicial do quadrado
GLfloat x1 = 100.0f;
GLfloat y1 = 150.0f;
GLsizei rsize = 50;
// Tamanho do incremento nas direções x e y
// (número de pixels para se mover a cada
// intervalo de tempo)
GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f;
// Largura e altura da janela
GLfloat windowWidth;
GLfloat windowHeight;
// Função callback chamada para fazer o desenho
void Desenha(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Limpa a janela de visualização com a cor de fundo especificada
glClear(GL_COLOR_BUFFER_BIT);
// Especifica que a cor corrente é vermelha
// R G B
glColor3f(1.0f, 0.0f, 0.0f);
// Desenha um quadrado preenchido com a cor corrente
glBegin(GL_QUADS);
glVertex2i(x1,y1+rsize);
glVertex2i(x1,y1);
// Especifica que a cor corrente é azul
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2i(x1+rsize,y1);
glVertex2i(x1+rsize,y1+rsize);
glEnd();
// Executa os comandos OpenGL
glutSwapBuffers();
}
// Função callback chamada pela GLUT a cada intervalo de tempo
// (a window não está sendo redimensionada ou movida)
void Timer(int value)
{
// Muda a direção quando chega na borda esquerda ou direita
if(x1 > windowWidth-rsize || x1 < 0)
xstep = -xstep;
// Muda a direção quando chega na borda superior ou inferior
if(y1 > windowHeight-rsize || y1 < 0)
ystep = -ystep;
// Verifica as bordas. Se a window for menor e o
// quadrado sair do volume de visualização
if(x1 > windowWidth-rsize)
x1 = windowWidth-rsize-1;
if(y1 > windowHeight-rsize)
y1 = windowHeight-rsize-1;
// Move o quadrado
x1 += xstep;
y1 += ystep;
// Redesenha o quadrado com as novas coordenadas
glutPostRedisplay();
glutTimerFunc(33,Timer, 1);
}
// Inicializa parâmetros de rendering
void Inicializa (void)
{
// Define a cor de fundo da janela de visualização como preta
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
// Função callback chamada quando o tamanho da janela é alterado
void AlteraTamanhoJanela(GLsizei w, GLsizei h)
{
// Evita a divisao por zero
if(h == 0) h = 1;
// Especifica as dimensões da Viewport
glViewport(0, 0, w, h);
// Inicializa o sistema de coordenadas
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Estabelece a janela de seleção (left, right, bottom, top)
if (w <= h) {
windowHeight = 250.0f*h/w;
windowWidth = 250.0f;
}
else {
windowWidth = 250.0f*w/h;
windowHeight = 250.0f;
}
gluOrtho2D(0.0f, windowWidth, 0.0f, windowHeight);
}
// Programa Principal
int main(void)
{
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(400,350);
glutInitWindowPosition(10,10);
glutCreateWindow("Anima");
glutDisplayFunc(Desenha);
glutReshapeFunc(AlteraTamanhoJanela);
glutTimerFunc(33, Timer, 1);
Inicializa();
glutMainLoop();
}
Obs.: Clique aqui para fazer o download deste programa.
Antes de prosseguir com a descrição das funções,
é necessário explicar o funcionamento do double-buffering, que é uma das características
mais importantes em qualquer pacote gráfico que está disponível na GLUT. Double-buffering
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
instantaneamente. Isto é útil, principalmente, por dois motivos:
|
Última alteração em 27 de março de 2003.