bg150.jpg (723 octets)

Plantages OpenGL et GLUT
Symptomes
Causes probables
Résolution

SYMPTOMES ET
CAUSES PROBABLES

BUG PROGRAMME
ET RESULTAT
OBTENU A L'ECRAN

CONSEILS
POUR VERIFIER
UN PROGRAMME
OPENGL ET GLUT

CONSEILS
POUR CONCEVOIR
UN PROGRAMME
OPENGL ET GLUT


RETOUR

 

Symptomes et causes probables

L'application plante avant l'ouverture de la fenêtre d'affichage 3D.

Cause:

  • Une fonction gl ou glu est exécutée avant l'exécution du glutCreateWindow.

L'application ne plante pas mais s'arrête sans qu'une fenêtre ait été ouverte.

Cause:

  • glutMainLoop n'est pas appelé dans la fonction main.

L'application plante après l'ouverture de la fenêtre d'affichage 3D.

Cause:

  • La fonction display ou la fonction reshape plante.

La fenêtre d'affichage 3D s'ouvre et affiche l'arrière plan de l'interface utilisateur.
Rien n'est réellement affiché dans la fenêtre d'affichage alors que le programme semble fonctionner normalement.

Cause:

  • GLUT est utilisé avec un double-buffer et glutSwapBuffers n'est pas appelé après le glFlush ou le glFinish de fin de display.

La fenêtre d'affichage 3D s'ouvre et affiche un fond de couleur aléatoire (uni ou non, bigaré ou non,...).
Les images semblent s'accumuler les unes sur les autres.

Cause:

  • glClear(GL_COLOR_BUFFER_BIT) n'est pas exécuté au début de la fonction display.

La fenêtre d'affichage 3D s'ouvre.
L'élimination des parties cachées ne fonctionne pas correctement au delà de la première image affichée.

Cause:

  • glClear(GL_DEPTH_BUFFER_BIT) n'est pas exécuté au début de la fonction display.

La fenêtre d'affichage 3D s'ouvre.
Les scènes affichées sont déformées quand l'utilisateur change la taille de la fenêtre d'affichage.

Cause:

  • L'appel de fonction (glOrtho, glOrtho2D, glFrustum ou gluPerspective usuellement exécuté dans la fonction reshape) qui définit la caméra de visualisation associée à la fenêtre d'affichage n'adapte pas le rapport ouverture horizontale sur ouverture verticale de la caméra au rapport largeur sur hauteur de la fenêtre.
  • En raison d'une division entière au sein de la fonction reshape, lappel de fonction (glOrtho, glOrtho2D, glFrustum ou gluPerspective) qui définit la caméra de visualisation associée à la fenêtre d'affichage n'adapte pas correctement le rapport ouverture horizontale sur ouverture verticale de la caméra au rapport largeur sur hauteur de la fenêtre.

La fenêtre d'affichage 3D s'ouvre et reste uniformément de couleur de fond.

Causes:

  • Aucune caméra de visualisation n'est associée à la fenêtre d'affichage.
  • La caméra de visualisation associée à la fenêtre d'affichage possède un volume de visualisation n'incluant pas la scène.
  • La gestion des lumières est activée et aucune lumière n'est allumée.
  • Les lumières nécessaires sont allumées mais elles ne sont pas ou pas correctement paramétrées par appels à glLight (les lumières 1 à n ont des valeurs par défaut équivalentes au noir).

La fenêtre d'affichage 3D s'ouvre. La scène se "déplace" incorrectement d'une image à l'image suivante.

Cause:

  • Le dessin d'une image réalisé par une exécution de la fonction display n'est pas isolé du dessin de l'image précédente réalisé à l'exécution précédente de la fonction display. Il n'y a pas de couple (glPushMatrix, glPopMatrix) pour inclure toutes les transformations géométriques réalisées pour un display.

La fenêtre d'affichage 3D s'ouvre. La scène est dessinée avec des caractéristiques de couleur et d'éclairage différentes d'une image à l'image suivante.

Cause:

  • Le dessin d'une image réalisé par une exécution de la fonction display n'est pas isolé du dessin de l'image précédente réalisé à l'exécution précédente de la fonction display:
    - Un matériel reste configuré.
    - Des lumières restent configurées.
    - ...

