2009-12-26 3 views
16

glLoadIdentity ditQuand faut-il appeler glGetError?

GL_INVALID_OPERATION est généré si glLoadIdentity est exécuté entre l'exécution de glBegin et l'exécution correspondante de glEnd.

Mais GL_INVALID_OPERATION est un indicateur renvoyé par glGetError.

Ma question est, quand devrions-nous appeler glGetError (afin de savoir si nous appelons opengl dans la bonne séquence)?

+1

Note: '' glBegin' et glEnd' [sont déconseillés] (http://gamedev.stackexchange.com/questions/34108/opengl-vbo-or-glbegin-glend). –

Répondre

22

Je ne sais pas si votre question concerne le moment où vous pouvez appeler glGetError si glBegin/End est une question plus générale sur l'utilisation de glGetError en général. Donc je vais répondre aux deux. Ce que vous pouvez faire entre glBegin et glEnd est très limité. Ceci est fait exprès, car vous mettez le GL dans un mode très spécifique - au milieu d'un tirage. En tant que tel, tout ce qui ne concerne pas directement les attributs par sommet est tout simplement invalide. Même un glGetError est invalide dans ce contexte. Essayez et pensez à glBegin + tous les appels GL entre + glEnd comme un seul appel Draw vers le GL, ce qui aide à se rapprocher de ce que le GL fait vraiment de toute façon.

Maintenant, vous ne devriez jamais avoir vraiment une erreur de GL déclenchée alors que l'intérieur du début/paire de fin si vous vous en tenez à la règle simple aux méthodes d'attributs uniquement d'appel (glNormal, glTexCoord, glColor, glSecondaryColor, glIndex, glMultiTexCoord, glVertexAttrib, glVertex et un couple d'autres). Tout le reste va déclencher une erreur. (erreur ... eh bien, glMaterial est un peu une exception, mais son utilisation a été déconseillée)

Si votre question est quand vous pouvez appeler glGetError lorsque l'erreur a été déclenchée dans une paire Begin/End, ChrisF a répondu dans un commentaire: après l'appel glEnd.

Maintenant, dans un sens plus large, utilisez glGetError uniquement comme outil de débogage. Mon parti pris est double:

  • contrôle glGetError une fois par image pour être sûr qu'il n'y a pas d'erreur
  • enveloppe la plupart des appels GL avec une macro qui permet de vérifier le code d'erreur GL, et ne l'activer lorsque le par La vérification de la trame échoue.

Bien sûr, étant donné que les méthodes d'attributs peuvent être appelés à l'extérieur Begin/paire de fin, il est un peu difficile de les obtenir droite. Mais dans la pratique, ces méthodes n'échouent jamais de toute façon, donc je ne prends pas la peine de les vérifier par macro.

Un petit mot de trivia: l'API GL a été conçue à l'origine de sorte que l'implémentation du client ne pouvait pas réellement savoir s'il y avait une erreur sur le site d'appel. Par exemple. si le GL était réellement implémenté dans une machine distante (comme dans les jours SGI), un appel à, par exemple, glTexEnv avec une cible non de GL_TEXTURE_ENV pourrait simplement être ajouté au tampon de commande, et aucune erreur ne serait enregistrée à ce point. Si vous appelez ensuite glGetError, le client doit alors vider le tampon de commande sur le serveur GL, attendre le traitement des commandes mises en mémoire tampon, récupérer le code d'erreur et renvoyer le code d'erreur approprié à L'application.

Si cela semble lourd, c'est parce que c'était. C'était la principale raison pour laquelle, en passant, chaque appel ne retournait pas un code d'erreur, et pourquoi appeler glGetError n'était considéré que correct pour le débogage. De nos jours, la plupart des implémentations de GL gèrent toutes les fonctions de gestion d'état dans le même processus, ce qui, comme je l'ai dit, est vraiment trivial pour la plupart des utilisateurs. Enfin, chaque fois que je parle de début/fin, je pense que je dois dire que vous devriez probablement ne pas l'utiliser du tout. Il s'agit de la façon la moins performante de dessiner avec GL.

4

Normalement, vous devriez appeler glGetError après tous les autres gl... appel comme l'un des effets de l'appel est d'effacer l'erreur de la pile (from the MSDN):

Lorsqu'une erreur se produit, l'indicateur d'erreur est réglé à la valeur de code d'erreur appropriée. Aucune autre erreur n'est enregistrée jusqu'à ce que glGetError soit appelé, le code d'erreur est renvoyé et l'indicateur est réinitialisé à GL_NO_ERROR.

Cependant, si vous avez des appels enveloppés dans glBegin et glEnd appel glError après la glEnd. Cela devrait vous renvoyer le code d'erreur correct (s'il y en avait un) et effacer la pile d'erreurs.

+0

Cependant, glGetError génère une erreur GL_INVALID_OPERATION si elle est appelée entre un appel glBegin et un appel glEnd. GlGetError ne peut donc pas être appelé après chaque appel gl .... –

+0

Ah - J'ai mal compris. Si vous avez des appels enveloppés dans 'glBegin' et' glEnd' appel 'glError' après le' glEnd'. – ChrisF

3

Certaines philosophies de codage s'attendent à ce que chaque programme vérifie toutes les erreurs possibles et traite ces erreurs de manière appropriée. Pourtant, suivre une de ces philosophies nécessite beaucoup de code supplémentaire, et peut considérablement ralentir un programme. En pratique, je n'utilise glGetError que lorsque je diagnostique un problème, ou j'écris du code qui a une possibilité significative d'échec et une action appropriée après l'erreur.

Dans le premier cas, diagnostiquant un problème, j'utilise l'une des deux stratégies suivantes. Parce que OpenGL n'enregistre pas de nouvelles erreurs jusqu'à ce que glGetError soit appelé, je peux soit vérifier les erreurs une fois à chaque fois à travers ma boucle principale. Cela me dit la première erreur, que je retrouve ensuite, et j'espère corriger. L'autre stratégie que j'utilise lorsque je me suis limité à un code problématique, mais je ne suis pas sûr de savoir quel appel cause le problème. Après chaque appel ... appelez en dehors d'un glBegin. . . bloc glEnd J'appelle glGetError et signale toute erreur. Cela me dira exactement quel gl ... appel est à l'origine du problème, et j'espère commencer moi sur le chemin d'une solution. Dans le second cas, en programmant de manière défensive pour une erreur probable, j'appelle glGetError pour effacer le drapeau d'erreur, fais mes autres appels ..., puis appelle glGetError. Ensuite, je prends toutes les mesures nécessaires pour gérer les rapports de glGetError.

Questions connexes