Sujets et Corrections
de TD et TP

Fichier zip
des exercices OpenGL

(avec Solution
Visual Studio
Pro 2015)

RETOUR

TD n°1 : Premières scènes OpenGL

Exercice n°1

(1) Programmer en OpenGL la scène suivante sous la forme d'une fonction C sans utiliser les fonctions glPushMatrix et glPopMatrix ailleurs qu'en début et fin de fonction:
Quatre cubes de coté 2.0 aux positions (2.0,0.0,2.0), (2.0,0.0,-2.0), (-2.0,0.0,2.0) et (-2.0,0.0,-2.0).

(2) Reprogrammer en OpenGL la scène de la question (1) de telle manière que les cubes aient une de leurs faces orientée vers l'origine du repère.

(3) Reprogrammer en OpenGL la scène de la question (2) en utilisant les fonctions glPushMatrix et glPopMatrix pour rendre les objets indépendants les uns des autres et simplifier l'écriture de la fonction scène.

(4) Programmer une scène OpenGL en plaçant 3 cubes de coté 2.0 aux 3 sommets d'un triangle équilatéral défini avec les caractéristiques suivantes:
  - rayon 1.5,
  - centré sur l'origine,
  - plongé dans le plan xOz.
Les 3 cubes présentent une de leurs faces orientée vers l'origine.

Exercice n°2

(1) Programmer la scène OpenGL modélisant un bras robot simplifié composé d'un bras et d'un avant-bras.
Le bras est articulé pour que sa base puisse tourner autour de l'axe Oy d'un angle r1. Il s'agit d'un parallélépipède rectangle de dimension (3.0,1.0,1.0).
L'avant-bras est articulé autour de l'axe y au bout du bras pour un angle r2. Il s'agit d'un parallélépipède rectangle de dimension (3.0,0.8,0.8).

(2) Modifier la fonction OpenGL de l'exercice n°1 en remplaçant les parallélépipèdes par des cylindres de tailles équivalentes.

Exercice 3

(1) Implanter en OpenGL une fonction de dessin d'une molécule de Benzène (C6H6).

Les atomes de carbone (atomes centraux) ont un rayon égal à 0.5.
Les liaisons entre 2 atomes de carbone ont pour longueur (centre à centre) 2.0 et pour rayon 0.15.
Les atomes d'hydrogène ont un rayon égal à 0.25.
Les liaisons entre atome de carbone et d'hydrogène ont pour longueur (centre à centre) 1.2 et pour rayon 0.05.
La molécule est centrée sur l'origine et placée dans le plan xOy.

(2) Modifier la modélisation de la molécule de benzène de la question précédente pour que les liaisons carbone-carbone soient alternativement des liaisons simples et des liaisons doubles (voir figure ci-dessous).
Les cylindres modélisant ces liaisons auront pour rayon 0.05 (comme les liaisons carbone-hydrogène). Dans le cas des liaisons doubles, les deux cylindres de modélisation seront écartés de 0.1.

Solutions

Quatre cubes (Question 3)
Trois cubes
Bras robot avec parallélépipèdes
Bras robot avec cylindres
Molécule de benzène

TP n°1 : Premières implantations OpenGL

Exercice n°1

Télécharger le fichier archive IG-2017-2018.zip. Ce fichier archive contient une "solution" Visual Studio 2015.
Après extraction, un répertoire IG-2017-2018 est créé. Ce répertoire contient lui-même 6 répertoires:
  - Bin pour les exécutables,
  - Include pour les fichiers d'entête OpenGL (fichiers non présents dans Visual Studio),
  - Lib pour les fichiers librairie OpenGL (fichiers non présents dans Visual Studio),
  - Projet pour le fichier de description de la solution (Projet.sln) et les répertoires contenant les projets faisant partie de la solution (Un seul répertoire actuellement: Exemple),
  - Src pour les fichiers source des projets inclus dans la solution,
  - Temp pour les fichiers temporaires (solution, compilation, ...).

