Al crear una abstracción del sistema, es mejor tener las API diferentes de la plataforma ocultas por una interfaz común en el nivel más bajo que tenga sentido.
Teniendo en cuenta las diferentes API de gráficos nativos modernos (sin canalización de función fija): OpenGLES 2.0+, OpengGL 3.0+, DirectX 10.0+, Xbox DirectX 9, LibGCM
Si uno fuera a crear una API gráfica de bajo nivel sin estado para sentarse sobre todos ellos, ¿cuál sería la mejor manera de hacerlo para que sea lo más delgado y rápido posible?
architecture
software-engineering
graphics
cross-platform
NocturnDragon
fuente
fuente
Respuestas:
El nivel más bajo que tiene sentido desde mi punto de vista es algo que habla de los recursos involucrados en el renderizado: vb / ib, superficies de renderizado, texturas, sombreadores, bloques de estado, etc.
El problema aquí es que algunos de estos deben estar en diferentes formatos, dependiendo de la API; ahí es donde se vuelve un poco complicado. La forma más fácil de evitarlo es preprocesar los recursos estáticos para la API respectiva. Para los dinámicos, use solo sombreadores para generarlos, lo que hace que sea bastante sencillo permanecer en formatos nativos.
Todo lo que haces en el nivel superior es configurar tuberías con recursos adjuntos y entregarlas a la GPU. Descubrirá que no todo se puede resumir de esa manera, especialmente si aprovecha los trucos específicos del hardware. Pero es un buen comienzo.
(Nota al margen: si trata los trucos específicos de la plataforma como un tipo especial de recurso, puede llevar todo este concepto bastante lejos).
Entonces, de alguna manera, creará dos cosas: un administrador de recursos de hardware, más un kit de herramientas para configurar un DAG de estos recursos.
fuente
Dada la amplia gama de API que desea cubrir, es probable que el enfoque de ajuste típico sea ineficiente y propenso a la dificultad de mapear conceptos de API en varias otras API que pueden o no admitir funciones particulares en diversos grados.
Como resultado, el enfoque más sensato sería crear una API centrada en características . Si bien este enfoque evita que el usuario de la API utilice todas las funciones disponibles, simplifica enormemente la implementación de cada back-end y permite optimizaciones específicas de back-end que de otro modo no serían posibles.
También simplifica enormemente la administración de funcionalidades no compatibles para el usuario de la API; ya no tienen que verificar si la función X existe y determinar qué características están afectadas, sino que solo necesitan consultar la característica en sí para ver si es compatible con la configuración actual. Incluso si admite modos parciales o limitados para las características, el contexto proporcionado hace que sea mucho más fácil de administrar.
En términos de crear un renderizador sin estado (también conocido como basado en el envío ), normalmente se usa una clave de 64 bits para empaquetar y enviar comandos para el procesamiento. A partir de ese momento, existe una gran flexibilidad en términos de cómo ejecutar comandos y qué información enviar dependiendo de las características y capacidades que desee admitir.
fuente
Para empezar, cada API hace las cosas de manera diferente, por lo que debería ser evidente que sería difícil ajustar todas las API anteriores. Dicho esto, a veces es necesario hacerlo: en algún momento un juego simplemente necesita ejecutarse en más de una plataforma, independientemente de lo difícil que sea hacerlo.
Creo que la mejor manera de hacerlo es idear la funcionalidad que se puede implementar en todas las API subyacentes y resumir eso y solo eso. Si está desarrollando un juego multiplataforma, no implementaría todas las funciones oscuras que admite cada API, solo implementaría lo que necesita. Esto también ayuda a mantener la API pequeña y rápida.
Para evitar el desorden de la implementación de cada API diferente que se empaqueta en la salida, la compilación debe hacerse con archivos de encabezado neutral de plataforma y archivos de código específicos de plataforma. Entonces, el archivo de código específico para la plataforma de destino sería el único compilado que mantiene la API pequeña.
fuente
Hay un artículo sobre GPU Pro sobre esto, por Emil Persson (Humus)
http://gpupro.blogspot.com/2009/12/making-it-large-beautiful-fast-and.html
fuente
Es posible que desee consultar la biblioteca SDL o Allegro . Ambas son bibliotecas de juegos de bajo nivel y altamente portátiles, que tienen una forma de conectarlas en un contexto OpenGL para que pueda renderizar sus gráficos allí. SDL tiene la fama de ser utilizado por Loki Games para portar algunos juegos populares de la década de 2000 a Linux, y Allegro tiene mucho tiempo funcionando y tiene una gran comunidad de desarrolladores de juegos aficionados.
fuente