Les objets sont éclairés différemment suivant leur grosseur.

Cause:

  • Les glScale s'appliquant aussi sur les normales de modélisation des objets, celles-ci perdent leurs normes de valeur 1. Les calculs d'éclairage utilisant les normales, ceux-ci sont perturbés.

Solution:

  • Ne pas utiliser de glScale.
  • Utiliser glEnable(GL_NORMALIZE) pour signifier à OpenGL de normer toutes les normales qu'il manipule avant de les utiliser.
    Par souci d'optimisation, on placera entre glEnable(GL_NORMALIZE), glDisable(GL_NORMALIZE) les seules zones de code OpenGL posant problème.

Les objets volumiques ne sont pas affichés correctement.

Cause:

  • L'élimination des parties cachées n'est pas activée.

Aucune animation ne semble être réalisée.

Causes:

  • La fonction idle existe mais n'a pas été spécifiée à GLUT via glutIdleFunc(idle).
  • La fonction idle ne réalise pas de glutPostRedisplay()
    -> Aucune nouvelle image n'est générée entre chaque exécution de idle par GLUT.
  • La fonction idle ne modifie pas les variables globales utilisées dans la fonction display.

Bugs et résultats généralement constatés à l'écran

  • Une fonction gl ou glu est exécutée avant l'exécution du glutCreateWindow.
    -> L'application plante sans même ouvrir une fenêtre.
  • glutMainLoop n'est pas appelé dans la fonction main.
    -> L'application ne plante pas mais s'arrête sans qu'une fenêtre ait été ouverte.
  • La fonction display ou la fonction reshape plante.
    -> L'application plante après l'ouverture de la fenêtre d'affichage 3D.
  • GLUT est utilisé avec un double-buffer et glutSwapBuffers n'est pas appelé après le glFlush ou le glFinish de fin de display.
    -> Le programme semble fonctionner normalement. La fenêtre d'affichage 3D s'ouvre mais n'affiche que l'arrière plan de l'interface utilisateur. Ou rien n'est réellement affiché dans la fenêtre d'affichage.
  • glClear(GL_COLOR_BUFFER_BIT) n'est pas exécuté au début de la fonction display.
    -> La fenêtre d'affichage 3D s'ouvre et affiche un fond de couleur aléatoire (uni ou non, bigaré ou non,...). Les images semblent s'accumuler les unes sur les autres.
  • glClear(GL_DEPTH_BUFFER_BIT) n'est pas exécuté au début de la fonction display.
    -> La fenêtre d'affichage 3D s'ouvre. L'élimination des parties cachées ne fonctionne pas correctement au delà de la première image affichée.
  • L'appel de fonction (glOrtho, glOrtho2D, glFrustum ou gluPerspective usuellement exécuté dans la fonction reshape) qui définit la caméra de visualisation associée à la fenêtre d'affichage n'adapte pas correctement le rapport ouverture horizontale sur ouverture verticale de la caméra au rapport largeur sur hauteur de la fenêtre.
    -> La fenêtre d'affichage 3D s'ouvre. Les scènes affichées sont déformées quand l'utilisateur change la taille de la fenêtre d'affichage.
  • Aucune caméra de visualisation n'est associée à la fenêtre d'affichage.
    -> La fenêtre d'affichage 3D s'ouvre et reste uniformément de la couleur de fond.
  • La caméra de visualisation associée à la fenêtre d'affichage possède un volume de visualisation n'incluant pas la scène.
    -> La fenêtre d'affichage 3D s'ouvre et reste uniformément de la couleur de fond.
  • La gestion des lumières est activée et aucune lumière n'est allumée.
    -> La fenêtre d'affichage 3D s'ouvre et reste uniformément de la couleur de fond.
  • Les lumières nécessaires sont allumées mais elles ne sont pas ou pas correctement paramétrées par appels à glLight (les lumières 1 à n ont des valeurs par défaut équivalentes au noir).
    -> La fenêtre d'affichage 3D s'ouvre et reste uniformément de la couleur de fond.
    -> Les éclairages sont incorrectement gérés d'une image sur une autre.
  • Le dessin d'une image réalisé par une exécution de la fonction display n'est pas isolé du dessin de l'image précédente tel que réalisé à l'exécution précédente de la fonction display:
    - Il n'y a pas de couple (glPushMatrix, glPopMatrix) pour inclure toutes les transformations géométriques réalisées pour un display.
    - Un matériel reste configuré.
    - Des lumières restent configurés.
    - ..
    .
    -> La fenêtre d'affichage 3D s'ouvre.
       - La scène se "déplace" incorrectement d'une image à l'image suivante.
       - Les caractéristiques de couleur et d'éclairage de la scène changent d'une image à la suivante.
    - ...
  • Des glScale sont utilisés imprudemment et s'appliquent sur les normales de modélisation des objets.
    -> Les objets sont éclairés différemment suivant leur grosseur.
    Solutions:
       - Ne pas utiliser de glScale.
       - Utiliser glEnable(GL_NORMALIZE) pour signifier à OpenGL de normer toutes les normales qu'il manipule avant de les utiliser.
    Par souci d'optimisation, on placera entre glEnable(GL_NORMALIZE), glDisable(GL_NORMALIZE) les seules zones de code OpenGL posant problème.
  • L'élimination des parties cachées n'est pas activée.
    -> Les objets volumiques ne sont pas affichés correctement.
  • La fonction idle existe mais n'a pas été spécifiée à GLUT via glutIdleFunc(idle).
    -> Aucune animation ne semble être réalisée.
  • La fonction idle ne réalise pas de glutPostRedisplay() et donc aucune nouvelle image n'est générée entre chaque exécution de idle par GLUT.
    -> Aucune animation ne semble être réalisée.
  • La fonction idle ne modifie pas les variables globales utilisées dans la fonction display.
    -> Aucune animation ne semble être réalisée.
  • Une division entière est réalisée maladroitement et entraine un arrondi à l'entier inférieur.
    -> Le rapport largeur fenêtre sur hauteur fenêtre utilisé dans la fonction reshape pour conserver inchangé le rapport ouverture horizontale sur ouverture verticale est mal calculé et entraine donc des problèmes d'affichage.