La solution comprend un seul projet nommé Exemple. Ce projet inclut un seul fichier source Exemple.cpp et est configuré pour une compilation utilisant OpenGL:
  - fichiers d'entête (répertoire implicite ../../Include),
  - fichiers librairie (fichiers OpenGL32.ms.lib, glu32.ms.lib, glut32.ms.lib),
  - copie de l'exécutable dans le répertoire Bin.
La compilation (génération) de ce projet doit conduire à la création d'un exécutable nommé Exemple.exe dans le répertoire Bin. Son exécution requière les dll OpenGL32.dll et Glu32.dll (toujours présentes dans le système d'exploitation Windows) ainsi que la librairie Glut32.dll (jamais présente dans le système d'exploitation Windows mais dont il existe une copie dans le répertoire Bin).

(1) Extraire l'archive IG-2017-2018.zip. Lancer Visual Studio 2015 et charger la solution. Vérifier la compilation et l'exécution du projet Exemple.

(2) Implanter la question (3) de l'exercice n°1 du TD n°1. On pourra directement modifier le fichier Exemple.cpp de la question précédente pour y intégrer le code de génération de la scène.

(3) Implanter la question (4) de l'exercice n°1 du TD n°1.

(4) Implanter la question (1) de l'exercice n°2 du TD n°1.

Solutions

 

GLUT

Quatre cubes

Trois cubes

Bras robot avec des "cubes"

TD n°2 : Modélisation par facettes

Exercice n°1

(1) Modéliser par facettes un cube de coté c centré sur l'origine du repère de modélisation. On ne générera pas les normales.
La fonction créée aura pour prototype:
  void mySolidCube(double c);

TD02-01a.png TD02-01b.png 

(2) Modifier la modélisation de la question précédente pour ajouter la gestion des normales.
Le but est de rendre possible les calculs d'éclairage.

TD02-02a.png TD02-02b.png 

Exercice n°2

(1) Modéliser par facettes un cylindre selon les caractéristiques suivantes:
  - choix du rayon,
  - choix de la hauteur,
  - choix du nombre de facettes en découpage longitudinal pour une valeur entière ns,
  - centré sur l'origine du repère de modélisation,
  - axé selon y.
On ne modélisera pas les bases du cylindre, mais uniquement le tube.
La fonction créée aura pour prototype:
  void mySolidCylindre(double hauteur, double rayon, int ns);

(2) Ajouter un découpage latéral (selon l'axe y) pour une valeur nl.
Le prototype de la fonction devient:
  void mySolidCylindre(double hauteur, double rayon, int ns, int nl);

TD02-03a.png TD02-03b.png 

TD02-04.png

Solutions

 

GLUT

Cubes et cylindre par facettes

TP n°2 : Utilisation de GLUt

(1) Télécharger, compiler et exécuter le code source suivant : GLUt.cpp

(2) Analyser la manière avec laquelle l'amorçage de l'environement fenêtré et le fonctionnement événementiel de ce programme sont gérés. Une documentation de la bibliothèque GLUt peut être trouvée à l'URL suivante : glut-3-spec.pdf.

(3) Implanter la fonctions de modélisation de cylindre du TD n°2.

(4) Implanter la question (2) de l'exercice (2) du TD n°1: le bras robot avec utilisation de cylindres.

(5) Implanter les contrôles clavier qui permettront de gouverner les deux angles de définition du bras robot au moyen de touches du clavier.

Solutions

 

GLUT

Bras robot contrôlé au clavier

TP n°3 : Animation OpenGL avec GLUt

Le but du TP est d'implanter une animation où une sphère se déplace diagonalement selon une trajectoire rectiligne dans la fenêtre d'affichage OpenGL et semble rebondir sur les bords de la fenêtre.
Pour cela, on téléchargera le fichier Animation.cpp et on l'adaptera pour implanter l'animation. Ce fichier code l'affichage d'une sphère immobile en GLUt + OpenGL. Les caractéristiques de cet affichage sont les suivantes:
 - La sphère a pour rayon 1.0 et est initialement placée en position (1.5F, 5.0F, 0.0F). La position en x et en y de la sphère est en fait définie par les variables globales réelles px et py. La position en z ne change pas et a pour valeur 0.0F.
 - La projection d'affichage est réalisée selon l'axe -z. l'axe x est orienté de gauche à droite. L'axe y est orienté de bas en haut.
 - Quelles que soient les dimensions de la fenêtre d'affichage, son bord gauche est en x = -10.0, son bord droit est en x = 10.0. Le bord inférieur (resp. supérieur) de la fenêtre d'affichage est en y = -(10.0*wTy)/wTx (resp. (10.0*wTy)/wTx) où wTx et wTy sont des variables globales entières adoptant automatiquement comme valeur la largeur et la hauteur en pixels de la zone d'affichage de la fenêtre. wTx et wTy sont initialement égaux à 480. Les coordonnées des bords étant ainsi gérées, l'origine du repère est obligatoirement au centre de la fenêtre.
Comme spécifié ci-dessus, le déplacement doit être réalisé en diagonal. Ainsi, entre chaque image, la position (px, py) de la sphère doit être incrémentée en x et en y de la même valeur en valeur absolue. On utilisera la fonction idle pour gérer les variations de px et py ainsi que la détection d'un choc contre un bord et les ajustements à réaliser en conséquence. On n'oubliera pas de placer un appel à la fonction glutPostRedisplay() en fin de idle pour poster un événement "rafraichissement de l'affichage" qui aura pour conséquence l'exécution de la fonction display() avec les nouvelles coordonnées de la sphère.

Solutions

 

GLUT

Une animation OpenGL + GLUt

TD n°3 : Paramètrage numérique de caméras

a) On considère une caméra de visualisation en projection parallèle orthographique placée en position (0.0, 0.0, 0.0) orientée selon l'axe (0.0, 0.0, -1.0). On considère une scène centrée sur le point de coordonnées (0.0, 0.0, -100.0) et occupant un volume circulaire de rayon 10.0.
Quelle ouverture doit-on donner à cette caméra pour visualiser cette scène en gros plan dans la fenêtre d'affichage?

b) On considère une caméra de visualisation en projection en perspective placée en position (0.0, 0.0, 0.0) orientée selon l'axe (0.0, 0.0, -1.0). On considère une scène centrée sur le point de coordonnées (0.0, 0.0, -100.0) et occupant un volume circulaire de rayon 10.0.
Quelle ouverture doit-on donner à cette caméra pour visualiser cette scène en gros plan dans la fenêtre d'affichage?

