OpenGL: VBO ou glBegin () + glEnd ()?

16

J'ai récemment reçu ce lien vers un site de tutoriel de quelqu'un à qui j'ai donné le livre rouge OGL original. Le troisième en-tête vers le bas dit clairement d'oublier glBegin () & glEnd () comme méthode de rendu typique. J'ai appris via la méthode du Redbook, mais je vois certains avantages dans les VBO. Est-ce vraiment la voie à suivre et, dans l'affirmative, existe-t-il un moyen de convertir facilement le code de rendu et les shaders suivants en VBO et en types de données ultérieurs?

S. Fitzgerald
la source

Réponses:

27

Avec les VBO d'OpenGL modernes sont la voie à suivre, les fonctions fixes (y compris glBegin / glEnd et les choses entre les deux) sont obsolètes depuis 3.0 et supprimées depuis 3.1.

Avec OpenGL Core Profile, OpenGL ES 2.0+ et WebGL, vous n'avez même pas accès aux anciens éléments.

Certaines personnes pensent qu'apprendre d'abord les anciennes choses est mieux parce que c'est un peu plus facile, mais ces choses que vous apprenez sont pour la plupart inutiles et ensuite vous devez les désapprendre.

Ce n'est pas seulement le VBO, vous devez utiliser des shaders pour tout et faire des transformations matricielles vous-même (ou utiliser GLM).

La seule raison d'utiliser les anciens trucs serait si vous vouliez cibler OpenGL avant 2.0. qui était de retour en 2003. Il y a quelques chipsets de netbook embarqués vraiment merdiques qui sont 1.5 mais même 1.5 devraient prendre en charge les VBO, pas les shaders. Ou OpenGL ES 1.x qui est basé sur le pipeline de fonctions fixes (par exemple, il est utilisé sur les anciens iPhones). Ou OpenGL SC (pour les systèmes critiques pour la sécurité).

Les fonctions couramment utilisées suivantes sont toutes obsolètes:

  • glBegin
  • glEnd
  • glVertex *
  • glNormal *
  • glTextCoord *
  • glTranslate *
  • glRotate *
  • glScale *
  • glLoadIdenity
  • glModelViewMatrix

Le opengl-tutorial.org tutoriels ont ce que je pense être la meilleure façon de faire pour apprendre OpenGL. Ils s'appuient sur certains éléments de compatibilité hérités, mais ils ne vous l'enseignent pas réellement. Par exemple, vous n'êtes pas censé rendre quoi que ce soit sans shader, mais cela fonctionne. Et vous devez gérer vous-même les opérations de matrices (rotation, translation, etc.) mais par défaut, vous obtiendrez une fenêtre 2D plate de base.

En plus d'éviter les choses obsolètes, il existe un tas de fonctions qui rendent le codage OpenGL beaucoup plus agréable, mais avec beaucoup d'entre elles, vous devez décider si vous êtes d'accord avec la nécessité de nouvelles versions 3.x + d'OpenGL et de matériel compatible.

Il y a plus d'informations dans un post que j'ai fait ici .

Si vous avez besoin de prendre en charge OpenGL plus ancien pour une raison quelconque, vous pouvez utiliser des VBO lorsque cela est possible et quand ce n'est pas le cas, fournissez une solution de rechange qui utilise glBegin / glEnd et boucle sur vos données de vertex.

D'un autre côté, il n'y a pas de véritable moyen «facile» de convertir le vieux code de rendu. Vous pouvez peut-être implémenter votre propre version des fonctions qui ajoutent les sommets à un tableau / vecteur qui le sauvegarde ensuite dans un VBO et le dessine lorsque vous fausses glEnd est appelé. mais ce serait très inefficace car il le ferait à chaque image (sauf si vous cochez pour ne le faire qu'une seule fois mais cela ne fonctionne pas pour les objets animés) et serait probablement plus de travail que de simplement passer aux VBO. Je suppose que si vous aviez beaucoup de code, cette approche pourrait fonctionner.

David C. Bishop
la source
7

Avec les VBO, vous avez généralement deux avantages majeurs.

L'avantage 1 concerne les données entièrement statiques et provient de la possibilité de conserver vos données de sommet en mémoire, ce qui est plus optimal pour le GPU.

L'avantage 2 concerne les données dynamiques et provient de la possibilité de spécifier vos données de sommet à tout moment avant de les utiliser pour le rendu, ce qui peut mieux les canaliser.

Un troisième avantage provient du traitement par lots des appels de tirage, mais est également partagé avec les tableaux de vertex à l'ancienne, donc je ne l'appelle pas spécifiquement pour les VBO. L'envoi de données à un GPU (ou l'utilisation de données déjà sur le GPU) est similaire à bien des égards aux E / S de disque et au trafic réseau - si vous avez quelques grands lots, c'est plus efficace que de nombreux petits lots.

