quinta-feira, 3 de novembro de 2011

Inicializando os Gráficos: Janela e Contexto 3D

Comecei escrever o código de uma engine. Minhas expectativas são:
  • Utilizarei C++ para o core;
  • Utilizarei TDD;
  • Multi-plataforma;
  • Altamente modular;
Quero aprender TDD, então nada melhor do que aplicar o conceito na prática. Além disso, quero utilizá-lo da forma mais xiita, ou seja, escrever sempre um teste que justifique a mudança do código. No início esta condição parece bastante extrema, mas é uma forma muito útil de você pensar em design antes de codificar qualquer coisa. Realmente sinto que demoro mais para fazer algo desta forma, mas o que é feito se torna mais consistente.

Não pretendo escrever código multi-plataforma de cara, mas pretendo escrevê-lo de uma forma que este trabalho seja facilitado no futuro. Inicialmente irei focar em OpenGL e utilizarei o SO Linux.

Finalmente, quando digo que o código será altamente modular, significa que quero diminuir ao máximo o acoplamento entre as classes / módulos da engine.

Comecei a escrever um pouquinho de código e já tenho encontrado dificuldades. Inicialmente quero realizar 3 tarefas:
  1. Criar uma janela no X11;
  2. Criar um contexto OpenGL;
  3. Ter uma interface para adicionar este contexto a uma janela;
Para realizar esta tarefa necessito de uma conexão com o X11. Realizar tal tarefa é trivial, porém este recurso será necessário em diversos pontos da aplicação, o que me leva a pensar no padrão Singleton.

Esta solução me deixa com uma pulga atrás da orelha, pois na criação de um objeto que represente uma janela, precisarei ter acesso a conexão com o servidor gráfico, que me leva a necessidade de criar uma interface para acessar esta propriedade. Tal organização expõe um conceito  do ambiente de execução na interface entre duas classes, o que não é legal para uma solução multi-plataforma.

Uma solução seria tornar o Singleton que representa a conexão com o servidor gráfico em uma fábrica de janelas e contextos, porém uma janela também não poderia ter uma interface para adicionar um contexto a ela, pois isto também iria expor detalhes da implementação de OpenGL, que no caso do X11 utiliza a extensão GLX. Espero que o ponto já esteja claro, ou seja, escrever uma biblioteca que não deixe "vazar" informações de seu ambiente é difícil, ainda mais quando os recursos são complexos.

Estas dificuldades me levaram ao livro Cross-Platform Development in C++. Através dele pude perceber que a tarefa é realmente difícil e exige bastante conhecimento. Desta forma começo a duvidar se estou seguindo pelo caminho certo, pois se continuar neste ritmo começarei a escrever algo do jogo só em 2020 :).

Irei me aprofundar no assunto, mas ao mesmo tempo irei analisar algumas bibliotecas que forneçam um ambiente multi-plataforma básico para o desenvolvimento de um jogo e que com certeza será assunto para um próximo post.