Solutions

 

GLUT

Ouverture d'une caméra orthographique

Ouverture d'une caméra en perspective

TP n°4 : Caméras OpenGL

Le but du TP est de montrer la manière avec laquelle les caméras sont gérées en OpenGL et plus généralement en informatique graphique. Pour cela, on téléchargera le fichier source GestionCamera.cpp et on l'adaptera en fonction des questions.

a) Télécharger, installer, compiler et exécuter le fichier source GestionCamera.cpp. Ce fichier contient une fonction reshape permettant de modéliser une caméra de visualisation en projection orthographique réalisant une projection selon l'axe -0z pour un observateur placé en position (0.0, 0.0, +infini). La scène affichée et centrée sur l'origine et s'incrit dans un volume sphérique de rayon 10.0. La scène est visualisée en gros plan.

b) Adapter l'appel à glOrtho du programme précédent pour que, quelle que soit la résolution de la fenêtre, la scène soit affichée en aussi gros plan que possible sans être tronquée horizontalement ou verticalement.

c) Modifier la fonction reshape par:
 - retrait de l'appel à la fonction glOrtho et remplacement de cet appel par un appel à la fonction gluPerspective,
 - ajout d'un appel à la fonction gluLookAt.
L'appel à gluLookAt est à placer tout à fait en fin de fonction après le second appel à glLoadIdentity de façon que cet appel s'intercale dans le flux d'exécution OpenGL entre les définition/paramétrage de la caméra et la modélisation de la scène.
Ces deux appels de fonction seront paramétrés de façon que la caméra de visualisation soit virtuellement placée en position (0.0, 0.0,100.0), qu'elle soit orientée en direction de l'origine (là où se trouve la scène) et que la direction de la verticale soit la direction y. Il conviendra de plus que la scène soit visualisée en gros plan.

