Estás haciendo un motor 3d. Quieres lo mejor de los mundos multiplataforma. De repente, se da cuenta de que si desea utilizar Direct3D en máquinas con Windows y OpenGL en OSX / Linux, tendrá que sacrificar las características compatibles de ambos al mínimo común denominador.
Algunos pueden usar OpenGL en tres SO ', ya que parece ser el mínimo común denominador en sí mismo. Todo es bueno. Luego, debe portar su backend de API de gráficos al GX de Nintendo, también debe hacer una ruta de PS3 y Xbox360.
¿Qué haces? ¿Diseña su propia API que es el mínimo común denominador en sí mismo y escribe implementaciones de back-end para cada plataforma o escribe para cada plataforma su propia rama?
Si opta por diseñar su propia API, ¿utiliza el patrón de puente o su propio vudú? ¿Dónde se detiene la locura donde te das cuenta de todo y el enfoque del fregadero de la cocina debe detenerse y básicamente tienes un motor separado para cada plataforma como una rama? O se adhiere a todo y al fregadero de la cocina y mantiene los detalles de la plataforma en las especializaciones de módulos de back-end para cada plataforma.
Todo lo que puedo decir es echar un vistazo a Ogre3D . Está escrito en C ++, código abierto (licencia MIT ahora) y se ejecuta en todas las plataformas principales listas para usar. Resume la API de representación y puede cambiar de usar DirectX a OpenGL con solo un par de configuraciones. Sin embargo, no sé lo suficiente sobre las diferencias entre los conjuntos de características de DirectX y OpenGL para decir que admite o no una característica específica.
Torchlight de Runic Games fue escrito usando Ogre y lo he jugado en Mac y PC y funciona muy bien en ambos.
fuente
No he hecho esto para gráficos, pero creé un kit de herramientas de audio multiplataforma (PC / XBOX / PS2). Tomamos la ruta de crear nuestra propia API con una capacidad de denominador menos común, así como capacidades opcionales específicas de la plataforma. Aquí hay algunas lecciones aprendidas:
La clave es definir una ruta de procesamiento que encapsule las capacidades centrales de cada plataforma y permita el crecimiento. Para hacer esto, debe comprender realmente la API de bajo nivel de cada plataforma para poder identificar las abstracciones correctas. Asegúrese de que la cadena funcione para la plataforma menos capaz, al tiempo que proporciona acceso a las funciones avanzadas de la plataforma más capaz. Haga el trabajo para hacerlo bien y ahorrará mucho esfuerzo más adelante.
Para el audio, la cadena era algo así
SoundSources -> [Decoders] -> Buffers -> [3D Positioner] ->[Effects] -> Players
.Para los gráficos, puede ser
Model -> Shapes -> Positioner -> Texturer -> [Lighting] -> [Particle Effects] -> Renderer
. (Este es probablemente un conjunto completamente incorrecto, no soy un tipo de gráficos).Escriba una API de front-end que maneje sus objetos principales y una back-end específica de la plataforma que asigne la API a las capacidades de bajo nivel. Proporcione el mejor esfuerzo para cada capacidad. Por ejemplo, en la PC y XBOX, el posicionamiento de audio en 3D se realizó utilizando las capacidades HRTF de los chips de sonido, mientras que PS2 usó un simple pan y fade. Un motor gráfico puede hacer algo similar con la iluminación.
Implemente la mayor cantidad de front-end posible con el código neutral de la plataforma. El código para adjuntar un objeto de reverberación a un objeto de sonido o un activo de textura a un objeto de forma debe ser completamente común, al igual que el código para iterar y procesar objetos activos. Por otro lado, los objetos de bajo nivel pueden ser completamente específicos de la plataforma, excepto por la interfaz común.
Asegúrese de que la API, o los archivos de configuración, permitan al usuario especificar opciones específicas de la plataforma. Intentamos evitar empujar el código específico de la plataforma al nivel del juego manteniéndolo en archivos de configuración: el archivo de configuración de una plataforma puede especificar "efecto: SuperDuperParticleGenerator" mientras que otro dice "efecto: SoftGlow"
Definitivamente desarrollar las plataformas en paralelo. Asegúrese de que las interfaces específicas de la plataforma estén bien definidas y se puedan probar por sí mismas. Esto evita mucho de "¿es el nivel de plataforma o el nivel de API?" problemas al depurar.
fuente
Estoy escribiendo un motor de juegos de código abierto llamado YoghurtGum para plataformas móviles (Windows Mobile, Android). Este fue uno de mis grandes y grandes problemas. Primero lo resolví así:
¿Viste el
void*
? Esto se debe a queRenderMethodDirectDraw
devuelve una superficie DirectDraw mientrasRenderMethodDirect3D
devuelve un grupo de vértices. Todo lo demás también estaba dividido. Tuve unaSprite
clase que tenía unSpriteDirectDraw
puntero o unSpriteDirect3D
puntero. Es un poco horrible.Así que últimamente, he estado reescribiendo muchas cosas. Lo que tengo ahora es a
RenderMethodDirectDraw.dll
y aRenderMethodDirect3D.dll
. De hecho, puede intentar usar Direct3D, fallar y usar DirectDraw en su lugar. Eso es porque la API sigue siendo la misma.Si quieres crear un sprite, no lo haces directamente sino a través de una fábrica. Luego, la fábrica llama a la función correcta en la DLL y la convierte en una matriz.
Entonces, esto está en la
RenderMethod
API:Y esta es la definición en
RenderMethodDirectDraw
:Espero que esto tenga sentido. :)
PD: Me encantaría haber usado STL para esto, pero no hay soporte en Android. :(
Básicamente:
EDITAR: Sí, tiene sentido tener interfaces virtuales como esta. Si su primer intento falla, puede probar con otro método de renderizado. De esta manera, puede mantener agnóstico todo su método de representación de código.
fuente
Me gusta usar SDL para esto. Tiene backends de renderizador para D3D, OpenGl, OpenGL ES y un puñado de otros backends específicos de plataforma, y está disponible para todo tipo de plataformas diferentes, y actualmente en desarrollo activo, con enlaces a muchos idiomas diferentes disponibles.
Resume los diferentes conceptos de renderizador y hace que la creación de video (así como el manejo de sonido y entrada y algunas otras cosas) esté disponible en una API simple y multiplataforma. Y fue diseñado por Sam Lantinga, uno de los principales desarrolladores de Blizzard, específicamente para facilitar la transferencia de juegos y crear juegos multiplataforma, para que sepa que se trata de una biblioteca de alta calidad.
fuente