Introdução
1. Elementos de Textura
2. Seleção via mouse
3. Download do Código Fonte
Conclusão
Dessa forma, este relatório será bem simples, consistindo de apenas 3 seções: a primeira, comenta os passos necessários
para inserir elementos de textura no jogo; a segunda, expõe o método que foi usado para fazer a seleção dos quadrantes
via mouse; e a terceira, disponibiliza o código fonte do jogo Batalha Naval.
Assim, optou-se por usar 3 tipos de texturas: uma para representar o oceano, como um todo, cobrindo toda a área do tabuleiro; outra para representar o fogo, que indicará os quadrantes acertados; e uma última para representar a água, simbolizando os quadrantes que receberam um tiro porém sem acertar nenhuma parte de navio.
Nesta etapa houve duas dificuldades: uma que envolveu uma maior complexidade para sua superação e outra mais simples. A mais complicada deve-se ao fato de OpenGL não trabalhar com os formatos de imagem mais utilizados, como bmp, jpg e png. Dessa forma, as funções que fazem o mapeamento de texturas em OpegnGL consideram, como parâmetro da função glTexImage2D(), uma matriz de pixels em formato interno RGB ou RGBA, deixando para o usuário a tarefa de ler uma imagem e obter essa matriz.
Para resolver este problema, o aluno Adler Cardoso indicou o site www.dca.ufrn.br/~ambj, no qual havia um exemplo de texturas em que o autor (Agostinho de Medeiros Brito Júnior) utiliza uma função que lê imagens com a extensão .RGB. Contudo, esta extensão não é suportada pelos principais softwares de foto, como Paint, Imaging e PhotoShop. Logo, foi preciso converter a textura que se tinha, a qual estava no formato BMP, para o formato RGB (extensão), usando o software 3D Max Studio.
A esta altura, o processo de texturização já funcionava corretamente, porém, o aluno Carlos Henrique indicou uma biblioteca que processa a leitura do formato BMP diretamente(loadimage.h) e, assim, optou-se por mudar essa leitura para tornar o código mais re-usável. Este encaminhamento mostrou-se o mais acertado principalmente após os testes com vários tipos de texturas, no formato BMP, que permitiram notar diferentes resultados e a conveniência de não demandar a conversão prévia.
A segunda dificuldade diz respeito ao fato de a textura alterar as cores dos navios, modificando-os por completo. Para resolver este problema, foi utilizado a função glTexEnvf(), a qual possui como último argumento um parâmetro que modifica os modos com que a textura interage com as superfícies da cena. Foram testados para este argumento os seguintes parâmetros: GL_DECAL, GL_REPLACE, GL_MODULATE, GL_BLEND, GL_ADD e GL_COMBINE, e desta forma, notou-se que GL_MODULATE era o que melhor mantinha as cores originais, logo, optou-se por ele.
Antes de mostrar algumas imagens do processo de texturização, é interessante também comentar que para o processo ser feito com êxito, é necessário que a imagem que representa a textura seja de ordem quadrática de pixels e, ainda, seja potência de 2. Segundo o Red Book, é aconselhável que essa ordem seja 64x64, 128x128, ou, no máximo, 256x256.
A seguir, são expostas algumas imagens do processo de texturização:
Assim, a grande dificuldade deste passo foi conseguir atirar nos quadrantes, mesmo com o tabuleiro rotacionado. Para resolver isso, inicialmente, usou-se a função gluUnProject(), a qual faz a projeção inversa em relação a matriz de projeção armazenada. Assim, os pontos da tela poderiam ser relacionados com os pontos tridimensionais e o problema seria resolvido. Contudo, tal método apresentou algumas imprecisões, até mesmo para quando o tabuleiro não possui uma grande inclinação. Como uma alternativa, tentou-se usar uma função de inversão de matrizes da biblioteca math.h. Mesmo assim, a imprecisão continuava.
A solução foi usar a função gluPickMatrix(), a qual define uma sub-área na tela centrada a partir do clique do mouse. Esta função trabalha definindo, antes de chamá-la, uma matriz de buffer, a qual é indicada através da função glSelectBuffer(), e serve para armazenar os identificadores pré-definidos. Estes elementos são aqueles em que se está interessado em identificar, que são definidos através dos comandos glLoadName() e glPushName(), que devem ser usados no modo GL_SELECT. No caso do jogo, cada quadrante corresponde a um identificador, indo de 00, até 99. É interessante dizer também que, antes de atribuir os valores aos identificadores, os comandos glInitNames() e glPushName(0) precisam ser chamados para uma inicialização da pilha.
Infelizmente, não foi possível ilustrar esse processo com telas capturadas, pois a tecla Print Screen não salva a posição do mouse na tela, logo, não daria para saber apenas pela imagem se o tiro foi dado via teclado ou cursor.
Além disso, uma das principais vantagens da textura, que é o aumento do realismo, foi observada na prática, pois com o uso de texturas têm-se praticamente um novo jogo. Não que este seja próximo de uma verdadeira batalha naval, mas está muito mais próximo do visual de um jogo comercial do que a versão anterior. Contudo, é necessário dizer que até então, o jogo rodava de maneira muito leve e, agora, ele já começa a mostrar-se um pouco pesado. Teoricamente, isso não deveria acontecer, pois trata-se de um jogo muito simples, todavia, poderia se comparar o benefício do custo computacional que está relacionado ao uso de texturas somente se modelar-se a cena com os mesmo aspectos visuais da textura, porém sem ela, o que logicamente, mostraria diferenças gritantes, pois é óbvio que uma cena sem texturas roda mais rápido do que uma com texturas.
De uma maneira geral, dado o término do projeto, foi possível aprender muitos recursos interessantes do OpenGL, como também constatar que falta ainda uma gama muito grande de conhecimentos, situando o conhecimento adquirido no nível básico de utilização da biblioteca. Um aspecto interessante e estimulante do projeto é que ficou evidenciado que não é preciso ser um artista gráfico para fazer um jogo, basta ter criatividade e conhecimentos de computação, que a estrutura do jogo pode ser definida. É claro que modelos geométricos de um artista sempre são bem vindos, porém, esta é apenas uma das muitas partes que compõem um jogo, sendo necessário também aprender a programar a lógica, o cenário, a iluminação e menus dos jogos, os quais pode-se pensar sem grandes efeitos.