Lors de la création d'une abstraction du système, il est préférable d'avoir la plate-forme API différente cachée par une interface commune au niveau le plus bas qui a du sens.
En tenant compte des différentes API graphiques natives modernes (sans pipeline de fonctions fixes): OpenGLES 2.0+, OpengGL 3.0+, DirectX 10.0+, Xbox DirectX 9, LibGCM
Si l'on devait créer une API graphique de bas niveau sans état pour s'asseoir au-dessus de toutes, quelle serait la meilleure façon d'aller pour la rendre aussi fine et aussi rapide que possible?
architecture
software-engineering
graphics
cross-platform
NocturnDragon
la source
la source
Réponses:
Le niveau le plus bas qui a du sens de mon point de vue est quelque chose qui parle des ressources impliquées dans le rendu - vb / ib, surfaces de rendu, textures, shaders, blocs d'état, etc.
Le problème ici est que certains d'entre eux doivent être dans différents formats, selon l'API - c'est là que cela devient un peu délicat. Le moyen le plus simple consiste à pré-traiter les ressources statiques pour l'API respective. Pour les dynamiques, utilisez uniquement des shaders pour les générer - ce qui rend assez simple de rester dans des formats natifs.
Tout ce que vous faites ensuite au niveau supérieur est de configurer des pipelines avec des ressources attachées et de les remettre au GPU. Vous constaterez que tout ne peut pas être résumé de cette manière, surtout si vous profitez d'astuces spécifiques au matériel. Mais c'est un bon début.
(Sidenote: si vous traitez les astuces spécifiques à la plate-forme comme un type spécial de ressource, vous pouvez pousser ce concept tout à fait loin.)
Donc, d'une certaine manière, vous allez créer deux choses: un gestionnaire de ressources matérielles, plus une boîte à outils pour configurer un DAG de ces ressources.
la source
Étant donné le large éventail d'API que vous souhaitez couvrir, l'approche de wrapping typique est susceptible d'être inefficace et sujette à des difficultés dans la mise en correspondance des concepts d'API entre plusieurs autres API qui peuvent ou non prendre en charge des fonctions particulières à des degrés divers.
En conséquence, l'approche la plus judicieuse serait de créer une API centrée sur les fonctionnalités . Bien que cette approche empêche l'utilisateur de l'API d'utiliser toutes les fonctionnalités disponibles, elle simplifie considérablement la mise en œuvre de chaque backend et permet des optimisations spécifiques au backend qui ne seraient pas possibles autrement.
Il simplifie également considérablement la gestion des fonctionnalités non prises en charge pour l'utilisateur de l'API; ils n'ont plus à vérifier si la fonction X existe et à déterminer quelles fonctionnalités sont affectées, mais à la place ils n'ont qu'à interroger la fonctionnalité elle-même pour voir si elle est prise en charge avec la configuration actuelle. Même si vous prenez en charge des modes partiels ou limités pour les fonctionnalités, le contexte fourni le rend beaucoup plus facile à gérer.
En termes de création d'un moteur de rendu sans état (également appelé soumission ), une clé 64 bits est généralement utilisée pour emballer et soumettre des commandes pour le rendu. À partir de là, il y a une grande flexibilité en termes d'exécution des commandes et des informations à soumettre en fonction des fonctionnalités et capacités que vous souhaitez prendre en charge.
la source
Pour commencer, chaque API fait les choses différemment, il va donc sans dire que l'encapsulation de toutes les API ci-dessus serait difficile. Cela dit, il est parfois nécessaire de le faire: à un moment donné, un jeu doit simplement fonctionner sur plusieurs plates-formes, quelle que soit la difficulté.
Je pense que la meilleure façon de procéder est de proposer les fonctionnalités qui peuvent être implémentées sur toutes les API sous-jacentes et d'abstraire cela et seulement cela. Si vous développez un jeu multiplateforme, vous n'implémenteriez pas toutes les fonctionnalités obscures prises en charge par chaque API, vous implémenteriez uniquement ce dont vous avez besoin. Cela permet également de maintenir l'API petite et rapide.
Pour éviter d'encombrer l'implémentation de chaque API différente dans la sortie, la compilation doit être effectuée avec des fichiers d'en-tête neutres et des fichiers de code spécifiques à la plate-forme. Ensuite, le fichier de code spécifique à la plate-forme cible serait le seul à être compilé en maintenant l'API petite.
la source
Il y a un article sur GPU Pro à ce sujet, par Emil Persson (Humus)
http://gpupro.blogspot.com/2009/12/making-it-large-beautiful-fast-and.html
la source
Vous voudrez peut-être consulter la bibliothèque SDL ou Allegro . Les deux sont des bibliothèques de jeux de bas niveau et hautement portables, qui ont un moyen de les brancher dans un contexte OpenGL afin que vous puissiez y rendre vos graphiques. SDL a la renommée d'être utilisé par le défunt Loki Games pour porter certains jeux populaires des années 2000 sur Linux, et Allegro a beaucoup de temps et dispose d'une grande communauté de développeurs de jeux amateurs.
la source