Technote 2230 fait de nombreuses suggestions pour améliorer les performances de vos applications iPhone qui utilisent OpenGL ES. Vous êtes maintenant assez loin dans votre compréhension de l'OpenGL ES que vous devriez le lire. Non, vraiment. Allez le lire, Je vais attendre.
Ok, fait? Sous la section intitulée Optimisation des données de vertex, Il ya une recommandation quelque peu sibylline de «soumettre la bande-commandé triangles indexé avec les données par vertex entrelacées». Quand Apple fait une recommandation, ils ont généralement une bonne raison pour cela, nous allons donc voir comment nous nous conformons à celui-ci.
Tout d'abord, regardons ce que cela signifie. Faisons le décomposer:
Bande ordonné: En d'autres termes, si votre modèle a triangles adjacents, à les soumettre sous forme de bandes triangle plutôt que de soumettre chaque triangle individuellement. Nous avons parlé de l'aide de bandes de triangle en versements plus tôt, de sorte que vous savez déjà un peu de cela. Ce n'est pas toujours possible d'utiliser des bandes triangle, mais pour un bon nombre d'objets que vous pourrez, et quand vous le pouvez, vous devriez, car en utilisant des bandes triangle diminue fortement la quantité de données de vertex que vous avez à pousser dans OpenGL ES chaque trame.
indexed: Ce n'est pas nouveau. Nous avons été en utilisant des indices de vertex pour un certain temps maintenant. Notre filature icosaèdre les utilise pour créer vingt faces avec seulement douze sommets. glDrawElements () dessine une base plutôt que des indices des sommets.
Heck, nous faisons beaucoup jusqu'ici, ne sommes-nous? Jusqu'à présent, nous semblent faire toutes les bonnes choses! Regardons la dernière partie de la recommandation, toutefois:
avec les données par vertex entrelacées: D'accord, hmm .. Qu'est-ce que cela signifie?
Bon, le temps de tester votre mémoire. Vous souvenez-vous dans plusieurs des versements de temps passé, quand nous nous avons parlé des fonctions comme glVertexPointer (), glNormalPointer (), glColorPointer (), ou glTexCoordPointer? Dans les premiers versements, je vous ai dit de ne pas s'inquiéter du paramètre appelé la foulée et à seulement elle est définie pour 0.
Eh bien, maintenant vous pouvez commencer à s'inquiéter foulée, parce que c'est la clé de l'entrelacement des données par votre vertex.
Vous vous souvenez, bien sûr, que dans OpenGL ES, nous passent toujours la géométrie en utilisant un éventail de vertex, qui est un tableau contenant des ensembles de trois GLfloats qui définissent les points qui composent nos objets. Parallèlement à cela, nous avons aussi parfois de spécifier d'autres données. Par exemple, si nous utilisons l'éclairage et la nécessité de normales au sommet, nous devons spécifier une normale par sommet dans notre gamme normale. si nous utilisons les coordonnées de texture, nous devons nous assurer que notre réseau de coordonnées de texture a un ensemble de coordonnées de texture par vertex. Et si nous utilisons une gamme de couleurs, nous devons spécifier une couleur par vertex. Avez-vous remarqué combien je continue à dire "par sommet"? Eh bien, ces types de données sont ce que Apple se réfère à quand ils disent "données par vertex" dans cette TechNote. C'est tout ce que vous transmettez comme un tableau dans OpenGL ES qui fournit tout type de données qui s'applique à des sommets dans le tableau de vertex.

Ce que nous allons apprendre à faire aujourd'hui est de Smush toutes ces données ensemble dans un seul bloc contigu de mémoire:

