2016-07-04 4 views
1

Je suis relativement familier avec le dessin instancié et les données d'instance: j'ai réussi cela avec succès dans le passé.Instanciation OpenGL: comment déboguer des données manquantes par instance

Maintenant, je suis en train de refactoriser un ancien code, et j'ai introduit un bug sur la façon dont les données d'instance sont fournies aux shaders. Les bits concernés sont les suivants:

  1. J'ai une boucle de rendu de travail en utilisant glMultiDrawElementsIndirect mis en œuvre: si je l'ignore par exemple tout les données tire comme prévu.
  2. J'ai un vbo qui stocke les transformations du monde de mes objets. J'ai utilisé le CodeXL d'AMD pour déboguer ceci: le tampon est correctement rempli avec des données, et est lié lors du dessin d'une image.

    glBindBuffer (GL_ARRAY_BUFFER, batch.mTransformBuffer); glBufferData (GL_ARRAY_BUFFER, taille de (glm :: mat4) * OBJ_NUM, & xforms, GL_DYNAMIC_DRAW);

  3. Le shader spécifie l'emplacement d'entrée explicitement:

    #version 450 
    layout(location = 0) in vec3 vertexPos; 
    layout(location = 1) in vec4 vertexCol; 
    //... 
    layout(location = 6)uniform mat4 ViewProj; 
    layout(location = 10)uniform mat4 Model; 
    

La matrice ViewProj est égale pour toutes les instances et est établie à l'aide correctement:

glUniformMatrix4fv(6, 1, GL_FALSE, &viewProjMat[0][0]); 

Model est par exemple matrice mondiale c'est faux: contient tous les zéros.

Après liaison du tampon et avant de tirer chaque image, je suis en train de configurer les pointeurs d'attributs et diviseurs de telle sorte que chaque exemple tiré recevra un autre transform:

for (size_t i = 0; i < 4; ++i) 
{ 
    glEnableVertexAttribArray(10 + i); 

    glVertexAttribPointer(10 + i, 4, GL_FLOAT, GL_FALSE, 
         sizeof(GLfloat) * 16, 
         (const GLvoid*) (sizeof(GLfloat) * 4 * i)); 

    glVertexAttribDivisor(10 + i, 1); 
} 

Maintenant, j'ai regardé et le code pendant un moment et je ne peux vraiment pas comprendre ce que je manque. CodeXL montre clairement que le modèle (emplacement 10) n'est pas correctement rempli. Aucune erreur OpenGL n'est générée.

Ma question est: est-ce que quelqu'un sait dans quelles circonstances la configuration de données par instance peut échouer silencieusement? Ou toute suggestion sur la façon de déboguer plus loin ce problème?

+1

Je ne comprends pas très bien la configuration. 'Model' n'est pas censé être un uniforme, c'est un attribut régulier (... l'entrée du vertex shader). Vous venez de lui définir un diviseur non nul, puis il sera alimenté par instance (toutes les invocations de vertex shader pour le numéro d'instance * i * obtiendront l'attribut * i/divisor * de ce tableau d'attributs). Pourquoi utilisez-vous 'uniform'? – peppe

Répondre

2
layout(location = 6)uniform mat4 ViewProj; 
layout(location = 10)uniform mat4 Model; 

Ce sont uniformes, pas des valeurs d'entrée. Ils ne sont pas nourris par des attributs; ils sont alimentés par glUniform* appels. Si vous voulez Model pour être une valeur d'entrée, alors qualifiez-le avec in, pas uniform. De même, les entrées et les uniformes n'obtiennent pas les mêmes emplacements. Ce que je veux dire, c'est que les emplacements uniformes ont un espace différent des emplacements d'entrée. Une entrée peut avoir le même indice de localisation qu'un uniforme, et ils ne feront pas référence à la même chose. Les emplacements d'entrée se réfèrent uniquement aux indices d'attributs; les emplacements uniformes se réfèrent à des emplacements uniformes. Enfin, les emplacements uniformes ne fonctionnent pas comme les emplacements d'entrée. Avec les attributs, chaque équivalent vec4 utilise un index d'attribut distinct. Avec des emplacements uniformes, chaque type de base (tout ce qui n'est pas une structure ou un tableau) utilise un seul emplacement uniforme. Donc, si ViewProj est un emplacement uniforme, alors il ne prend que 1 emplacement.Mais si Model est une entrée, alors elle prend 4 indices d'attribut.

+0

Merci pour l'explication. Ca a du sens. Cela explique pourquoi le débogage je ne voyais rien dans l'uniforme, mais quand même, en changeant à "dedans", ne semble pas suffisant pour résoudre mon problème. J'ai probablement un bug ailleurs! – Heisenbug