d) Modifier les paramétrages réalisés à la question (c) pour que la caméra soit virtuellement placée en position (100.0, 0.0, 100.0) tout en "regardant" vers l'origine et en conservant une visualisation en gros plan.

e) Modifier les paramétrages réalisés à la question (d) pour que la caméra soit virtuellement placée en position (100.0, 100.0, 100.0) tout en "regardant" vers l'origine et en conservant une visualisation en gros plan.

f) Reprendre les questions (c), (d) et (e) pour retirer l'appel à la fonction gluLookAt et le remplacer par les appels à glTranslatef et glRotatef qui conduisent exactement au même résultat.

Solutions

 

GLUT

Gestion des caméras

TP n°5 : Lumières et matériel

Le but du TP est de montrer la manière avec laquelle les lumières et un matériel sont gérés en OpenGL et plus généralement en informatique graphique. Pour cela, on téléchargera le fichier source MaterielEtLumieres.cpp et on l'adaptera en fonction des questions.

a) Télécharger, installer, compiler et exécuter le fichier source MaterielEtLumieres.cpp. Ce fichier contient une application complète permettant l'affichage du scène centrée sur l'origine du repère de modélisation. Cette scène est contituée de 6 cylindres et de 8 sphères organisés pour que les cylindres matérialisent les arêtes d'un cube et les sphères matérialisent les sommets de ce cube. L'affichage est réalisé avec tous les objets colorés en blanc. La scène est animée par rotation sur elle-même.  

b) Activer la gestion OpenGL des lumières et d'un matériel.

c) Activer la lumière n°0.

d) Configurer la lumière n°0 pour qu'elle devienne une lumière directionnelle provenant de la gauche.

e) Configurer la lumière n°0 pour qu'elle devienne une lumière ponctuelle placée en position (15.0,15.0,15.0)

f) Configurer la lumière n°0 pour qu'elle devienne une lumière spot placée en position (-15.0,15.0,15.0), d'angle "cutOff" de 10.0° et qu'elle soit orientée vers l'origine.

g) Configurer la lumière n°0 pour qu'elle devienne une lumière ponctuelle diffusante blanche placée en position (15.0,15.0,15.0) et que la scène soit munie d'un matériel diffusant dans le rouge. Les autres caractéristiques de la lumière n°0 et du matériel restent à leurs valeurs par défaut.

h) Configurer la lumière n°0 pour qu'elle devienne une lumière ponctuelle diffusante et spéculaire blanche placée en position (15.0,15.0,15.0) et que la scène soit munie d'un matériel diffusant dans le rouge, réfléchissant spéculairement dans le blanc et de réflectivité égale à 60.0. Les autres caractéristiques de la lumière n°0 et du matériel restent à leurs valeurs par défaut.

i) Configurer la lumière n°0 pour qu'elle devienne une lumière directionnelle diffusante rouge et spéculaire blanche provenant de la gauche. Configurer et activer la lumière n°1 pour qu'elle devienne une lumière ponctuelle diffusante verte et spéculaire blanche placée en position (15.0,15.0,15.0). Configurer et activer la lumière n°2 pour qu'elle devienne une lumière spot diffusante bleue et spéculaire blanche placée en position (-15.0,15.0,15.0), orientée vers l'origine et l'angle "cutOff" égal à 10.0°. Configurer le matériel utilisé pour la scène de façon qu'il soit diffusant dans le blanc, réfléchissant spéculairement dans le blanc et de réflectivité égale à 60.0. Les autres caractéristiques des lumières et du matériel restent à leurs valeurs par défaut.

