Upload
api-3806174
View
338
Download
7
Embed Size (px)
Citation preview
HUGO IMPERIANO NÓBREGA 10711467
INTRODUÇÃO À COMPUTAÇÃO GRÁFICA
JOÃO PESSOA
2008
HUGO IMPERIANO NÓBREGA
PROJETO FINAL
LABIRINTO VIRTUAL
Projeto desenvolvido para a disciplina
Introdução à Computação Gráfica do
curso de Ciência da Computação da
Universidade Federal da Paraíba.
JOÃO PESSOA
2008
SumárioSumário
1
Introdução .................................................................................
.............. 1
1.1
Apresentação .................................................................................... 1
1.2
Objetivos........................................................................................... 1
2
Ferramentas ..............................................................................
.............. 2
2.1
OpenGL ............................................................................................ 2
2.2 Blender e
Wavefront .......................................................................... 3
3 Etapas de
Desenvolvimento .................................................................... 3
3.1
Importador ........................................................................................ 3
3.2
Interação .......................................................................................... 4
3.21
Movimentação ........................................................................ 5
3.21 Detecção de
Colisão ............................................................... 7
3.3
Modelagem ....................................................................................... 9
3.4
Aplicação ......................................................................................... 10
4
Resultados .................................................................................
............ 11
5
Conclusão ..................................................................................
............ 13
6
Bibliografia ................................................................................
............ 14
6.1 Referências
Bibliográficas ................................................................. 14
6.2 Referências
Adicionais ...................................................................... 14
1. Introdução
1.1Apresentação
Os ambientes virtuais têm inúmeras aplicações, que vão desde uso em atividades
científicas até o uso em áreas de lazer, como jogos e animações para cinema.
Existem também, diversos enfoques que podem ser dados na criação de um ambiente
virtual, podendo ser um enfoque mais específico como a criação de um jogo em cima de um
engine já existente ou o desenvolvimento de uma plataforma que serviria para criação de
outras aplicações.
Neste trabalho, abordamos um pouco do desenvolvimento mais abrangente e criamos
uma aplicação-exemplo para implementar as funcionalidades criadas.
1.2 Objetivos
Este projeto tem por objetivo, além da aplicação dos conhecimentos adquiridos no
decorrer da disciplina de Introdução à Computação Gráfica, a criação de um ambiente
virtual. Mais especificamente, pode-se dizer, que o objetivo deste trabalho é o
desenvolvimento de um ambiente juntamente com um conjunto de funcionalidades que
tornem este ambiente genérico, no sentido de estar apto a servir como base para várias outras
aplicações, como por exemplo, diferentes tipos de jogos. Para demonstrar as funcionalidades,
optou-se por criar uma espécie de labirinto.
2. Ferramentas
Para o desenvolvimento do projeto, foram usadas as seguintes ferramentas:
• OpenGL, GLUT, GLU e C
• Blender e Wavefront (.obj)
2.1 OpenGL
“A OpenGL (Open Graphical Library) pode ser definida como uma inferface de
software (API – Aplication Program Interface) para aceleração gráfica de dispositivos
gráficos” [1].
Foi com o uso desta biblioteca de funções, além da GLU (OpenGL Utility) e da
GLUT (OpenGL Utility Toolkit) , em cima da linguagem de programação C, que se
desenvolveu esta aplicação.
Da OpenGL, incluindo GLU e GLUT, foi utilizado:
• Dois buffers de desenho, para que houvesse uma maior agilidade para renderizar os
objetos.
• Detph Buffer, que implementa o algoritmo do Z-Buffer, para testes de profundidade.
• Modelo de iluminação de Gouraud e funções para aplicação de materiais.
• Funções para criação e configuração da janela de visualização, viewport, projeção.
• Funções para interação via mouse/teclado.
2.2 Blender e Wavefront
O blender foi usado basicamente para a modelagem de objetos e exportação para o
formato Wavefront (obj) e este por sua vez foi usado para a importação dos objetos para
OpenGL.
3. Etapas de Desenvolvimento
No processo de desenvolvimento do projeto houve uma divisão por etapas, de forma
que fosse mantido o foco do desenvolvimento. Estas etapas foram quatro e elas são descritas
à seguir de maneira breve:
• Criação do importador
• Criação de interação com o ambiente
• Modelagem
• Criação da aplicação
3.1 Importador
Devido à necessidade de utilizar modelos de certa complexidade, optou-se por
desenvolver um importador que à partir de objetos modelados em algum programa que
oferecesse maiores facilidades para esta tarefa, conseguisse montar esses objetos por meio da
OpenGL.
Inicialmente, optou-se por criar um importador baseado em arquivos da linguagem
VRML (Virtual Reality Modelling Language), na sua versão 1.0, que possibilita o
desenvolvimento de ambientes tridimensionais estáticos[2]. Entretanto, encontrou-se
dificuldade em relação às normais, das faces dos objetos no formato VRML, pois
aparentemente elas não estavam contidas nos arquivos dos objetos, de forma que foi
necessária a criação de uma função para à partir das faces do objeto, determinar as normais
destas faces. Entretanto, para usar o Modelo de Sombreamento de Gouraud, que necessita-se
das normais de vértice[1], eram necessários cálculos extras, de forma que optou-se por usar o
tipo de arquivo WAVEFRONT, de formato obj, que fornece as normais para todos os
vértices.
Na criação deste novo importador, foram usadas as estruturas de dados já criadas para
o primeiro importador, de modo que fossem guardados os pontos (vértices), as normais, as
faces e os objetos. Foi criada uma hierarquia baseada no fato de que um objeto contém faces
e estas por sua vez contêm vértices e normais para estes vértices.
A seguir, é dada uma breve descrição do funcionamento do importador:
• Deve ser chamada a função abrearquivo(), de forma que seja passada como parâmetro um
string com o nome do arquivo e o seu formato. Esta função, coerentemente com sua
denominação, abre o arquivo no formato obj.
• Em seguida, deve ser chamada a função learquivo(), que lê o arquivo em busca dos
pontos ,normais e faces, e os organiza em estruturas apropriadas e todas elas são
armazenadas em uma estrutura objeto em uma lista destes, de forma que o primeiro objeto a
ser lido seja o primeiro da lista e assim por diante.
• A partir disto, tem-se os objetos armazenados na memória prontos para serem usados por
meio de funções de desenho criadas dentro do módulo objeto (que contém estruturas e
funções relacionadas aos objetos).
3.2 Interação
Para que o usuário possa interagir com o ambiente, faz-se necessário o
desenvolvimento de funções que possibilitem basicamente a sua movimentação e a detecção
de colisão.
3.2.1 Movimentação
Baseado nisto, foi desenvolvido um sistema de funções que tenta tornar a
movimentação do usuário o mais intuitiva possível. Optou-se então por possibilitar ao
usuário, por meio do mouse, fazer uma movimentação referente à visão do usuário, que foi
implementada em 1ª pessoa, e por meio do teclado, possibilitou-se a movimentação em um
plano paralelo ao XZ.
A movimentação da visão do usuário foi implementada por meio de rotações em
torno dos eixos X, Y e Z onde essas rotações são dadas por valores de variáveis globais.
Entretanto, optou-se por movimentar o mundo ao invés do observador, de forma que desse a
impressão de que o segundo estaria se movimentando, estando o observador sempre na
origem e assim facilitando algumas operações. Estas variáveis globais são modificadas da
seguinte maneira:
• São criadas duas variáveis globais: angley e anglev, onde a primeira marca o ângulo
com relação ao eixo Y, sendo considerado 0 em cima da parte negativa do eixo Y e o anglev
pode ser considerado como a combinação dos ângulos nos X e Z.
• Para movimentar a visão de forma correspondente a olhar para cima ou para baixo,
deve-se segurar o clique com o botão esquerdo e mover o mouse na direção vertical da tela
para cima e para baixo, de forma que uma função perceba a variação do posicionamento do
cursor do mouse e caso ela seja positiva ou negativa, irá aumentar ou diminuir
respectivamente o valor desta variável. Então, é chamada uma função de rotação da OpenGL
de forma que sejam rotacionados os valores cos(angley*PI/180) e sen(angle*PI/180) em
torno de X e de Z respectivamente, onde PI/180 é necessário para uma conversão do valor de
angley para radiano. O calculo uso das funções seno e co-seno são necessárias, para que haja
um equilíbrio da quantidade rotacionada em torno dos eixos X e Z, pois de outra forma,
poderia haver uma movimentação não vertical da visão.
• A movimento de olhar (ou girar o corpo, pois são a mesma operação) para esquerda
ou direita, é razoavelmente mais simples. Quando move-se o cursor do mouse com o botão
esquerdo pressionado para a esquerda ou direita da tela, testa-se se o posição horizontal do
mouse mudou e havendo uma nova posição aumentará o valor de angley e rotacionar-se-á em
torno do eixo Y um valor correspondente a variação no angley.
A movimentação do usuário, no sentido de locomover-se, que assim como a
movimentação da visão é relativa – o mundo move-se, é possível de quatro maneiras
diferentes:
• Pressionando a tecla “w” do teclado, tem-se o que pode se chamar de uma
movimentação frontal. O usuário se moverá paralelamente ao eixo XZ com base na direção e
sentido que ele olha, considerando-se apenas a componente horizontal, ou seja, a
movimentação será baseada no valor da variável global angley, pois ela mede a rotação atual
em torno do eixo Y. O seno e o co-seno de angley (em radianos) serão mais uma vez
utilizados, onde o seno de angley será acrescentado ao valor atual da posição do observador
em X, que é dado pela variável global posx e o co-seno será acrescentado ao valor atual da
variável global posz, que representa a posição do observador em Z. Dessa forma, andar-se-á
sempre uma unidade na direção em que o observador olha.
• Pressionando a tecla “s”, “a” e “d” temos, de forma similar, a movimentação na
direção em que o observador olha e na direção perpendicular à que o observador olha para à
esquerda e direita respectivamente.
3.2.2 Detecção de colisão
Para detectar colisão, desenvolveu-se funções de comparação entre às variáveis
globais posx e posz (que repesentam a posição relativa do observador com relação ao plano
XZ) e os pontos de cada uma das faces triangulares dos objetos que se deseja detectar, que
ficam armazenadas nas estruturas criadas no momento de importação.
Para a questão da movimentação, quando são pressionadas as teclas “w”, “a”, “d” e
“s”, são feitos testes de colisão em X e em Z antes e se acrescentar as variáveis posx e posz
respectivamente.
Um teste de colisão em Z é feita da seguinte forma:
• É passado para a função colisaoZ() os valores posx e posz, entretanto, o valor posz é
passado com o acrescimo da quantidade que se deseja andar em Z. É então testado para cada
face dos objetos escolhidos se o valor de posz está entre o menor e o maior valores de X nos
vértices da face acrescentados de -1.9 e +1.9 respectivamente (esse valores são usados para
garantir que não sejam atravessadas as quinas), se posz (acrescentado da quantidade que
deseja-se andar em Z) acrescentado de +2.5 for maior que a posição z da face e posz
(acrescentado da quantidade que deseja-se andar em Z) acrescentado de -2.5 for menor que a
posição z da face, então, se o objeto não estiver na altura do piso (caso em que é
desconsiderado) , é retornado 1, o que significa que há colisão.
• Para colisão em X, temos uma função colisaoX() que é similar a colisãoZ(), onde a
única diferença é que os testes feitos com posz e posx são invertidos.
Devido aos testes serem separados, a movimentação paralela à uma parede, por
exemplo, é ainda permitida no caso de o observador estar “encostado” nessa parede.
Após alguns testes, entretanto, notou-se que havia o problema de ficar travado em
algumas situações em que observador próximo ás quinas andasse rente à parede. Para
resolver isto, foi criado mais um teste após os citados acima. Esse teste verifica se a distância
à posição no eixo na direção do qual deseja mover-se (posx ou posz) sem o acréscimo da
quantidade que deseja-se andar à posição nesse eixo (X ou Z) é maior do que a distância
dessa posição acrescentada da quantidade que deseja-se andar, pois nesse caso, está
confirmada a colisão. Caso contrário, então considera-se que não há colisão, pois o
observador estaria se afastando da parede, por exemplo.
Foi também desenvolvido o teste de colisão para objetos os quais de deseja poder
atravessar, que é único para os dois movimentos (em X e Z). Ele tem semelhanças com as
funções acima, mas é mais simples, visto que importa apenas a posição atual sem nenhum
acréscimo ou decréscimo.
3.3 Modelagem
Como dito na seção 2, foi usado o Blender para a modelagem dos objetos e
exportação para o formato Wavefront. Os quais foram:
• Labirinto
• Esferas
• Porta da saída do labirinto
3.4 Aplicação
Utilizando o que foi feito nas etapas anteriores, importou-se o labirinto a porta de
saída e as esferas. Onde ao labirinto e à porta, foi aplicada a detecção de colisão em X e em
Z e às esferas, foi aplicada a colisão que permite atravessar às esferas.
A detecção de colisão da forma como foi organizada, teve a intenção de que o
observador tenha de atravessar o labirinto, que inicialmente tem apenas um acesso ao
mundo exterior, que é a entrada. No decorrer do percurso no labirinto, o usuário deverá
encontrar quatro esferas douradas para depois disso a porta do labirinto apareça, liberando
assim a saída.
Mapa do labirinto.
4. Resultados
Com o uso de todas as ferramentas e técnicas citadas, conseguiu-se chegar à
finalização da aplicação.
O resultado da aplicação pode ser visualizado nas seguintes imagens:
Imagem externa do labirinto.
Imagem dos muros.
Antes de pegar a quarta esfera que está na frente da porta.
Depois de pegar a quarta esfera a porta foi aberta.
5. Conclusão
Por fim, chega-se à conclusão de que dentro dos objetivos traçados houve um nível
satisfatório de êxito, tendo em vista que se consegui criar uma aplicação-exemplo em cima
das funções de interação que tiveram um nível razoável de generalidade.
Dessa forma, poder-se-á usar essas funções desenvolvidas para outras aplicações
futuras.
6. Bibliografia
6.1 Referências Bibliográficas
[1] Azevedo, E.; Conci, A. Computação Gráfica - Teoria e Prática; Campus, 2004.
[2] FV de Araújo, AZ Cordenosi, CU Franciscano – tise.cl
6.2 Referências Adicionais
Hearn, D.; Baker. Computer Graphics with OpenGL. Prentice Hall, 2003.
Woo, M.; Neider, J.; Davis, T.; Shreiner, D. OpenGL Programmin Guide, 3a edição. Addison
Wesley 1999.