Você está criando um mecanismo 3D. Você quer o melhor dos mundos multiplataforma. De repente, você percebe que, se quiser usar o Direct3D em máquinas Windows e o OpenGL no OSX / Linux, terá que sacrificar os recursos suportados pelo denominador menos comum.
Alguns podem usar o OpenGL em três sistemas operacionais ', pois parece ser o denominador menos comum por si só. Tudo está bem. Em seguida, você deve portar o back-end da API de gráficos para o GX da Nintendo, além de criar um caminho para PS3 e Xbox360.
O que você faz? Você cria sua própria API, que é o denominador menos comum em si mesma, e cria implementações de back-end para cada plataforma ou escreve para cada plataforma de sua própria filial?
Se você optar por projetar sua própria API, usa padrão de ponte ou seu próprio vodu? Onde a loucura para onde você percebe que tudo e a abordagem da pia da cozinha devem parar e você basicamente tem um mecanismo separado para cada plataforma como um ramo. Ou você se apega a tudo e à pia da cozinha e mantém os detalhes da plataforma nas especializações dos módulos de back-end para cada plataforma.
Tudo o que posso dizer é dar uma olhada no Ogre3D . Está escrito em C ++, código aberto (licença MIT agora) e é executado em todas as principais plataformas prontas para uso. Ele abstrai a API de renderização e pode mudar do DirectX para o OpenGL com apenas algumas configurações. No entanto, não sei o suficiente sobre as diferenças entre os conjuntos de recursos do DirectX e do OpenGL para dizer que ele suporta ou não um recurso específico.
O Torchlight da Runic Games foi escrito usando o Ogre e eu joguei isso no Mac e no PC e funciona muito bem em ambos.
fonte
Não fiz isso para gráficos, mas criei um kit de ferramentas de áudio para várias plataformas (PC / XBOX / PS2). Seguimos o caminho de criar nossa própria API com um recurso de denominador menos comum e recursos específicos de plataforma opcionais. Aqui estão algumas lições aprendidas:
A chave é definir um caminho de processamento que encapsule os principais recursos de cada plataforma e permita o crescimento. Para fazer isso, você precisa realmente entender a API de baixo nível de cada plataforma para poder identificar as abstrações corretas. Certifique-se de que a cadeia funcione para a plataforma menos capaz, enquanto fornece acesso aos recursos avançados da forma mais adequada. Faça o trabalho para corrigir isso e você economizará muito esforço mais tarde.
Para o áudio, a cadeia era algo parecido
SoundSources -> [Decoders] -> Buffers -> [3D Positioner] ->[Effects] -> Players
.Para gráficos, pode ser
Model -> Shapes -> Positioner -> Texturer -> [Lighting] -> [Particle Effects] -> Renderer
. (Este é provavelmente um cenário completamente errado, eu não sou um cara gráfico).Escreva uma API de front-end que lide com seus objetos principais e um back-end específico da plataforma que mapeie a API para os recursos de baixo nível. Forneça o melhor esforço para cada recurso. Por exemplo, no PC e no XBOX, o posicionamento do áudio 3D foi feito usando os recursos HRTF dos chips de som, enquanto o PS2 usou um pan e fade simples. Um mecanismo gráfico pode fazer algo semelhante com a iluminação.
Implemente o máximo possível do front end com código neutro de plataforma. O código para anexar um objeto de reverberação a um objeto de som ou um recurso de textura para um objeto de forma deve ser completamente comum, assim como o código para iterar e processar objetos ativos. Por outro lado, os objetos de baixo nível podem ser completamente específicos da plataforma, exceto a interface comum.
Verifique se a API ou os arquivos de configuração permitem ao usuário especificar opções específicas da plataforma. Tentamos evitar levar o código específico da plataforma ao nível do jogo, mantendo-o nos arquivos de configuração: o arquivo de configuração de uma plataforma pode especificar "effect: SuperDuperParticleGenerator", enquanto outro diz "effect: SoftGlow"
Definitivamente desenvolva as plataformas em paralelo. Verifique se as interfaces específicas da plataforma estão bem definidas e testáveis por conta própria. Isso impede muito do "é o nível da plataforma ou da API?" problemas ao depurar.
fonte
Estou escrevendo um mecanismo de jogo de código aberto chamado YoghurtGum para plataformas móveis (Windows Mobile, Android). Esse foi um dos meus grandes problemas. Primeiro eu resolvi assim:
Você viu o
void*
? IssoRenderMethodDirectDraw
ocorre porque retorna uma superfície DirectDraw eRenderMethodDirect3D
retorna um pool de vértices. Todo o resto foi dividido também. Eu tive umaSprite
aula que tinha umSpriteDirectDraw
ponteiro ou umSpriteDirect3D
ponteiro. Isso meio que sugou.Ultimamente, tenho reescrito bastante as coisas. O que eu tenho agora é um
RenderMethodDirectDraw.dll
e umRenderMethodDirect3D.dll
. Na verdade, você pode tentar usar o Direct3D, falhar e usar o DirectDraw. Isso ocorre porque a API permanece a mesma.Se você deseja criar um sprite, não o faz diretamente, mas através de uma fábrica. A fábrica chama a função correta na DLL e a converte em um pai.
Então, isso está na
RenderMethod
API:E esta é a definição em
RenderMethodDirectDraw
:Espero que isto faça sentido. :)
PS: Eu adoraria ter usado o STL para isso, mas não há suporte no Android. :(
Basicamente:
EDIT: Sim, faz sentido ter interfaces virtuais como esta. Se sua primeira tentativa falhar, você pode tentar outro método de renderização. Dessa forma, você pode manter todo o seu método de renderização de código independente.
fonte
Eu gosto de usar SDL para isso. Possui backend de renderizador para D3D, OpenGl, OpenGL ES e vários outros backends específicos de plataforma, e está disponível para todos os tipos de plataformas diferentes, e atualmente em desenvolvimento ativo, com ligações para vários idiomas diferentes disponíveis.
Ele abstrai os diferentes conceitos de renderizador e disponibiliza a criação de vídeo (além de lidar com som e entrada e algumas outras coisas) em uma API simples e multiplataforma. E foi projetado por Sam Lantinga, um dos principais desenvolvedores da Blizzard, especificamente para facilitar a portabilidade de jogos e a criação de jogos de plataforma cruzada, para que você saiba que está lidando com uma biblioteca de alta qualidade.
fonte