Solutions

 

GLUT

Lumières et matériel

TD n°4 : Animation de lumières

Reprendre le fichier MaterielEtLumieres.cpp du TP n°5. Modifier ce fichier de manière que la scène devienne immobile et que les lumières tournent autour.

TP n°6 : Plaçage de texture bitmap: Texture unique

L'archive zip suivante contient les fichiers sources d'une librairie de gestion des fichiers png: Png.zip.
Plus précisément, les deux fonctions d'importation et d'exportation sont décrites dans le fichier ChargePngFile.h.
La fonction d'importation prend en paramètre le nom du fichier à importer et deux pointeurs sur entier destinés à récupérer la résolution en x et la résolution en y de l'image importée. Elle retourne un pointeur sur unsigned char correspondant au tableau d'octets issu de l'importation (NULL si échec). Le tableau retourné est alloué dynamiquement par malloc et se doit d'être libéré par free après utilisation. Il contient les composantes RVB des pixels codées sur 8 bits et entrelacées.

a) Importer cette archive, en faire l'extraction, inclure l'ensemble des fichiers qu'elle contient dans un projet de développement, vérifier la compilation et l'exécution par importation d'une image png sous la forme d'un tableau de pixels (sans affichage). On pourra se servir de l'image Test.png qui est formée d'une matrice de 64x64 pixels dont la première ligne est bleue.

b) Implanter un programme OpenGL de dessin d'un carré de coté 6.0 sur lequel est placée une image bitmap.

c) Implanter un programme OpenGL de modélisation d'un cylindre sur le tube duquel est placée une texture bitmap.

On pourra utiliser et adapter la fonction ci-dessous.

/* Modelisation par facettes d'un cylindre  */

#ifndef M_PI
#define M_PI 3.14159265358979
#endif

static void myCylindre(double hauteur,double rayon,int ns) {
  glPushMatrix();
  hauteur /= 2.0F;
  glBegin(GL_QUAD_STRIP);
  forint i = 0 ; i <= ns ; i++ ){
    double a = (2.0*M_PI*i)/ns;
    float cs = cos(a);
    float sn = -sin(a);
    glNormal3f(cs,0.0F,sn);
    float x = rayon*cs;
    float z = rayon*sn;
    glVertex3f(x,hauteur,z);
    glVertex3f(x,-hauteur,z); }
  glEnd();
  glPopMatrix();
}

On pourra se reporter au chapitre sur le texturage pour une description plus précise des principes utilisés pour cette technique et à la partie 3 du chapitre sur OpenGL pour son application en OpenGL. 

Solution

 

GLUT

Texture bitmap placée sur un carré

Texture bitmap placée sur un cylindre

TD n°5 et n°6 : Coordonnées homogènes et test de planarité

Exercice n°1

Proposer une méthode permettant de tester la planarité d'une facette non dégénérée à 4 sommets.

Exercice n°2

a) Développer en C++ une classe CoordonneesHomogenes3D.

b) Dériver de la classe CoordonneesHomogenes3D une classe Position3D pour le stockage de positions dans un espace à trois dimensions.

c) Dériver de la classe CoordonneesHomogenes3D une classe Direction3D pour le stockage de directions dans un espace à trois dimensions.

d) Développer une méthode de calcul du produit scalaire de deux Direction3D.

e) Développer une méthode de calcul du produit vectoriel de deux Direction3D.

f) Implanter une fonction ou une méthode de test de la planarité de facettes à 4 sommets.

Solutions

 

CMD

Coordonnées homogènes et test de planarité

