Processamento Gráfico

UFPE - Prof. Marcelo Walter

SIVOP - Sistema Visualizador de Objetos Poliédricos

TRABALHO INDIVIDUAL! Entregar em aula o documento pedido e enviar por email, até a meia-noite do dia 15/09/08 ao professor (marcelo.walter at gmail.com) os arquivos fontes de seu programa e qualquer outro fonte necessário para compilar seu executável! A cada hora de atraso no envio do email, será descontado 1.0 (um) ponto do total da nota. Explicitar no documento qualquer informação necessária para compilar corretamente seu programa.


1. Introdução

Este primeiro projeto tem os seguintes objetivos:


    a. Introduzir as bibliotecas gráficas OpenGL e GLUT, que formarão a base dos nossos trabalhos de desenvolvimento de software, propiciando uma familiarização com as mesmas;

    b. Introduzir e praticar o conceito de programação direcionada por eventos;

    c. Aplicar num exemplo prático os conceitos básicos de computação gráfica como câmera sintética para exibição de objetos representados por uma coleção de polígonos, iluminação e interação simples com um programa através do mouse e teclado.


2. Especificação Geral do Visualizador

Você deve implementar um Sistema Visualizador de Poliedros (abreviado SIVOP). Poliedros são objetos representados por uma coleção de polígonos. No nosso caso utilizaremos apenas polígonos de 3 lados, ou seja, triângulos.  A interação é efetuada via mouse e teclado. O seu programa deverá ser capaz de carregar objetos e permitir ao usuário executar operações básicas de translação e rotação da posição da câmera sintética  através do mouse. A figura a seguir  ilustra uma possível tela do programa, onde o objeto representa um cachorro.


3. Requisitos

Para este exercício você deverá implementar o seguinte:


    * Rotinas que abrem uma janela com projeção perspectiva (veja a descrição de glFrustum e glPerspective). O usuário poderá redimensionar a janela livremente mantendo a proporção do objeto sendo exibido. A janela deverá ter inicialmente tamanho de 400x400 pixels.


    * Rotina para ler um objeto em formato obj. O formato dos arquivos obj bem como uma estrutura de dados adequada para seu armazenamento, são especificados no item 5 abaixo. O seu programa deverá ler como parâmetro na linha de comando o nome do arquivo que contém a descrição do objeto. Chame o executável de sivop. A execução numa janela DOS ou terminal linux seria do tipo:


     sivop dog.obj


onde "dog.obj" é o nome do arquivo especificando o objeto sendo carregado.


* Rotinas que permitam exibir o objeto em modo de preenchimento de polígonos (ao invés de somente aramado). O modo default é apresentar o objeto aramado. A tecla F mudará a representação do objeto para um dos 2 modos possíveis: aramado e preenchido. No modo preenchido a cor das arestas dos polígonos deverá ser diferente da cor de preenchimento dos polígonos (veja imagem acima, onde os polígonos estão na cor cinza claro e as arestas estão em preto).

  

* Rotinas que permitam ao usuário rotacionar e transladar a posição da câmera. O eixo para translação e rotação poderá ser x, y ou z. O controle da quantidade de rotação e translação é controlado pelo movimento do mouse. Veja as dicas (item 6) abaixo.


* Rotinas que permitam ao usuário ligar e desligar uma fonte de luz no ambiente. A tecla L liga e desliga a luz virtual. A posição da fonte de luz é livre, desde que fique claro na imagem que ela está presente.


    * As opções de interação via  teclado são:


      X - especifica eixo corrente igual ao X

      Y - especifica eixo corrente igual ao Y

      Z - especifica eixo corrente igual ao Z

      R - especifica modo Rotação

      T - especifica modo Translação

      F - especifica trocar o modo de exibição (de preenchido para não-preenchido ou vice-versa)

      L - liga e desliga a fonte de luz

      Q - encerra a execução do programa


* Rotinas que exibem na tela uma mensagem no canto inferior esquerdo, indicando ao usuário qual operação está ativa (rotação ou translação) e qual eixo está ativo (X, Y, ou Z).


Na ilustração acima o programa está no modo Rotacao na direção Y sem luz ligada. Você precisará utilizar as funções glRasterPos3f e glutBitmapCharacter para poder escrever estas mensagens na tela.


4. Recursos


É EXTREMAMENTE aconselhável que você leia e entenda as explicações dos recursos especificados abaixo.


    * Programa Exemplo
    Para auxiliá-lo na execução deste trabalho, coloquei a disposição um programa  que executa a rotação de    um cubo pressionando-se a tecla R. Deve proporcionar um bom ponto de partida para o seu programa.


    * Programando com o mouse em GLUT

   

    * Noções sobre Projeções


    * Como calcular o vetor normal necessário para os cálculos de iluminação



5. Arquivos obj

