Wadlib

abril 15, 2011

Algumas semanas atrás, numa noite de insônia comecei um projeto por diversão que acabou evoluindo um pouco mais do que eu esperava, numa das minhas recaídas para jogar Doom resolvi dar uma fuçada nos arquivos Wad, que são os arquivos, ou melhor, o arquivo onde o Doom armazena todos os seus dados.

Consegui encontrar um bocado de documentação na web e depois de uns 40 minutos programando fiz um carregador básico de mapas de Doom em SDL:

Primeira versão do visualizador de mapas, linhas vermelhas são linhas que dividem setores

A partir disso acabei criando um projeto no Google Code chamado Wadlib, que tem como objetivo ser uma biblioteca para converter dados do Doom para formatos mais modernos.

Atualmente a Wadlib é formada por dois projetos: uma biblioteca para manipulaçao de arquivos wad, mais precisamente, leitura de arquivos wad e um “viewer” em SDL que permite visualizar os mapas em 2D e exportar texturas para formato bmp.

Objetivos

A minha principal meta com o projeto é fazer uma ferramenta que converta mapas do Doom para um formato de malha que possa ser usado motores modernos, no meu caso pretendo gerar malhas no formato usado pelo Ogre e no meu projeto de motor de jogo, devagar quase parando, Phobos.

Alias, quando o Phobos foi criado nunca me passou pela cabeça essa idéia de usar mapas do Doom, a escolha do nome foi apenas uma pequena homenagem Smile.

Além de gerar as malhas pretendo fazer um “plugin” para o exportador gerar um projeto para o Ogitor (que é o formato de nível que o Phobos atualmente suporta), assim poderei editar e modificar o nível para customizar o que for preciso.

O exportador também em algum ponto não vai apenas gerar uma malha única para todo o nível, pretendo separar portas, elevadores e tudo mais que se movimenta no Doom (que até onde me lembro era apenas isso) em malhas separadas, assim vai ser possível implementar elevadores e portas no Phobos ou em algum outro motor.

Desempenho

Aqueles que conhecem um pouco do funcionamento do Doom devem estar se dizendo: “Mas transformar isso numa malha vai ser absurdamente lento”. Realmente, se compararmos com o motor original do Doom que fazia todo aquele trabalho de culling vai ficar mesmo um lixo renderizar o cenário todo, mas levando em conta nossas GPUs de hoje e a pequena quantidade de polígonos que vão ser gerados, isso certamente não vai ser problema.

Futuramente se o projeto continuar crescendo, quem sabe não vale a pena gerar zonas e subdividir o nível usando portais e gerar cenas usando o Portal Connected Zone Manager.

Outra idéia é criar um SceneManager para o Ogre especifico para Doom, assim como o SceneManager de mapas de Quake, mas esse já é um projeto que eu não tenho tanto interesse em tocar, voluntários?

Texturas

Para gerar as malhas com os níveis do Doom e poder renderizar elas com um mínimo de qualidade pretendo também usar as texturas, para isso a wadlib precisa carregar e exportar as texturas para um formato que possa ser usado.

Logo após fazer o load do nível funcionar, comecei a analisar as texturas e o mais simples no inicio foi trabalhar com os “Flats”, que é o nome dado as texturas usadas no chão e teto dos níveis. Essa texturas são todas de tamanho 64×64 e são armazenadas em “raw format”, basta então localizar elas dentro do wad e copiar para um buffer de bmp, junto com palheta e pronto.

No ultimo final de semana resolvi trabalhar com as texturas das paredes, chamadas de “Walls”, estas deram um pouco mais de trabalho, pois o formato é meio chato de entender e a documentação que encontrei um tanto confusa.

As texturas de parede são subdividas em Patches, que é como se fossem sub-texturas que juntas formam a textura final. Cada patch possui uma lista de colunas de pixels, pois estas são armazenadas num formato coluna x linha, diferente do tradicional onde imagens são no formato linha x coluna, isso ajuda em muito o renderizador do Doom, que desenhava paredes coluna a coluna e era um dos segredos do bom desempenho do Doom.

Cada coluna ou Post, como é chamado no motor, possui um número indicando a quantidade de pixels, um offset dela e os pixels. A parte chata é que pixels transparentes não são armazenados, então é preciso tratar isso no código e preencher esses espaços em branco, que o Doom simplesmente pulava para deixar a parede transparente.

Feito isso, o resultado pode ser visto abaixo:

Texturas exportadas do Doom

Próximos Passos

Na próxima etapa do projeto pretendo finalmente começar a gerar os arquivos mesh do Ogre, na sequência gerar os materiais no formato do Ogre e os arquivos de projeto para Ogitor, mas falta surgir tempo livre para isso ou falta de sono Smile.

Anúncios