Comment re-glBufferData () interagit-il avec glVertexAttribPointer?

Aug 21 2020

Je comprends la séquence de base: glGenBuffers () crée un "nom d'objet tampon", glBindBuffer () crée l'objet tampon réel (ainsi que la liaison du nom), glBufferData () "crée et initialise le magasin de données d'un objet tampon" et glVertexAttribPointer () définit le format des données de la mémoire tampon, ainsi que l'enregistrement de la liaison de l'objet tampon dans le cadre de l'état du tableau attribut vertex.

La chose délicate dont je ne suis pas sûr est si le truc glVertexAttribPointer () reste valide si le "buffer object data store" (mais pas l'objet buffer lui-même) est époustouflé par un nouvel appel à glBufferData (). Je suis conscient que ce n'est généralement pas une bonne idée - utilisez glBufferSubData () lorsque vous réécrivez simplement des tampons - mais glBufferData () semble être la seule option si elle doit être redimensionnée. De plus, je suis juste curieux.

Les pages de référence donnent l'impression que cela pourrait aller dans les deux sens - en particulier (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml):

Si le pointeur n'est pas NULL, un objet tampon nommé différent de zéro doit être lié à la cible GL_ARRAY_BUFFER (voir glBindBuffer ), sinon une erreur est générée. Le pointeur est traité comme un décalage d'octet dans le magasin de données de l'objet tampon. La liaison d'objet tampon (GL_ARRAY_BUFFER_BINDING) est enregistrée en tant qu'état de tableau d'attributs de vertex générique (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) pour l'index d' index .

Lorsqu'un tableau d'attributs de sommets générique est spécifié, la taille , le type , la normalisation , la foulée et le pointeur sont enregistrés en tant qu'état du tableau de sommets, en plus de la liaison d'objet tampon du tableau de sommets actuelle.

Il semble que le décalage d'octet et la liaison d'objet tampon puissent rester valides, même si le magasin de données a été remplacé par quelque chose de différent. Mais je pourrais aussi le voir être implémenté de telle sorte qu'au moment de l'appel, la liaison capture un pointeur spécifique dans le magasin de données, qui devient invalidé si le magasin de données est remplacé. Aucune des deux solutions ne semble exclue par le libellé.

Réponses

D0SBoots Aug 22 2020 at 04:45

Il semble que les liaisons glVertexAttribPointer () restent valides, même après des appels ultérieurs à glBufferData (). J'ai déterminé cela en l'essayant, ce qui n'est pas une preuve à 100% - cela pourrait simplement fonctionner uniquement dans cette implémentation (pilotes NVidia, dans mon cas).

Cependant, avec un rappel de message d'erreur et un mode de débogage activé, j'obtiens le message suivant lors du deuxième appel à glBufferData (), ce qui suggère fortement que cette situation est attendue / conçue pour:

[LWJGL] Message de débogage OpenGL
    ID: 0x20071
    Source: API
    Type: AUTRE
    Gravité: NOTIFICATION
    Message: Informations détaillées sur le tampon: Objet tampon 1 (lié à GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1) et GL_ARRAY_BUFFER_BINDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1) et GL_ARRAY_BUFFER_BINDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1) et GL_ARRAY_BUFFER_BINDING_ARB).

Les deux premières liaisons représentent mes deux appels à glVertexAttribPointer () et ne sont pas présentes dans le message qui est consigné la première fois que j'appelle glBufferData ().