Aula Prática: Transformações Geométricas Disciplina: Computação Gráfica Professora: Isabel Harb Manssour |
O objetivo desta aula aprender a trabalhar com as transformações geométricas usando a biblioteca OpenGL. Para isto, serão utilizadas as bibliotecas OpenGL, GLU e GLUT, de maneira que o programa fique portável e possa ser executado tanto no ambiente Windows como no ambiente Linux. Para implementação de aplicações OpenGL na linguagem de programação C/C++ é necessário criar um projeto para linkar as bibliotecas. Na primeira aula prática já foi fornecido este projeto para o ambiente Dev-Cpp, portanto, basta remover os programas fontes anteriores do projeto e incluir o programa fonte que será usado nesta aula, que na verdade é a resposta dos exercícios 2D da aula prática de Mapeamento, Câmera e Projeção. Inicialmente, verifique o conteúdo do programa fonte fornecido para entender como foi implementado o zoom, o pan e a correção de aspecto. Depois, compile e execute o programa que abrirá uma janela com fundo branco, uma casinha e duas linhas que representam os eixos cartesianos. Aplique zoom e pan e procure alterar o tamanho da janela várias vezes, aumentando e diminuindo bastante a sua largura e altura, de maneira intercalada. Observe atentamente o código para entender o seu funcionamento e observe as funções callback implementadas(Desenha, Teclado, TeclasEspeciais e GerenciaMouse). Agora altere o código fonte conforme descrito a seguir para implementar as transformações geométricas em duas casinhas separadamente. A cada alteração, compile e execute novamente o programa para verificar os resultados obtidos. Em caso de dúvida, consulte a professora ou o tuturial de introdução à OpenGL disponível em http://www.inf.pucrs.br/~manssour/OpenGL/Tutorial.html. Altere o programa de maneira que as chamadas para as funções que desenham a casa fiquem em uma função, conforme o exemplo abaixo: void DesenhaCasa(void) { glLineWidth(3); glBegin(GL_TRIANGLES); .... glEnd(); glBegin(GL_LINE_LOOP); .... glEnd(); } void Desenha(void) { .... glTranslatef(tx, ty, 0); DesenhaCasa(); .... } Em seguida, declare as seguintes variáveis globais (logo após os includes):
Inicialize estas variáveis na função Inicializa() com os seguintes valores:
Agora acrescente os comandos abaixo na função Desenha, logo após a chamada
para a função glTranslatef colocada anteriormente:
Finalmente, para fazer o tratamento dos eventos, inclua e termine de implementar a função callback TeclasEspeciais conforme descrito abaixo. O código desta função deve ser alterado para permitir:
void TeclasEspeciais(int key, int x, int y) { switch (key) { ... // teclas já implementadas case GLUT_KEY_PAGE_UP: break; case GLUT_KEY_PAGE_DOWN: break; case GLUT_KEY_HOME: break; case GLUT_KEY_END: break; } ... Para outras informações sobre o tratamento de eventos, consulte o tutorial de OpenGL (http://www.inf.pucrs.br/~manssour/OpenGL/Eventos.html). O objetivo agora é criar duas instâncias da casa que podem ser manipuladas através das transformações de escala, rotação e translação, de forma independente, como exemplificado na próxima figura. Neste caso, é necessário criar outras variáveis para guardar as transformações que serão aplicadas na nova instância da casinha. A função callback que gerencia eventos do teclado deve ser alterada de maneira que, por exemplo, quando o usuário pressiona F1, ele irá manipular a primeira instância da casinha, e quando ele pressiona F2 ele irá manipular a segunda instância da casinha (dica: crie uma variável para armazenar qual foi a instância selecionada). Basta alterar a função Desenha() para que as transformações geométricas sejam aplicadas apenas em uma das instâncias de cada vez. Para isto, devem ser utilizadas as funções glPushMatrix() e glPopMatrix() da seguinte maneira: void Desenha(void) { .... // Desenha a primeira instância da casinha glPushMatrix(); glTranslatef(...); glScalef(...); glRotatef(...); DesenhaCasa(); glPopMatrix(); // Desenha a segunda instância da casinha glPushMatrix(); glTranslatef(...); glScalef(...); glRotatef(...); DesenhaCasa(); glPopMatrix(); .... } As funções glPushMatrix e glPopMatrix são usadas para definir o escopo das transformações. A glPushMatrix é utilizada para guardar a matriz de transformação corrente na pilha, e a glPopMatrix para recuperar a matriz de transformação corrente da pilha. Agora vamos aprender a utilizar algumas primitivas gráficas disponíveis na GLUT para modelos de objetos 3D e exercitar as transformações geométricas 3D. Inicialmente faça o download do programa que será usado nesta aula. Grave este arquivo no drive h e inclua-o no projeto para o ambiente Dev-Cpp. Lembre de remover os programas fontes anteriores do projeto para incluir o programa fonte que será usado nesta aula. A função glutWireTeapot(50.0f); é usada para desenhar o wire-frame de um
teapot (bule de chá). Seu protótipo é: glutWireTeapot(GLdoouble size);, onde o parâmetro size indica
um raio aproximado do teapot. Uma esfera com este raio irá "envolver" totalmente o modelo [Wright 2000].
Assim como a função teapot, a biblioteca GLUT também possui funções para desenhar outros objetos 3D.
Estas funções estão listadas abaixo [Woo 1999]:
Os parâmetros slices e stacks que aparecem no protótipo de algumas funções, significam, respectivamente, o número de subdivisões em torno do eixo z (como se fossem linhas longitudinais) e o número de subdivisões ao longo do eixo z (como se fossem linhas latitudinais). Já rings e nsides correspondem, respectivamente, ao número de seções que serão usadas para formar o torus, e ao número de subdivisões para cada seção. Agora crie e inicialize as seguintes variáveis globais no programa:
Acrescente no seu código os comandos necessários para incrementar e decrementar o valor destas variáveis. Por exemplo, F1 incrementa e F2 decrementa a variável rings, F3 incrementa e F4 decrementa a variável nsides, e assim por diante. Inclua no lugar do teapot um torus. Passe por parâmetro para a função glutWireTorus as variáveis rings e nsides criadas anteriormente, compile e execute o programa. Depois altere os valores destas variáveis utilizando as teclas especificadas anteriormente. Observando o funcionamento do programa, na sua opinião, qual técnica de modelagem foi utilizada para modelar o torus? Teste a utilização das funções Cone, Sphere e Cube disponíveis na GLUT. Utilize as variáveis globais criadas anteriormente na chamada destas funções (rings, nsides, slices, stacks). Durante a execução, experimente alterar os valores destas variáveis. Olhe a próxima figura e faça as alterações necessárias para gerar a imagem que aparece na figura. Agora, usando as transformações geométricas e a função glutWireCone(30, 30, 10, 8); acrescente o código necessário para gerar a imagem abaixo. Importante: NÃO altere os parâmetros da glutWireCone NEM os parâmetros de visualização. Use apenas as transformações geométricas!!! Agora remova duas das chamadas para a função glutWireCone, deixando que
apenas um cone seja desenhado. Depois, inclua os comandos necessários para que seja possível alterar as
transformações geométricas que são aplicadas simplesmente pressionando uma tecla. Para isto, inicialmente, deverão
ser criadas as seguintes variáveis globais:
Exercício: tente fazer a aula prática sobre composição de transformações geométricas disponível aqui.
Comentários, dúvidas, sugestões, envie um mail para [email protected] |
Última alteração em 11 de setembro de 2006.