Une bonne analogie (pas 100% précise mais suffisante pour vous aider à comprendre) est que si vous êtes un chauffeur de bus qui doit amener 50 personnes d'une ville à l'autre. Vous pouvez les charger un à la fois et effectuer 50 trajets distincts - c'est glBegin / glEnd. Alternativement, vous pouvez mettre tous les 50 dans le bus et faire un seul voyage - c'est-à-dire avec des tableaux de vertex ou des VBO (dans le cas VBO, les 50 personnes seraient déjà dans le bus;)).

Cela a cependant un prix, et ici le prix est que vous perdez la possibilité de simplement spécifier les données de sommet au fur et à mesure que vous en avez besoin. Eh bien, OK, vous pouvez le faire (avec un travail supplémentaire), mais vous n'obtiendrez pas toutes les performances de votre code. Au lieu de cela, vous devez réfléchir davantage à vos données de sommet, à la façon dont elles sont utilisées, à la manière (et si) qu'elles doivent être mises à jour, à la possibilité de réaliser des animations dans un shader (permettant ainsi aux données de rester statiques - les VBO ont vraiment besoin de shaders pour un beaucoup de cas d'animation pour bien fonctionner) ou si vous avez besoin de spécifier à nouveau les données de sommet chaque image, des stratégies de mise à jour efficaces si ces dernières, etc. Si vous ne faites pas cela et implémentez simplement une conversion naïve, vous avez un risque très élevé de mettre dans beaucoup de travail seulement pour que le résultat final fonctionne réellement plus lentement!

Cela peut sembler énormément de travail lorsque vous le rencontrez pour la première fois, mais ce n'est pas vraiment le cas. Une fois que vous êtes dans le mode de penser comme ça, vous constaterez en fait que c'est incroyablement facile et vient presque naturellement. Mais vous pouvez gâcher vos premières tentatives et ne vous découragez pas si c'est le cas - le gâchis est l'occasion d'apprendre de ce que vous avez fait de mal.

Quelques dernières réflexions.

Avoir vos données de modèle dans un format qui peut être facilement chargé dans un VBO peut vous aider à rendre ce processus beaucoup plus facile. Cela signifie que vous devez éviter les formats plus complexes ou exotiques, au moins au début (et jusqu'à ce que vous soyez plus à l'aise avec le processus); gardez les choses aussi simples et basiques que possible lors de l'apprentissage et il y aura moins de choses à se tromper et moins d'endroits où chercher des erreurs si (ou quand!) les choses tournent mal.

Les gens sont parfois découragés s'ils voient une implémentation VBO utilisant plus de mémoire qu'une implémentation glBegin / glEnd optimisée / compressée (ils peuvent même l'appeler "gaspillage"). Ne sois pas comme ça. Sauf dans les cas extrêmes, l'utilisation de la mémoire n'est vraiment pas si importante. C'est un compromis clair ici - vous acceptez une utilisation de la mémoire potentiellement plus élevée en échange de performances sensiblement supérieures. Aide également à développer l'état d'esprit selon lequel la mémoire est une ressource bon marché et abondante qui peut être utilisée; la performance ne l'est pas.

Et enfin le vieux châtaignier - s'il est déjà assez rapide, votre travail est terminé. Si vous atteignez votre cadence d'images cible, si vous avez de la marge pour les conditions transitoires, alors c'est assez bon et vous pouvez passer à l'étape suivante. Vous pouvez perdre beaucoup de temps et d'énergie en extrayant 10% supplémentaires de quelque chose qui n'en a pas réellement besoin (été là, fait cela, toujours tomber dans le piège), alors pensez toujours à l'utilisation la plus optimale de votre temps - parce que le temps du programmeur est encore moins bon marché et moins abondant que la performance!

Maximus Minimus
la source