2017-10-01 1 views
3

J'analyse une application OpenGL obfusquée. Je veux générer un fichier .obj qui décrit le modèle multi-polygone qui est affiché dans l'application. J'ai donc gelé l'application et déterré les valeurs définies dans VBO et IBO. Mais les valeurs fixées dans IBO étaient bien plus mystérieuses que ce à quoi je m'attendais. La valeur étaitComment fonctionnent les séquences triplées dans l'IBO?

0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 5, 8, 3, 3, 9, 9, 10, 11, 12, 12, 10, 13 , 14, 14, 10, 15, 16, 16, 17, 17, 7, 8, 8, 18, 18, 19, 20, 21, 21, 22, 22, 23, 24, 25, 25, 26, 26 27, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 36, 37, 38, 38, 36, 39, 34, 34, 40, 40, 40 et 41 , 42, 43, 44, 44, 45, 45, 46, 47, 48, 49, 49, 50, 50, 51, 52, 52, 53, 53, 54, 55, 55, 56, 56, 57, 58 , 58, 59, 59, 60, 61, 62, 62, 63, 63, 63, 64, 65, 66, 67, 64, 68, 68, 69, 69, 70, 71, 72, 73, 74, 75 , 76, 76, 77, 77, 78, 79, 80, 81, 82, 82, 80, 83, 83, 84, 84, 85, 86, 87, 88, 88, 89, 89, 90, 91, 91 , 92, 92, 92, 93, 94, 95, 96, 96, 97, 97, 97, 98, 99, 100, 101, 102, 102, 100, 103, 103, 104, 104, 105, 106, 107 , 107, 108, 108, 108, 109, 110, 111, 112, 112, 100, 100, 101, 113, 114, 114, ... (longueur = 10495)

Comme vous pouvez le voir comme indices 40, 63, 92 et 108 sont triplés, la mise en sorte que ni GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_QUADS, ni GL_QUAD_STRIPGL_POLYGON-glDrawElements ne fonctionnera pas correctement. Existe-t-il un certain type de techniques avancées pour utiliser les indices triples séquencés dans l'IBO? Qu'est-ce que ça veut dire? Pour quelle raison est-il utilisé?

+1

Vous avez besoin de savoir comment ce tableau d'index est réellement utilisé. Notez qu'il ne doit pas y avoir un seul appel draw consommant le tableau entier comme le même type primitif.Notez également qu'il existe des cas d'utilisation obscurs pour les triangles de zone nulle (comme les bords de retournement dans une bande triangulaire). Notez également qu'il pourrait y avoir simplement des primitives dégénérées. – derhass

Répondre

5

Des indices répétés comme ceux-là indiquent une optimisation agressive des bandes triangulaires. Un index répété crée des triangles dégénérés: triangles avec une zone nulle. Comme ils n'ont pas de zone visible, ils ne sont pas rendus. Ils existent de sorte que vous pouvez sauter d'une bande de triangle à l'autre sans avoir à émettre une autre commande draw.

Ainsi, un double index est souvent utilisé pour assembler deux bandes ensemble. Les deux triangles qu'il génère ne seront pas rendus.

Cependant, en raison de la façon dont strips work with the winding order, l'orientation pour les triangles peut mal fonctionner. C'est-à-dire que si vous cousiez deux bandes ensemble avec un double index, la seconde bande commencerait avec l'ordre inverse de l'enroulement qu'elle désire.

C'est là que les indices triples entrent en jeu. Le troisième index fixe l'ordre d'enroulement pour les triangles dans la bande de destination. Les trois triangles supplémentaires générés ne seront pas rendus.

La manière la plus moderne de gérer plusieurs bandes dans le même appel de dessin est d'utiliser primitive restart indices. Mais la liste d'index telle qu'elle est actuellement est adéquate pour une utilisation avec GL_TRIANGLE_STRIP.

Vous pouvez lire cette liste de bandes et la transformer en une série de triangles séparés (selon le cas pour GL_TRIANGLES) assez facilement. Il suffit de regarder chaque séquence de 3 sommets, et de la sortir dans votre triangle tampon, tant que ce n'est pas un triangle dégénéré. Et vous devrez inverser l'ordre de deux des indices pour chaque triangle impaire. Le code ressemblerait à ceci:

const int num_faces = indices.size() - 2; 
faces.reserve(num_faces); 

for(auto i = 0; i < num_faces; ++i) 
{ 
    Face f(indices[i], indices[i + 1], indices[i + 2]); 

    //Don't add any degenerate faces. 
    if(!(f[0] == f[1] || f[0] == f[2] || f[1] == f[2])) 
    { 
    if(i % 2 == 1) //Every odd-numbered face. 
     std::swap(f[1], f[2]); 

    faces.push_back(f); 
    } 
}