Question

Mon programme utilise Pyopengl (donc c'est Python) avec PSYCO.

J'ai environ 21 000 segments de ligne que je dois rendre dans chaque cadre de mon rendu (sauf si l'utilisateur zoome, auquel cas les segments de ligne sont abattus et non envoyés à la carte). Cela prend actuellement environ 1,5 seconde chaque cadre à terminer. Ce n'est tout simplement pas assez bon, donc je cherche des moyens de réduire le nombre de segments de ligne distincts.

J'imagine qu'il y aurait des cas où plusieurs segments de ligne peuvent être fusionnés en une seule grande ligne, mais honnêtement, je ne sais même pas par où commencer. J'ai le point de départ et le point final de chaque ligne stockée, donc cela pourrait aider les choses. Notez que je suis capable de prendre aussi longtemps que je dois au démarrage, et l'utilisation de la mémoire n'est pas trop préoccupante.

Toutes les idées seraient très appréciées.

Était-ce utile?

La solution

C'est presque certainement les frais généraux de tous les appels de fonction de mode immédiat qui tuent vos performances. Je ferais ce qui suit.

N'utilisez pas GL_LINE_STRIPS, utilisez une seule liste de GL_LINES Au lieu de cela, ils peuvent être rendus en une seule fois.

Utilisation glDrawArrays Au lieu d'un rendu de mode immédiat:

float* coordinates = {....}; //x and y coordinate pairs for all line segments
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 2 * sizeof(float), coordinates);
glDrawArrays(GL_LINES, 0, 2 * linecount);
glDisableClientState(GL_VERTEX_ARRAY);

(Pour des performances encore meilleures, vous pouvez stocker le tampon de sommet dans quelque chose appelé un objet tampon de sommet, mais cela devrait être bien pour commencer)

Une dernière chose, si vous abattez par ligne, il est probablement plus rapide de le sauter et d'envoyer toutes les lignes au GPU.

Autres conseils

Les segments de 20K ne sont pas tellement. En outre, vous aurez de la chance lorsque vous pourrez fusionner 10 à 100 lignes par cadre, donc l'accélération par cette optimisation sera négligeable. Le processus de rendu est probablement lent car vous créez le modèle encore et encore. Utilisation glNewList() Pour enregistrer toutes les commandes de rendu dans une liste de rendu GL sur la carte, puis il suffit d'émettre glCallList() Pour le rendre avec une seule commande.

Vous pouvez définir une métrique d'erreur pour fusionner deux segments de ligne en un, puis tester toutes les paires de segments, puis les fusionner si l'erreur est inférieure à un certain seuil.

Un exemple est cet algorithme:

  1. Construisez un nouveau segment de ligne X des deux points les plus éloignés les uns des autres dans les deux segments de ligne A et B.
  2. Trouvez la distance minimale à X pour tous les points en A et B.
  3. Attribuez l'erreur comme le maximum de ces distances minimales.
  4. Remplacez A et B par x si l'erreur est en dessous de votre seuil.

Ce n'est pas le meilleur algorithme, mais il est facile à mettre en œuvre.

Modifier 1

Essayez certainement de faire des listes d'affichage ou un rendu d'objet tampon de sommet avant de l'implémenter.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top