web-dev-qa-db-fra.com

Différence entre glGenBuffers et glCreateBuffers

Étant donné que nous utilisons OpenGL 4.5 ou que nous prenons en charge l'extension GL_ARB_direct_state_access, nous avons la nouvelle fonction glCreateBuffers .

Cette fonction a une signature identique à glGenBuffers , mais spécifie:

renvoie n noms de tampon précédemment non utilisés dans buffers, chacun représentant un nouvel objet de tampon initialisé comme s'il avait été lié à une cible non spécifiée

glGenBuffers a la spécification suivante:

Les noms d'objet tampon renvoyés par un appel à glGenBuffers ne sont pas renvoyés par les appels suivants, sauf s'ils ont d'abord été supprimés avec glDeleteBuffers.

Ainsi, tout nom de tampon renvoyé par glCreateBuffers ne sera plus jamais utilisé seul, mais pourrait l'être par glGenBuffers.

Il semble que glCreateBuffers crée toujours de nouveaux objets de tampon et renvoie leur nom, et glGenBuffers ne crée de nouveaux tampons que s'il n'y a pas de tampons précédents qui ont été supprimés depuis.

Quel est l'avantage d'ajouter cette fonction?

Quand devrais-je utiliser glCreateBuffers sur glGenBuffers?


P.S.
Je pense que cela représente toutes les fonctions glCreate* ajoutées par GL_ARB_direct_state_access

15
CoffeeandCode

Ce que vous remarquez ici, c’est essentiellement d’améliorer la cohérence de l’API par rapport à la création d’objets Shader et Program. Celles-ci ont toujours été générées et initialisées en un seul appel et étaient la seule partie de l'API qui fonctionnait ainsi. Tous les autres objets ont d'abord été réservés à l'aide de glGen* (...), puis initialisés en liant le nom réservé à une cible.

En fait, avant le GL 3.0, il était permis de sauter le glGen* (...) et de créer un objet simplement en liant un numéro unique quelque part.

Dans GL 4.5, chaque type d'objet s'est vu attribuer une fonction glCreate* (...) qui les génère et les initialise en un seul appel dans GL 4.5. Cette méthodologie convient parfaitement à l'accès direct à l'État, où la modification (dans ce cas, la création) d'un objet ne nécessite pas de modifier (et éventuellement de restaurer) un état de liaison.


De nombreux objets exigent une cible ( par exemple textures) lors de l'utilisation de l'API de cette manière, mais les objets de mémoire tampon sont pratiquement sans typage. C'est pourquoi la signature de l'API est identique. Lorsque vous créez un objet tampon avec cette interface, il s'agit de "initialisé comme s'il avait été lié à une cible non spécifiée". Ce serait un non-sens complet pour la plupart des types d’objets dans GL; ils ont besoin d'une cible pour les initialiser correctement.

La principale considération ici est que vous souhaiterez peut-être créer et configurer l'état d'un objet dans GL sans affecter un autre élément de code qui s'attend à ce que l'objet lié à une certaine cible reste inchangé. C’est pour cela que Direct State Access a été créé, et c’est la raison principale pour laquelle ces fonctions existent.

En théorie, comme le souligne dari, initialiser un objet tampon en le liant à une cible spécifique donne potentiellement des indications au conducteur sur son utilisation prévue. Je ne mettrais pas beaucoup de choses là-dessus, cependant, c'est aussi suspect que les indicateurs d'utilisation réels lorsque glBufferData (...) est appelé; un indice au mieux.

11
Andon M. Coleman

Spécification OpenGL 4.5 - 6.1 Créer et relier des objets de tampon:

Un objet tampon est créé en liant un nom renvoyé par GenBuffers à Une cible de tampon. La liaison est effectuée en appelant 

void BindBuffer (cible enum, tampon uint); 

target doit être l’une des cibles listées dans le tableau 6.1. Si l'objet tampon nommé buffer n'a pas été précédemment lié , Le GL crée un nouveau vecteur d'état, initialisé avec Une mémoire tampon de taille zéro et comprenant tous les états et avec les mêmes valeurs initiales que celles indiquées dans le tableau 6.2. 

Ainsi, la différence entre glGenBuffers et glCreateBuffers est que glGenBuffers ne renvoie qu'un nom non utilisé, tandis que glCreateBuffers crée et initialise également le vecteur d'état décrit ci-dessus.


Usage:

Il est recommandé d’utiliser glGenBuffers + glBindBuffer, car 

le GL peut faire des choix différents en ce qui concerne l'emplacement de stockage et la disposition en fonction de la liaison initiale.

Comme dans glCreateBuffers aucune liaison initiale n'est donnée, ce choix ne peut pas être effectué.

5
dari

glCreateBuffers n'a pas de cible car les objets de tampon ne sont pas typés. La première cible de liaison n'a jamais été utilisée que comme indice dans OpenGL. Et Khronos a envisagé de donner à glCreateBuffers un paramètre target, mais ils ont décidé contre:

NamedBufferData (et la fonction correspondante de EXT d'origine) N'incluent pas le paramètre <target>. Est-ce que les implémentations peuvent faire Des hypothèses initiales sur l'utilisation d'un magasin de données basé sur ce paramètre . Où est-il allé? Devrions-nous le ramener?

RÉSOLU: Pas besoin d'un paramètre cible pour le tampon. Les implémentations [sic] Ne font pas d'hypothèses d'utilisation basées sur le paramètre <target>. Une seule extension de fournisseur Le fait pour AMD_pinned_memory. Une approche cohérente Pour spécifier une utilisation de la mémoire tampon consiste à ajouter un nouvel indicateur pour ce paramètre <flags> De BufferStorage.

L'accent a été ajouté.

1
Nicol Bolas