Vous faites un moteur 3D. Vous voulez le meilleur des mondes multiplateformes. Soudain, vous réalisez que si vous souhaitez utiliser Direct3D sur les machines Windows et OpenGL sur OSX / Linux, vous devrez sacrifier les fonctionnalités prises en charge des deux au plus petit dénominateur commun.
Certains peuvent utiliser OpenGL sur trois systèmes d'exploitation, car il semble être le dénominateur le moins commun en soi. Tout est bon. Ensuite, vous devez porter votre backend API graphique sur le GX de Nintendo, vous devez également créer un chemin PS3 et Xbox360.
Que faire? Concevez-vous votre propre API qui est le dénominateur le moins commun en soi et écrivez-vous des implémentations backend pour chaque plate-forme ou écrivez-vous pour chaque plate-forme sa propre branche?
Si vous choisissez de concevoir votre propre API, utilisez-vous un modèle de pont ou votre propre vaudou? Où la folie s'arrête-t-elle là où vous réalisez tout et l'approche d'évier de cuisine doit s'arrêter et vous avez essentiellement un moteur séparé pour chaque plate-forme en tant que branche. Ou vous vous en tenez à tout et à l'évier de cuisine et conservez les spécificités de la plate-forme dans les spécialisations du module backend pour chaque plate-forme.
Tout ce que je peux dire, c'est jeter un œil à Ogre3D . Il est écrit en C ++, Open source (licence MIT maintenant) et fonctionne sur toutes les principales plates-formes. Il résume l'API de rendu et peut passer de l'utilisation de DirectX à OpenGL avec seulement quelques paramètres. Cependant, je ne connais pas suffisamment les différences entre les ensembles de fonctionnalités de DirectX et d'OpenGL pour dire qu'il prend ou ne prend pas en charge une fonctionnalité spécifique.
Torchlight par Runic Games a été écrit en utilisant Ogre et j'ai joué sur Mac et PC et il fonctionne très bien sur les deux.
la source
Je n'ai pas fait cela pour les graphiques, mais j'ai créé une boîte à outils audio multiplateforme (PC / XBOX / PS2). Nous avons opté pour la création de notre propre API avec une capacité de dénominateur le moins commun ainsi que des capacités spécifiques à la plate-forme en option. Voici quelques leçons apprises:
La clé est de définir un chemin de traitement qui encapsule les capacités de base de chaque plate-forme et permet la croissance. Pour ce faire, vous devez vraiment comprendre l'API de bas niveau de chaque plate-forme afin de pouvoir identifier les bonnes abstractions. Assurez-vous que la chaîne fonctionne pour la plate-forme la moins performante, tout en donnant accès aux fonctionnalités avancées de la plateforme la plus performante. Faites le travail pour bien faire les choses et vous économiserez beaucoup d'efforts plus tard.
Pour l'audio, la chaîne ressemblait à quelque chose
SoundSources -> [Decoders] -> Buffers -> [3D Positioner] ->[Effects] -> Players
.Pour les graphiques, c'est possible
Model -> Shapes -> Positioner -> Texturer -> [Lighting] -> [Particle Effects] -> Renderer
. (C'est probablement un ensemble complètement faux, je ne suis pas un graphiste).Écrivez une API front-end qui gère vos objets principaux et un back-end spécifique à la plate-forme qui mappe l'API aux capacités de bas niveau. Fournir un effort optimal pour chaque capacité. Par exemple, sur PC et XBOX, le positionnement audio 3D a été effectué en utilisant les capacités HRTF des puces sonores, tandis que PS2 a utilisé un simple panoramique et fondu. Un moteur graphique peut faire quelque chose de similaire avec l'éclairage.
Implémentez autant de front-end que possible avec un code neutre sur la plateforme. Le code permettant d'attribuer un objet de réverbération à un objet sonore ou un élément de texture à un objet de forme doit être complètement courant, de même que le code pour parcourir et traiter les objets actifs. D'un autre côté, les objets de bas niveau peuvent être entièrement spécifiques à la plate-forme, à l'exception de l'interface commune.
Assurez-vous que l'API ou les fichiers de configuration permettent à l'utilisateur de spécifier des options spécifiques à la plate-forme. Nous avons essayé d'éviter de pousser le code spécifique à la plate-forme au niveau du jeu en le conservant dans les fichiers de configuration: un fichier de configuration d'une plate-forme peut spécifier "effet: SuperDuperParticleGenerator" tandis qu'un autre dit "effet: SoftGlow"
Développer définitivement les plateformes en parallèle. Assurez-vous que les interfaces spécifiques à la plate-forme sont bien définies et testables par elles-mêmes. Cela empêche une grande partie de "est-ce le niveau de la plateforme ou le niveau de l'API?" problèmes lors du débogage.
la source
J'écris un moteur de jeu open source appelé YoghurtGum pour les plateformes mobiles (Windows Mobile, Android). C'était l'un de mes gros gros problèmes. Je l'ai d'abord résolu comme ceci:
Avez-vous repéré le
void*
? En effet,RenderMethodDirectDraw
renvoie une surface DirectDraw tandis queRenderMethodDirect3D
renvoie un pool de vertex. Tout le reste était également divisé. J'avais uneSprite
classe qui avait soit unSpriteDirectDraw
pointeur soit unSpriteDirect3D
pointeur. Ça craignait.Ces derniers temps, j'ai beaucoup réécrit les choses. Ce que j'ai maintenant c'est un
RenderMethodDirectDraw.dll
et unRenderMethodDirect3D.dll
. Vous pouvez en fait essayer d'utiliser Direct3D, échouer et utiliser DirectDraw à la place. C'est parce que l'API reste la même.Si vous voulez créer un sprite, vous ne le faites pas directement mais via une usine. La fabrique appelle ensuite la fonction correcte dans la DLL et la convertit en parent.
Donc, c'est dans l'
RenderMethod
API:Et voici la définition de
RenderMethodDirectDraw
:J'espère que cela a du sens. :)
PS J'aurais aimé utiliser STL pour cela, mais il n'y a pas de support sur Android. :(
Fondamentalement:
EDIT: Oui, il est logique d'avoir des interfaces virtuelles comme celle-ci. Si votre première tentative échoue, vous pouvez essayer une autre méthode de rendu. De cette façon, vous pouvez garder toute votre méthode de rendu de code agnostique.
la source
J'aime utiliser SDL pour cela. Il a des backends de rendu pour D3D, OpenGl, OpenGL ES et une poignée d'autres backends spécifiques à la plate-forme, et il est disponible pour toutes sortes de plates-formes différentes, et actuellement en développement actif, avec des liaisons vers de nombreux langages différents disponibles.
Il résume les différents concepts de rendu et rend la création de vidéo (ainsi que la gestion du son et des entrées et quelques autres choses) disponible dans une API simple et multiplateforme. Et il a été conçu par Sam Lantinga, l'un des principaux développeurs de Blizzard, spécialement pour faciliter le portage de jeux et la création de jeux multiplateformes, de sorte que vous savez que vous avez affaire à une bibliothèque de haute qualité.
la source