2016-04-16 2 views
0

Habituellement, j'essaie de séparer les informations spécifiques au maillage (VBO/VAO) des informations spécifiques à l'instance (transformation, uniformes, etc.).Réutilisation du VBO pour l'instanciation matérielle

De cette manière, les parties du code qui manipulent les informations d'instance n'ont pas besoin de savoir quoi que ce soit sur les VBO/VAO, et vice-versa.

Cependant, récemment, j'ai commencé à utiliser l'instanciation matérielle à l'aide de glDrawInstanced et le fait que les attributs d'instance soient liés ensemble dans le VAO rend ma séparation des problèmes plus difficile.

La raison en est que généralement le VBO/VAO a été construit à partir de mon chargeur .OBJ (qui a toutes les informations nécessaires pour construire cela) et d'autres parties du code ne s'inquiètent que des shaders uniformes. Maintenant, ces parties du code ont besoin de connaître la structure du VAO afin d'attacher l'information sur leurs attributs d'instance.

Cela devient encore plus gênant quand j'ai des VBO qui peuvent être réutilisés pour le rendu normal et instancié.

Existe-t-il une méthode recommandée qui permettrait de conserver une séparation des préoccupations entre la définition des attributs de maillage et des attributs d'instance? Je pensais avoir deux VAO, un pour le rendu normal et un autre pour le rendu instancié où j'ajouterais les attributs d'instance supplémentaires dont j'ai besoin, mais je n'ai trouvé aucun moyen de dupliquer ou d'inspecter les données VAO d'origine. besoin de connaître la structure réelle du VBO/VAO et pas seulement les paramètres d'instance.

+0

Créer un autre niveau d'abstraction sur votre géométrie, qui va créer et dessiner des lots de données d'une manière spécifiée (avec ou sans instanciation). – Drop

+0

Oui, c'est précisément ce que j'espérais éviter ... Je le ferai finalement si aucune autre suggestion ne se présente. – glopes

Répondre

0

Trouvé un moyen de le faire!

J'ai oublié que vous pouvez réellement inspecter l'état d'un VAO en utilisant glGetVertexAttrib*. Cela permet à mes modules de manipulation de paramètres d'instance de créer un nouvel objet VAO pour instancier et reconstruire sa structure de base à partir du maillage VAO d'origine, puis d'ajouter les attributs supplémentaires pour les paramètres d'instanciation. De cette façon, ils peuvent rester indépendants de la structure de sommet spécifique du maillage et ne doivent s'inquiéter que de la structure des données d'instanciation.

inspection ressemble à ceci:

std::vector<VertexAttrib> attribs; 
for (int i = 0; ; i++) 
{ 
    int enabled; 
    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled); 
    if (enabled == 0) break; 

    VertexAttrib attrib; 
    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &attrib.size); 
    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &attrib.stride); 
    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &attrib.type); 
    glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &attrib.normalized); 
    attribs.push_back(attrib); 
} 

VertexAttrib est ma propre structure pour stocker vertex attribut états introspection à. Une fois que j'ai la liste des états introspects, je crée et lie mon nouvel objet VAO et lui donne le même état que le VAO d'origine. Ensuite, je procède à l'ajout des attributs supplémentaires pour l'instanciation du matériel. Cela a aussi l'avantage que je peux lier ce nouveau VAO au VBO d'origine et réutiliser exactement les mêmes données de maillage. Ensuite, tout se déroule conformément au pipeline d'instanciation normal. Si j'ai besoin de dessiner le modèle sans instanciation, je peux également lier le VAO original.