24
HUGO IMPERIANO NÓBREGA 10711467 INTRODUÇÃO À COMPUTAÇÃO GRÁFICA

Relatório

Embed Size (px)

Citation preview

Page 1: Relatório

HUGO IMPERIANO NÓBREGA 10711467

INTRODUÇÃO À COMPUTAÇÃO GRÁFICA

JOÃO PESSOA

2008

Page 2: Relatório

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

Page 3: Relatório

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

Page 4: Relatório

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

Page 5: Relatório

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

Page 6: Relatório

• 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.

Page 7: Relatório

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

Page 8: Relatório

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.

Page 9: Relatório

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

Page 10: Relatório

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.

Page 11: Relatório

• 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.

Page 12: Relatório

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

Page 13: Relatório

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

Page 14: Relatório

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:

Page 15: Relatório

Imagem externa do labirinto.

Imagem dos muros.

Page 16: Relatório

Antes de pegar a quarta esfera que está na frente da porta.

Depois de pegar a quarta esfera a porta foi aberta.

Page 17: Relatório

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

Page 18: Relatório

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.