Ao criar uma abstração do sistema, é melhor ter APIs diferentes da plataforma ocultas por uma interface comum no nível mais baixo que faça sentido.
Levando em conta as diferentes APIs nativas modernas (sem pipeline de função fixa): OpenGLES 2.0+, OpengGL 3.0+, DirectX 10.0+, Xbox DirectX 9, LibGCM
Se alguém criasse uma API gráfica de baixo nível sem estado para ficar em cima de todas, qual seria a melhor maneira de torná-la a mais fina e rápida possível?
architecture
software-engineering
graphics
cross-platform
NocturnDragon
fonte
fonte
Respostas:
O nível mais baixo que faz sentido do meu ponto de vista é algo que fala sobre os recursos envolvidos na renderização - vb / ib, superfícies de renderização, texturas, shaders, blocos de estado etc.
O problema aqui é que alguns deles precisam estar em formatos diferentes, dependendo da API - é aí que fica um pouco complicado. A maneira mais fácil de contornar isso é pré-processar os recursos estáticos para a respectiva API. Para os dinâmicos, use apenas shaders para gerá-los - o que torna bastante simples permanecer em formatos nativos.
Tudo o que você faz no nível superior é configurar pipelines com recursos anexados e entregá-los à GPU. Você descobrirá que nem tudo pode ser abstraído dessa maneira, especialmente se você aproveitar os truques específicos do hardware. Mas é um bom começo.
(Nota: se você tratar os truques específicos da plataforma como um tipo especial de recurso, poderá levar esse conceito muito longe).
Então, de certa forma, você criará duas coisas: um gerenciador de recursos de hardware, além de um kit de ferramentas para configurar um DAG desses recursos.
fonte
Dada a ampla variedade de APIs que você deseja cobrir, é provável que a abordagem típica de agrupamento seja ineficiente e propensa a dificuldades no mapeamento de conceitos de API em várias outras APIs que podem ou não suportar funções específicas em graus variados.
Como resultado, a abordagem mais sensata seria criar uma API centrada em recursos . Embora essa abordagem impeça o usuário da API de utilizar todas as funcionalidades disponíveis, ela simplifica bastante a implementação de cada back-end e permite otimizações específicas de back-end que, de outra forma, não seriam possíveis.
Também simplifica bastante o gerenciamento de funcionalidades não suportadas pelo usuário da API; eles não precisam mais verificar se a função X existe e determinar quais recursos são afetados, mas precisam apenas consultar o próprio recurso para ver se ele é suportado pela configuração atual. Mesmo se você suportar modos parciais ou limitados para recursos, o contexto fornecido facilita muito o gerenciamento.
Em termos de criação de um renderizador sem estado (também conhecido como baseado em envio ), normalmente uma chave de 64 bits é usada para compactar e enviar comandos para renderização. A partir desse ponto, há muita flexibilidade em termos de como executar comandos e quais informações enviar, dependendo dos recursos e recursos que você deseja oferecer suporte.
fonte
Para começar, cada API faz as coisas de maneira diferente; portanto, não é necessário dizer que seria difícil agrupar todas as APIs acima. Dito isto, às vezes é necessário fazê-lo: em algum momento, um jogo simplesmente precisa ser executado em mais de uma plataforma, independentemente da dificuldade que é fazer.
Eu acho que a melhor maneira de fazer isso é criar a funcionalidade que pode ser implementada em todas as APIs subjacentes e abstrair isso e somente isso. Se você estiver desenvolvendo um jogo multiplataforma, não implementaria todas as funcionalidades obscuras suportadas por cada API, apenas implementaria o que precisa. Isso também ajuda a manter a API pequena e rápida.
Para evitar que a desordem da implementação de cada API diferente seja compactada na saída, a compilação deve ser feita com arquivos de cabeçalho neutros da plataforma e arquivos de código específicos da plataforma. Em seguida, o arquivo de código específico para a plataforma de destino seria o único compilado mantendo a API pequena.
fonte
Há um artigo no GPU Pro sobre isso, de Emil Persson (Humus)
http://gpupro.blogspot.com/2009/12/making-it-large-beautiful-fast-and.html
fonte
Você pode querer verificar a biblioteca SDL ou Allegro . Ambas são bibliotecas de jogos de baixo nível e altamente portáteis, que têm uma maneira de conectá-las a um contexto OpenGL para que você possa renderizar seus gráficos lá. SDL tem a fama de ser usado por ele extinto Loki Games para portar alguns jogos populares dos anos 2000 para Linux, e Allegro tem muito tempo correndo e tem uma grande comunidade de desenvolvedores de jogos amadores.
fonte