Conseils de vérification des programmes OpenGL et GLUT

  • Utiliser glGetError() pour vérifier qu'aucune erreur OpenGL ne se produit au cours de l'exécution.
    On pourra inclure la portion de code suivante juste après le glFlush ou glFinish de fin de display:
    int error = glGetError();
    if ( error != GL_NO_ERROR )
      printf("Attention erreur : %d\n",error);
  • Programmer un mode de visualisation en fil de fer pour vérifier les objets.
  • Programmer un mode de visualisation avec manipulation ou animation de la scène pour vérifier les objets.
  • Programmer une couleur de fond différente du noir pour vérifier si la scène est dessinée sans que les éclairages fonctionnent.
Ne jamais appeler soi-même la fonction display. Un glutPostRedisplay() permet de demander à GLUT de l'exécuter.
  • Ne jamais appeler soi-même la fonction reshape. Si elle contient du code à réexécuter, déplacer ou recopier ce code dans la fonction display et poster un redisplay.
  • Utiliser printf pour envoyer des message dans la console d'où a été lancée l'application OpenGL. la fonction display et poster un redisplay.
  • Utiliser printf pour envoyer des message dans la console d'où a été lancée l'application OpenGL.
  • Isoler les appels gl et glu ne devant être réalisés qu'une fois et une seule au sein d'une fonction init lancées après le glutCreateWindow() et avant le glutMainLoop().
    Placer dans la fonction display tous les appels de fonction gl et glu devant être réalisés plusieurs fois au cours de la vie du programme.
  • Ne pas placer d'appel de fonction gl et glu ailleurs que dans les fonctions display et reshape.
    -> Meilleur contrôle de l'ordonnancement de ces appels (qui doit être déterministe) au sein de la gestion événementielle réalisée par GLUT.
    Dans toutes les autres fonctions spécifiées à GLUT, ne réaliser que des modifications de variables globales utilisées dans display et reshape.
    Ainsi conçu un programme ne réalisera que des appels successifs à Ne pas programmer de fonction idle "vide" (i.e. qui éventuellement ne réalise rien). Si aucune tâche de fond (animation ou autre) n'est nécessaire, supprimer la spécification antérieure d'une  fonction idle via un appel glutIdleFunc(NULL).
  •