Les tampons devraient-ils être dissociés?

12

Je fais des tests avec OpenGL ES 2 et j'ai des questions, mon programme actuel est comme ça:

Init
-------
-> create index buffer
-> fill index buffer glBufferData 
-> create vertex buffer
-> fill vertex buffer glBufferData 

Draw
-------
 1. Apply vertex buffer

    -> Bind VAO
       -> bind vertex buffer
          - enable attributs (glVertexPointer, …)
       -> unbind vertex buffer
    -> Unbind VAO
    -> Bind VAO

 3. Apply index buffer
 4. Draw

Le problème

Le crash de code donné, après quelques recherches, j'ai compris pourquoi: j'ai besoin de dissocier mon tampon d'index dans la partie init (après "remplir le tampon d'index glBufferData") ou de le dissocier avant le premier "Bind VAO"

Mes questions sont:

  • Puis-je mettre mon tampon d'index en VAO (VAO stock index buffer?)?
  • Dois-je dissocier les tampons après chaque mise à jour (glBufferData)?

Dans mon application, j'ai des tampons qui sont mis à jour sur chaque image (Exemple: Particles) donc j'ai une pile OpenGL comme ça:

-> bind buffer 1
-> update buffer 1
-> close buffer 1
-> bind buffer 1
-> draw

Les 3 premières lignes mettent à jour le tampon Vertex, les deux derniers objets dessinés, cela devrait être quelque chose comme ça:

-> bind buffer 1
-> update buffer 1
-> draw

Merci

user30088
la source

Réponses:

12

Vous semblez faire beaucoup sur la liaison / dissociation inutile. Si vous utilisez un VAO, vous ne devez lier le VAO que lors de sa configuration et lors du dessin de la géométrie. Vous ne liez à nouveau le VBO / IBO que lorsque vous devez les mettre à jour.

Après avoir dessiné ou mis à jour un tampon, vous n'avez pas nécessairement à le délier, bien que ce soit une bonne idée de le faire pour éviter des écritures accidentelles sur des tampons qui ont été liés.

Maintenant, prenant votre première séquence d'opérations, voici l'ordre général que je m'attendrais à voir:

À l'init:

  1. Créez et liez un VAO. Tout VBO et IBO que vous liez dans la séquence sera associé au VAO actuel (celui-ci).

  2. Créer et lier un tampon d'index.

    • Remplissez le tampon d'index avec glBufferData/glMapBuffer.
  3. Créer et lier un tampon de vertex.

    • Remplissez le tampon de sommet glBufferData/glMapBuffer.
  4. Configurez les attributs de sommet avec glEnableVertexAttribArray/glVertexAttribPointer, etc.

  5. En option, dissociez tout pour éviter une modification accidentelle des tampons et du VAO. N'oubliez pas de délier le VAO en premier . Par exemple:glBindVertexArray(0);

Au tirage:

  1. Si seulement dessiner les tampons :

    • Liez le VAO;
    • Exécutez le ou les appels de tirage.
  2. Si mise à jour et dessin :

    • Liez VAO, VBO, IBO;
    • Mettre à jour les tampons (la mise à jour des attributs de sommet n'est nécessaire que si le format de sommet a changé);
    • Exécutez le ou les appels de tirage.
  3. Déliez éventuellement pour éviter la modification accidentelle des tampons et VAO.

C'est aussi simple que ça. Cet ordre des opérations devrait fonctionner sans problème.

glampert
la source
2
Je voudrais ajouter que dans mes expériences (2014) avec des cas réels (mais de simples shaders pour ne pas goulot d'étranglement au niveau du GPU), j'ai trouvé les améliorations de performances utilisant VAO insignifiantes (<2% d'économies CPU) après une commande correcte des appels de rendu a été implémenté pour ignorer complètement la configuration VBO lors de l'utilisation du même VBO lors d'appels de rendu consécutifs (10 à 33% d'économies de processeur), et j'ai rencontré des bugs avec certains pilotes avec VAO, j'ai donc fini par les désactiver par défaut. Il était encore moins important lors de l'utilisation de shaders complexes, MSAA, etc., qui goulot d'étranglement au niveau du GPU, laissant le processeur attendre de toute façon, même sur mobile.
Stephane Hockenhull
2
Notez que le désalignement des données de sommet d'une manière qui n'est pas prise en charge par le matériel forcera les pilotes GPU à réorganiser les données VBO sur chaque configuration tandis que les pilotes peuvent les réorganiser une fois avec VAO tant que rien n'est modifié, donc YMMV. Il est préférable d'aligner et de remplir les données de sommet de toute façon.
Stephane Hockenhull
1
Pourquoi le VAO doit-il être libéré avant tout le reste?
Daniel Safari
@DanielSafari, tu veux dire après la configuration? Si vous déliez d'abord un tampon (tampon de liaison 0 / null), il effacera ce point de liaison dans le VAO actuel. C'est pourquoi le VAO nul doit être défini en premier.
glampert
@glampert - non, ce n'est pas ainsi que fonctionnent les liaisons; la liaison du tampon est utilisée lorsque glVertexAttribPointer est appelée, et pas autrement (exception: GL_ELEMENT_ARRAY_BUFFER). La modification de la liaison du tampon après votre appel glVertexAttribPointer n'a aucun effet.
Maximus Minimus