J'ai commencé à regarder le flux Handmade Hero , où Casey Muratori crée un moteur de jeu sans utiliser de frameworks ou autres. Hier, je suis arrivé à la partie où il a montré comment une image est dessinée sur l'écran. Pour autant que je l'ai compris, il vient d'allouer une mémoire aussi grande que la taille de l'écran sur lequel il souhaite dessiner. Et puis il a créé un bitmap qu'il a passé à la mémoire tampon qu'il a allouée et l'a dessiné à l'écran en utilisant une fonction spécifique au système d'exploitation.
Cela semble assez simple. J'ai utilisé GameMaker, changé pour Love2D, travaillé un peu avec Sprite Kit mais je me demandais toujours ce qui se passait vraiment sous ces couches parfois déroutantes.
Compte tenu de cela, pourquoi même s'embêter à utiliser des bibliothèques graphiques (OpenGL, SFML, SDL,…) alors que tout ce que vous avez à faire est simplement d'allouer du tampon, de passer un bitmap et de le dessiner à l'écran?
Si vous voulez ensuite dessiner des choses distinctes sur votre écran, écrivez-les simplement dans votre bitmap qui est ensuite passé dans le tampon. Je suis assez nouveau en programmation, mais cela me semble assez simple. Corrigez-moi si j'ai tort, s'il-vous plait.
la source
Réponses:
Ce n'est pas seulement une question de rapidité d'exécution, mais aussi de simplicité. Bien que le rendu logiciel utilisé dans cet exemple soit beaucoup plus lent que l'utilisation de l'accélération matérielle (c'est-à-dire un GPU), dessiner quelques bitmaps à l'écran est une tâche si banale que vous ne remarquerez pas la baisse des performances.
Cependant, les activités de bas niveau comme la rastérisation triangulaire, le tri en profondeur et autres sont des concepts bien compris que le GPU peut gérer implicitement avec quelques commandes. Ré-implémenter ceux en mode logiciel réinvente essentiellement la roue. C'est bien si vous voulez acquérir une compréhension de bas niveau de la façon dont le rendu est effectué, j'ai moi-même écrit un moteur de rendu 3D juste pour l'explorer un peu, mais dans la plupart des cas, c'est une perte de temps quand OpenGL peut le faire plus rapidement hors de la boîte.
L'exemple que vous avez donné semble extrêmement basique, il suffit de dessiner une seule image sur l'écran, d'où la mise en œuvre est facile. Une fois que vous commencez à superposer la complexité, vous constaterez qu'il devient de plus en plus compliqué d'obtenir tout le rendu correctement. Les choses que les gens devaient faire à l'époque de Quake du rendu logiciel 3D étaient folles, bien que j'apprécie que vous n'alliez pas si loin (encore).
la source
Bref: parce que c'est rapide (OpenGL, DirectX).
Longue:
Vous pensez peut-être que vous pouvez le faire vous-même. Dessinez des pixels sur un écran. Vous pouvez écrire une petite bibliothèque pour dessiner des formes, comme des quads ou des triangles. Cela fonctionnera, bien sûr. Il existe de nombreuses bibliothèques pour faire exactement cela. Certains d'entre eux implémentent même la spécification OpenGL (ils sont donc comme un côté logiciel pour opengl) qui fera exactement ce que fait Casey Muratori. Ils calculent tout du côté logiciel, définissent les pixels du côté logiciel et écrivent le résultat à l'écran.
Mais c'est lent . Le CPU qui finira par exécuter toutes ces choses n'a pas été conçu pour ce scénario. C'est à cela que servent les GPU. Ce qu'OpenGL fait (sauf s'il s'agit d'une implémentation logicielle bien sûr), c'est de prendre tout ce que vous lui demandez de faire et de pousser toutes les données, tous les appels, presque tout vers la carte graphique et de dire au GPU de faire le travail. Le GPU est spécialement conçu pour ce type de travail. Multiplier les nombres à virgule flottante (c'est ce que vous faites beaucoup lorsque vous dessinez une scène 3D) et exécuter des shaders. Et cela en parallèle. Juste pour vous donner une idée de la vitesse du GPU, pensez à une simple scène en 3D en plein écran avec 1920x1080 pixels. Ce sont, multipliés, 2 073 600 pixels à dessiner. Pour chaque singlepixel, le GPU exécutera le fragment-shader au moins une fois , la plupart du temps plus d'une fois. Maintenant, disons que nous fonctionnons à 60 images par seconde. Cela signifie que le GPU exécute le fragment-shader 2 073 600 * 60 = 124 416 000 fois par seconde . Pensez-vous que vous pouvez faire quelque chose comme ça sur votre CPU? (C'est une explication assez simplifiée, il y a beaucoup plus de choses à considérer comme le nombre de pixels que vous surplombez par des objets plus proches, la quantité de MSAA que vous utilisez, etc., mais les 124 416 000 fois par seconde sont probablement les plus faibles que vous pouvez obtenir, et vous aura facilement beaucoup plus de 60 images par seconde avec une scène simple)
C'est ce que font OpenGL et Direct3D, pour quels moteurs voient @Uri Popovs répondre.
la source
Ce qu'il fait est appelé rendu logiciel , ce que fait OpenGL est appelé rendu GPU
Quelle est la différence entre eux? Vitesse et mémoire.
La pixellisation (remplissage des triangles à l'écran) prend un certain temps. Si vous le faites sur le CPU, vous prenez essentiellement ce temps loin de la logique du jeu, surtout s'il n'est pas bien optimisé.
Et peu importe la taille de l'image, il doit lui allouer une certaine quantité de mémoire. Les GPU ont une mémoire vidéo pour cela.
la source
Bien que les réponses des autres soient plus correctes que toute réponse que je pourrais donner, je tiens à souligner le malentendu fondamental sur le fonctionnement du développement logiciel qui, je pense, sous-tend votre question. Bien qu'il soit toujours possible de faire les choses "par vous-même" sans cadre, et qu'il y ait souvent de grands avantages pédagogiques à le faire, la réalité n'est pas que les logiciels modernes sont créés.
Quelqu'un a créé le matériel et les langages machine qui s'y exécutent. Quelqu'un d'autre crée des langages et des compilateurs de niveau supérieur, des pilotes et des systèmes d'exploitation, des bibliothèques graphiques et ainsi de suite. Nous nous appuyons tous sur le travail de nos prédécesseurs. Ce n'est pas seulement "d'accord", c'est une exigence.
Vous tracez la ligne de ce qui est "acceptable" ou non à un point arbitraire de la chaîne d'outils. Vous pourriez tout aussi bien dire «pourquoi utiliser C ++ alors que vous pourriez faire la même chose dans l'assemblage? Il n'y a pas assez d'heures dans la journée ou d'années dans une vie pour que tout le monde fasse tout lui-même.
Cela ne s'applique pas uniquement au développement de logiciels, mais à la vie moderne en général. Avez-vous déjà entendu parler du gars qui a lui-même construit un grille-pain? http://www.thomasthwaites.com/the-toaster-project/ . Cela a pris beaucoup de temps et d'efforts. Pour un grille-pain. Essayez de créer vous-même tout ce qui est nécessaire pour actualiser un jeu vidéo dans l'éther!
la source
Les moteurs font bien plus que dessiner une image à l'écran. Ils gèrent l'éclairage, les ombres, l'entrée, la détection de collision. Même juste la partie de rendu est beaucoup plus complexe que de simplement pousser un tampon sur l'écran. Pour les scènes 3D en particulier, vous devez faire beaucoup de calculs sur des données beaucoup plus complexes qu'un bitmap. Permettez-moi de vous donner une analogie avec une voiture: ce que vous décrivez comme simple, c'est l'échappement de la voiture. Vous faites juste un tuyau avec la bonne taille, puis vous poussez le gaz d'un bout à l'autre. Cependant, c'est loin d'être la seule chose qui se passe dans le mécanisme de la voiture.
la source
Les réponses ci-dessus sont excellentes, mais aucune ne dépasse vraiment la raison la plus importante pour laquelle OpenGL et autres sont préférés. La raison principale est d'utiliser un matériel dédié spécialement conçu pour fonctionner avec des choses comme le rendu de millions de pixels sur un écran, le GPU .
Avec le rendu logiciel, en utilisant le CPU, le rendu fera une boucle, un par un, sur tous les pixels d'une image bitmap et émettra des ordres pour les afficher chacun à l'écran. Donc, si vous effectuez le rendu d'une image de taille 1000x1000, ce million de boucles pour que votre processeur passe. Ils sont conçus avec un contrôle à l'esprit après tout; beaucoup de conditions if, sautant d'un ensemble d'instructions à l'autre et une direction stricte du flux de contrôle. Cependant, un GPU est conçu en sachant qu'il fera beaucoup de boucles similaires sur les pixels à l'écran.Un GPU prendrait une boucle for avec 1000000 itérations et diviserait le travail sur son grand nombre de cœurs pour que chacun fonctionne ** en parallèle et indépendamment les uns des autres **. Donc, contrairement au CPU, chaque fois qu'un GPU rencontre une condition if-else, il gérera les deux branches de code sur deux cœurs et ALORS, à la toute fin, il examinera ce que la condition évalue et rejette la résultat de la branche inutile (c'est pourquoi de nombreuses conditions if-else dans les shaders GPU sont désapprouvées; elles sont toujours responsables d'un gaspillage).
Alors oui, les GPU sont construits autour du parallélisme . Cela rend le travail sur les pixels pour eux beaucoup plus rapide que les processeurs.
la source
Voir Dois-je vraiment besoin d'utiliser une API graphique?
Bien sûr, vous pouvez demander un tampon, y mettre quelques bits et l'écrire à l'écran. C'était essentiellement la seule façon de faire de la programmation graphique sur PC jusqu'à la disponibilité d'accélérateurs graphiques au milieu des années 90 de 3DFX. Même sous Windows, DirectX a été développé pour donner un accès direct à la mémoire vidéo.
Mais sur du matériel non PC, des machines de jeux dédiées, il y a toujours eu des techniques pour accélérer les graphiques en déchargeant le travail du processeur. Même l'Atari 2600 avait des "sprites matériels", en partie parce qu'il n'avait pas assez de RAM pour un framebuffer.
Plus tard (au milieu des années 80), les consoles de jeux ont été optimisées pour les jeux de plateforme. Encore une fois, pas de framebuffer; à la place, le programmeur pourrait spécifier des grilles de tuiles :
la source
Les processeurs modernes sont assez rapides pour faire n'importe quel jeu 2D en logiciel, donc pour les graphiques 2D, OpenGL / DirectX n'offrirait aucun avantage, à part ajouter une autre dépendance et une couche de complexité à votre projet, comme par exemple définir une matrice de projection 3D pour dessiner un groupe de sprites et le téléchargement de données sur GPU.
OpenGL vous obligerait également à emballer tous vos sprites dans des textures 512x512 (un artefact d'anciennes consoles, comme PSX, empaquetant des graphiques dans des pages de mémoire vidéo), vous obligeant à écrire un code d'emballage de sprite assez complexe.
D'un autre côté, si vous faites de la 3D, en rendant des millions de triangles avec un ombrage complexe, le GPU est inévitable. Il y a longtemps, il y avait une version 2d plus simple de Direct3d, appelée DirectDraw, qui accélérait le dessin de sprite par le GPU, mais maintenant Microsoft ne le prend plus en charge, peut-être parce que les processeurs sont assez rapides pour faire 2d sans aucune accélération, si vous ne vous souciez pas des économies d'énergie .
la source