Ne vous inquiétez pas si vous ne pouvez pas lire le code dans cette illustration. Quand il devient important, je vais vous donner la liste de code à nouveau, c'est juste pour illustrer le point que nous allons avoir l'ensemble de nos données de vertex dans un glob unique de la mémoire. Qu'est-ce que ça va faire est de mettre toutes les données décrivant un seul sommet en un seul endroit dans la mémoire. Cela permettra OpenGL accès plus rapide aux informations sur chaque sommet. Dans versement d'aujourd'hui, nous allons sommets Interleave, normales, et les données de couleur, mais la même technique exacte serait travailler pour les coordonnées de texture, ou tout simplement pour un entrelacement sommets et les normales. En fait, dans le projet d'accompagnement Xcode, il ya des structures de données définies pour gérer tous les trois de ces scénarios d'entrelacement.
Assez simple, hein? Vous avez juste créer une structure avec chaque morceau de chaque sommet de données que nous utilisons.
Ensuite, bien sûr, nous avons besoin pour remplir nos données de vertex, nous avons donc besoin de combiner ces trois tableaux statiques const en un seul. Voici ce que les mêmes données icosaèdre ressemble spécifié en utilisant un tableau statique de notre nouveau type de données:
Voici comment nous transmettre les informations en OpenGL. Plutôt que de transmettre le pointeur vers le tableau approprié, on passe de l'adresse du membre approprié de le premier sommet du tableau, et de fournir la taille de cette structure comme argument la foulée.
Le paramètre le dernier dans chacun de ces appels une pointe vers les données correspondant au premier sommet. Ainsi des points de couleur, par exemple, & vertexData [0]. À l'information couleur pour le premier sommet. Le paramètre stride identifie combien d'octets de données qui doivent être ignorés avant le même type de données pour le prochain sommet peut être trouvé. Cela pourrait donner un sens un peu plus si vous regardez ce schéma (désolé, c'est large, vous pouvez avoir à développer votre navigateur pour voir tous de celui-ci:

Quoi de plus facile, non? Si vous n'avez pas envie de taper la totalité, vous pouvez télécharger la version de l'entrelacé filer icosaèdre. J'ai aussi mis à jour ma OpenGL ES Xcode modèle avec ces nouvelles structures de données
Nous ne sommes pas encore en utilisant des bandes triangle, mais la fusion des triangles en bandes triangle va être un sujet pour un versement futur, car il est temps d'aller rencontrer des gens à la WWDC.
Ok, fait? Sous la section intitulée Optimisation des données de vertex, Il ya une recommandation quelque peu sibylline de «soumettre la bande-commandé triangles indexé avec les données par vertex entrelacées». Quand Apple fait une recommandation, ils ont généralement une bonne raison pour cela, nous allons donc voir comment nous nous conformons à celui-ci.
Tout d'abord, regardons ce que cela signifie. Faisons le décomposer:
Bande ordonné: En d'autres termes, si votre modèle a triangles adjacents, à les soumettre sous forme de bandes triangle plutôt que de soumettre chaque triangle individuellement. Nous avons parlé de l'aide de bandes de triangle en versements plus tôt, de sorte que vous savez déjà un peu de cela. Ce n'est pas toujours possible d'utiliser des bandes triangle, mais pour un bon nombre d'objets que vous pourrez, et quand vous le pouvez, vous devriez, car en utilisant des bandes triangle diminue fortement la quantité de données de vertex que vous avez à pousser dans OpenGL ES chaque trame.
indexed: Ce n'est pas nouveau. Nous avons été en utilisant des indices de vertex pour un certain temps maintenant. Notre filature icosaèdre les utilise pour créer vingt faces avec seulement douze sommets. glDrawElements () dessine une base plutôt que des indices des sommets.
Heck, nous faisons beaucoup jusqu'ici, ne sommes-nous? Jusqu'à présent, nous semblent faire toutes les bonnes choses! Regardons la dernière partie de la recommandation, toutefois:
avec les données par vertex entrelacées: D'accord, hmm .. Qu'est-ce que cela signifie?
Bon, le temps de tester votre mémoire. Vous souvenez-vous dans plusieurs des versements de temps passé, quand nous nous avons parlé des fonctions comme glVertexPointer (), glNormalPointer (), glColorPointer (), ou glTexCoordPointer? Dans les premiers versements, je vous ai dit de ne pas s'inquiéter du paramètre appelé la foulée et à seulement elle est définie pour 0.
Eh bien, maintenant vous pouvez commencer à s'inquiéter foulée, parce que c'est la clé de l'entrelacement des données par votre vertex.
Données par Vertex
Donc, vous demandez peut-être ce que "les données par vertex" et comment vous serait-il entrelacement.Vous vous souvenez, bien sûr, que dans OpenGL ES, nous passent toujours la géométrie en utilisant un éventail de vertex, qui est un tableau contenant des ensembles de trois GLfloats qui définissent les points qui composent nos objets. Parallèlement à cela, nous avons aussi parfois de spécifier d'autres données. Par exemple, si nous utilisons l'éclairage et la nécessité de normales au sommet, nous devons spécifier une normale par sommet dans notre gamme normale. si nous utilisons les coordonnées de texture, nous devons nous assurer que notre réseau de coordonnées de texture a un ensemble de coordonnées de texture par vertex. Et si nous utilisons une gamme de couleurs, nous devons spécifier une couleur par vertex. Avez-vous remarqué combien je continue à dire "par sommet"? Eh bien, ces types de données sont ce que Apple se réfère à quand ils disent "données par vertex" dans cette TechNote. C'est tout ce que vous transmettez comme un tableau dans OpenGL ES qui fournit tout type de données qui s'applique à des sommets dans le tableau de vertex.
Interleaving
Jusqu'à maintenant, dans cette série, nous avons créé un tableau pour stocker les données de vertex, et d'autres tableaux distincts pour contenir les données normales, les données couleur et / ou des données de coordonnées de texture, comme ceci:
Ce que nous allons apprendre à faire aujourd'hui est de Smush toutes ces données ensemble dans un seul bloc contigu de mémoire:

Ne vous inquiétez pas si vous ne pouvez pas lire le code dans cette illustration. Quand il devient important, je vais vous donner la liste de code à nouveau, c'est juste pour illustrer le point que nous allons avoir l'ensemble de nos données de vertex dans un glob unique de la mémoire. Qu'est-ce que ça va faire est de mettre toutes les données décrivant un seul sommet en un seul endroit dans la mémoire. Cela permettra OpenGL accès plus rapide aux informations sur chaque sommet. Dans versement d'aujourd'hui, nous allons sommets Interleave, normales, et les données de couleur, mais la même technique exacte serait travailler pour les coordonnées de texture, ou tout simplement pour un entrelacement sommets et les normales. En fait, dans le projet d'accompagnement Xcode, il ya des structures de données définies pour gérer tous les trois de ces scénarios d'entrelacement.
Définir un noeud Vertex
Pour que cela fonctionne, nous avons besoin d'une nouvelle structure de données. Afin de sommets Interleave, normales, et les données de couleur, nous avons besoin d'une structure qui ressemble à ceci:typedef struct {
Vertex3D vertex;
Vector3D normal;
Color3D color;
} ColoredVertexData3D;Assez simple, hein? Vous avez juste créer une structure avec chaque morceau de chaque sommet de données que nous utilisons.
Ensuite, bien sûr, nous avons besoin pour remplir nos données de vertex, nous avons donc besoin de combiner ces trois tableaux statiques const en un seul. Voici ce que les mêmes données icosaèdre ressemble spécifié en utilisant un tableau statique de notre nouveau type de données:
static const ColoredVertexData3D vertexData[] = {
{
{0, -0.525731, 0.850651}, // Vertex |
{0.000000, -0.417775, 0.675974}, // Normal | Vertex 0
{1.0, 0.0, 0.0, 1.0} // Color |
},
{
{0.850651, 0, 0.525731}, // Vertex |
{0.675973, 0.000000, 0.417775}, // Normal | Vertex 1
{1.0, 0.5, 0.0, 1.0} // Color |
},
{
{0.850651, 0, -0.525731}, // Vertex |
{0.675973, -0.000000, -0.417775}, // Normal | Vertex 2
{1.0, 1.0, 0.0, 1.0} // Color |
},
{
{-0.850651, 0, -0.525731}, // Vertex |
{-0.675973, 0.000000, -0.417775}, // Normal | Vertex 3
{0.5, 1.0, 0.0, 1.0} // Color |
},
{
{-0.850651, 0, 0.525731}, // Vertex |
{-0.675973, -0.000000, 0.417775}, // Normal | Vertex 4
{0.0, 1.0, 0.0, 1.0} // Color |
},
{
{-0.525731, 0.850651, 0}, // Vertex |
{-0.417775, 0.675974, 0.000000}, // Normal | Vertex 5
{0.0, 1.0, 0.5, 1.0} // Color |
},
{
{0.525731, 0.850651, 0}, // Vertex |
{0.417775, 0.675973, -0.000000}, // Normal | Vertex 6
{0.0, 1.0, 1.0, 1.0} // Color |
},
{
{0.525731, -0.850651, 0}, // Vertex |
{0.417775, -0.675974, 0.000000}, // Normal | Vertex 7
{0.0, 0.5, 1.0, 1.0} // Color |
},
{
{-0.525731, -0.850651, 0}, // Vertex |
{-0.417775, -0.675974, 0.000000}, // Normal | Vertex 8
{0.0, 0.0, 1.0, 1.0}, // Color |
},
{
{0, -0.525731, -0.850651}, // Vertex |
{0.000000, -0.417775, -0.675973}, // Normal | Vertex 9
{0.5, 0.0, 1.0, 1.0} // Color |
},
{
{0, 0.525731, -0.850651}, // Vertex |
{0.000000, 0.417775, -0.675974}, // Normal | Vertex 10
{1.0, 0.0, 1.0, 1.0} // Color |
},
{
{0, 0.525731, 0.850651}, // Vertex |
{0.000000, 0.417775, 0.675973}, // Normal | Vertex 11
{1.0, 0.0, 0.5, 1.0} // Color |
}
};Voici comment nous transmettre les informations en OpenGL. Plutôt que de transmettre le pointeur vers le tableau approprié, on passe de l'adresse du membre approprié de le premier sommet du tableau, et de fournir la taille de cette structure comme argument la foulée.
glVertexPointer(3, GL_FLOAT, sizeof(ColoredVertexData3D), &vertexData[0].vertex);
glColorPointer(4, GL_FLOAT, sizeof(ColoredVertexData3D), &vertexData[0].color);
glNormalPointer(GL_FLOAT, sizeof(ColoredVertexData3D), &vertexData[0].normal);Le paramètre le dernier dans chacun de ces appels une pointe vers les données correspondant au premier sommet. Ainsi des points de couleur, par exemple, & vertexData [0]. À l'information couleur pour le premier sommet. Le paramètre stride identifie combien d'octets de données qui doivent être ignorés avant le même type de données pour le prochain sommet peut être trouvé. Cela pourrait donner un sens un peu plus si vous regardez ce schéma (désolé, c'est large, vous pouvez avoir à développer votre navigateur pour voir tous de celui-ci:

Quoi de plus facile, non? Si vous n'avez pas envie de taper la totalité, vous pouvez télécharger la version de l'entrelacé filer icosaèdre. J'ai aussi mis à jour ma OpenGL ES Xcode modèle avec ces nouvelles structures de données
Nous ne sommes pas encore en utilisant des bandes triangle, mais la fusion des triangles en bandes triangle va être un sujet pour un versement futur, car il est temps d'aller rencontrer des gens à la WWDC.
Aucun commentaire:
Enregistrer un commentaire