2017-09-25 3 views
3

Je calcule beaucoup de sommets, puis je les affiche avec des quadrichromie pour un tracé de surface 3D.Existe-t-il une connexion entre glPushMatrix() et glBegin()?

J'avais un comportement étrange pour certains sommets, changeant les couleurs de façon imprévisible. J'ai essayé de le réparer et par hasard, j'ai trouvé que le problème est résolu, quand je mets glPushMatrix() et glPopMatrix avant et après. Est-ce que quelqu'un sait quel pourrait être le problème sous-jacent? Dois-je généralement utiliser push/pop autour de glBegin/glEnd?

Voici mon code de travail:

for (int i = 1; i < vec.size(); i++) { 
    glPushMatrix(); 
    glBegin(GL_QUAD_STRIP); 
     for (int j = 0; j < vec[i].size(); j++) { 
      glNormal3dv(vertex_normal[i][j]); 
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, reflectance[i][j]); 
      glVertex3d(vec[i][j].x(), vec[i][j].y(),vec[i][j].z()); 

      glNormal3dv(vertex_normal[i-1][j]); 
      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, reflectance[i-1][j]); 
      glVertex3d(vec[i-1][j].x(), vec[i-1][j].y(), vec[i-1][j].z()); 
     } 
    glEnd(); 
    glPopMatrix(); 
} 
+0

Vous ne devez pas utiliser l'API obsolète. –

Répondre

5
  1. La taille de la pile est limitée !!!

    si vec.size() doit être inférieur ou égal à votre OpenGL taille de la pile de la matrice de mise en œuvre - couches utilisées avant de la boucle. Cela rend votre piratage un peu dangereux.

  2. Utilisez glGetError

    Vous devriez vérifier glGetError après toutes les grandes choses gl que vous utilisez (pendant le débogage et appliquez également jusqu'à ce qu'il retourne pas d'erreur). Il y a aussi des outils comme glIntercept qui font cela pour vous. Il devrait révéler où le problème est vraiment.

  3. manquant glEnd()

    Comme vous utilisez l'ancien api essayer d'ajouter quelques fois glEnd(); avant que la boucle. Si cela vous aide, vous avez manqué glEnd(); quelque part qui est un bug habituel avec les recrues comme glEnd; est également compilable mais ne fait rien.

    Cela pourrait être réinitialisé par le OpenGL après la matrice push/pop mais c'est pure spéculation de mon côté.

  4. appelant glMaterialfv à l'intérieur glBegin/glEnd

    Les OpenGL docs états:

    Les paramètres matériels peuvent être mis à jour à tout moment. En particulier, glMaterial peut être appelé entre un appel à glBegin et l'appel correspondant à glEnd. Si un seul paramètre de matériau doit être modifié par sommet, , glColorMaterial est préférable à glMaterial (voir glColorMaterial).

    Je voudrais essayer d'éviter d'utiliser glMaterial à l'intérieur glBegin/glEnd que mon expérience est que les mauvaises OpenGL implémentations (comme Intel) ne suit pas les spécifications à la lettre et peuvent causer des problèmes sur certaines plates-formes/circonstances avec utilisation hors du commun si pas maintenant alors à l'avenir ...

pour répondre à votre question: Aucun glBegin/glEnd ne devrait pas être affectée par glPushMatrix/glPopMatrix et vi ce verset s'ils sont utilisés correctement (push/pop n'est pas autorisé à l'intérieur de glBegin/glEnd et vous ne devez pas dépasser la limite de la pile).

+1

Je me suis débarrassé de l'appel 'glMaterial' et cela a résolu le problème. Merci pour la réponse très utile. –

4

Je vais prendre une autre position et dire que l'ajout d'un coup de pouce supplémentaire et de la pop ne devrait faire aucune différence.

Dans l'ancienne OpenGL, il existe plusieurs piles de matrices. En plus d'un tas d'opérations qui modifient tout ce qui est actuellement sur le dessus de la pile, dont vous n'avez pas, push et pop sont offerts. Poussez les doublons tout ce qui est en haut de la pile. Donc, si la pile était A B C D, elle devient A B C D D. Pop supprime tout ce qui se trouve en haut de la pile - il vous ramènera de A B C D D à A B C D.

Cela donne une structure qui s'intègre bien avec une pile d'appels. En obtenant une copie de l'ancien haut vous héritez des changements à ce jour. Vous pouvez ensuite apporter les modifications souhaitées, puis revenir en arrière et peu importe ce que vous appelez.

Ceci est complètement orthogonal de glBegin et glEnd qui dit simplement "commencer un lot de géométrie" et "terminer ce lot de géomtrie". La géométrie est affectée par les valeurs actuelles en haut des piles appropriées, mais vous ne modifiez pas réellement la valeur.

Je suppose donc que vous souffrez d'un comportement indéfini et que vous avez subi un correctif placebo pour votre machine particulière.