O formato obj foi desenvolvido pela Wavefront para especificar facilmente objetos representados por polígonos. A idéia principal do formato é apresentar inicialmente uma lista de vértices seguida de uma lista de faces que apontam para os vértices que a compõe. Um cubo, por exemplo, teria a seguinte representação:

# ------------------------------------------------------------------------------------------------------------------------------------------------

# cubo.obj

# cubo representado por triangulos centrado na origem

# Linhas que iniciam com # sao comentarios

# Autor: Marcelo Walter

# Lista de vertices

v -0.5 0.5 0.5

v -0.5 -0.5 0.5

v 0.5 -0.5 0.5

v 0.5 0.5 0.5

v -0.5 0.5 -0.5

v -0.5 -0.5 -0.5

v 0.5 -0.5 -0.5

v 0.5 0.5 -0.5

# Lista de faces

f  1 2 3

f  8 7 6

f  4 3 7

f  5 1 4

f  5 6 2

f  2 6 7

f  1 3 4

f  8 6 5

f  4 7 8

f  5 4 8

f  5 2 1

f  2 7 3

# ------------------------------------------------------------------------------------------------------------------------------------

Observe que as linhas que iniciam com o caracter # são consideradas linhas de comentário e não afetam a representação do objeto. O caracter v especifica um vértice; o caracter f especifica uma face. No exemplo todas as faces são formadas por 3 vértices. A face 1, por exemplo, é formada pelos vértices 1, 2 e 3 da lista de vértices. A figura abaixo ilustra uma possível estrutura de dados para armazenamento desta informação.


Observe que uma estrutura dinâmica para armazenamento é mais adequada, pois você não sabe a princípio quantos vértices ou faces um objeto tem.

Obviamente que um cubo apenas não é muito interessante. Nesta página há outros objetos para você testar o seu programa. Observe que a sua implementação não precisará ler todos os objetos disponíveis da lista. Neste trabalho você deve se preocupar apenas com os objetos representados por triângulos.


6. Dicas


    * Para acompanhar os movimentos do mouse você precisará utilizar 2 rotinas de callback do GLUT: glutMouseFunc e glutMotionFunc. A primeira é chamada cada vez que algum botão do mouse é pressionado; a segunda é chamada cada vez que o mouse está sendo movimentado AO MESMO TEMPO que algum botão está sendo pressionado. Para calcular a quantidade de transformação a ser aplicada via mouse faça o seguinte:

          o Dentro da rotina glutMouseFunc armazene a posição corrente do mouse

          o Com o movimento do mouse a rotina glutMotionFunc será chamada repetidamente. Durante cada chamada você pode determinar quanto o mouse se moveu na direção X e utilizar este valor para controlar a quantidade de transformação.

    * Você precisará habilitar a eliminação de elementos ocultos (depth buffering) em OpenGL. Para isto você precisará:

          o Incluir o parâmetro GLUT_DEPTH na chamada da função glutInitDisplayMode

          o Habilitar a eliminação de elementos ocultos em OpenGL com o comando glEnable(GL_DEPTH_TEST)

          o Escolher uma condição para o teste de z-buffer com o comando glDepthFunc. O frame buffer deve ser limpo cada vez que a cena é redesenhada passando o parâmetro GL_DEPTH_BUFFER_BIT para o comando glClear

    * A projeção perspectiva sempre tem por default a câmera posicionada em (0,0,0). Para poder visualizar algo você deve transladar o objeto para uma posição (0,0,-5) por exemplo (em OpenGL a parte positiva do eixo z sempre aponta para fora da tela e conseqüentemente a parte negativa aponta para dentro da tela).

    * Nos arquivos OBJ representandos por triângulos, normalmente não há a informação do vetor normal, então você deverá calcular um vetor normal para cada vértice da malha. Para isto, durante a leitura das faces, calcule o vetor normal de cada face (explicação aqui) e armazene este vetor com cada vértice que compõe a face. Ao final da leitura calcule a média dos vetores associados aos vértice. Este é o vetor normal do vértice.


7. Critérios para avaliação


Os seguintes criterios serão utilizados para avaliação do seu trabalho:


    - (5%) Documentação a ser entregue. Você deverá entregar um documento COM NO MÁXIMO 2 PÁGINAS, onde você descreverá o trabalho implementado, dificuldades encontradas e outros pontos que você achar relevante (por exemplo, se você implementou algo extra no trabalho). Incluir neste documento explicações necessárias para compilar seu programa.

    - (15%) Leitura correta do arquivo obj

    - (15%) Interação via mouse (controle da câmera)

    - (15%) Iluminação

    - (40%) Projeção perspectiva, aspect ratio, objeto aramado/preenchido, outros.

    - (10%) Mensagens corretas na tela


Observação Importante: A fraude escolar (cópia de trabalhos, trabalhos não feitos pelo aluno, etc) constitui falta grave e pode resultar em nota zero para o aluno no trabalho e dependendo da gravidade da fraude inclusive em sanções mais duras.