TP n°7 : Plaçage de texture bitmap: Textures multiples

Le TP n°6 a illustré l'utilisation d'une seule texture dans un programme à affichage 3D géré en OpenGL. Si plusieurs textures doivent être utilisées, il est possible, à chaque changement de texture, de charger la nouvelle texture en mémoire de la carte graphique au moyen de l'instruction glTexImage2D. Toutefois, cette opération étant longue, les performances obtenues risquent fortement d'être mauvaises. Depuis OpenGL 1.1, il est possible, dans un premier temps, de charger toutes les textures à utiliser en mémoire de la carte graphique, puis, avant de modéliser chaque objet graphique, d'indiquer laquelle des textures en mémoire doit être utilisée:
Au lieu d'exécuter un glTexImage2D chaque fois d'un objet doit être modélisé et donc texturé, on effectue, avant de commencer à modéliser, autant de glTexImage2D qu'il y a de textures.

Les opérations à réaliser sont:
 - En début de programme, utiliser la fonction glGenTextures(int n,unsigned int *texturesID) pour réserver n handles numériques permettant de référencer individuellement une texture et stocker ces handles dans le tableau texturesID (de taille suffisante).
 - En cours de programme, utiliser la fonction glBindTexture(enum target,unsigned int textureID) avec target égal à GL_TEXTURE_2D et textureID égal au handle de la texture concernée pour indiquer, qu'à partir de maintenant, toute opération impliquant une texture (chargement, paramètrage, utilisation, ...) concernera la texture référencée par le handle textureID.
 - En fin de programme, utiliser la fonction glDeleteTextures(int n,unsigned int *texturesID) pour libérer les n textures stockées en mémoire graphique dont les handle sont stockés dans le tableau texturesID.

Reprendre la question (b) du TP n°6 pour modéliser géométriquement 3 facettes carrées au lieu d'une seule en plaçant sur chacune de ces facettes une texture différente. On pourra utiliser les images stockées dans les fichiers suivants:
 - Test1.png
 - Test2.png
 - Test3.png

Solution

 

GLUT

Textures bitmap placées sur des carrés

TD n°7 : Coordonnées homogènes et transformations géométriques

Exercice n°1

a) Développer en C++ une classe TransformationGeometrique3D en coordonnées homogènes.

b) Dériver de la classe TransformationGeometrique3D une classe Translation3D pour le stockage d'opérateurs de type translation de vecteur (tx, ty, tz).

c) Dériver de la classe TransformationGeometrique3D une classe Rotation3D pour le stockage d'opérateurs de type rotation d'angle a autour de l'axe (ax, ay, az) passant par l'origine.

d) Implanter une méthode de transformation d'une position ou d'une direction par une translation ou une rotation.

e) Implanter une méthode de composition d'une transformation géométrique par une transformation géométrique.

Solutions

 

CMD

Transformations géométriques

TP n°8 : Coordonnées homogènes

Implanter le TD n°5-6

Solutions

 

CMD

Coordonnées homogènes et test de planarité

 

TP n°9 : Transformations géométriques en coordonnées homogènes

Exercice n°1

a) Implanter le TD n°7

b) Utiliser l'implantation de la question (a) pour implanter l'exemple de cours portant sur la possibilité de modéliser en une transformation géométrique la composition de transformations géométriques

Solutions

 

CMD

Transformations géométriques

Hiérarchie de classes

Vecteur4     CoordonneesHomogenes3D     Position3D
       
             
            Dimension3D
           
             
Matrice4x4     TransformationGeometrique3D     Translation3D
       
             
      MatriceDeBase     Rotation3D
         
             
            Scale3D
           
             
            LookAt
           
             
Rvb     Couleur      
         
             
      Energie      
           
             
             
Lumiere     LumierePonctuelle     LumiereSpot
       
             
      LumiereDirectionnelle      
           
             
Materiel            
           
             
Objet     Sphere