Sujets et Corrections
de TD et TP

Fichier zip
des exercices OpenGL

(avec Solution
Visual Studio 2015)

RETOUR

TP n°1 et TP n°2 : Premières implantations OpenGL

Exercice n°1

Télécharger le fichier archive IG-2020-2021.zip. Ce fichier archive contient une "solution" Visual Studio 2015. Une solution est un package destiné à contenir des projets de développement (exécutables, librairies, dll, drivers, ...). Une solution est formée à minima d'un fichier .sln quand elle ne contient aucun projet de développement. Elle consistera plus généralement en un fichier .sln, en les fichiers .vcxproj des projets qu'elle inclut et en les fichiers (source ou autre) nécessaires à la compilation de ces projets. Il est bon que tout cela soit organisé physiquement en répertoires pour que tout ne soit pas mélangé.
Après extraction, un répertoire IG-2020-2021 est créé. Ce répertoire contient lui-même 6 répertoires :
  - Bin pour les exécutables générés,
  - Include pour les fichiers d'entête OpenGL (fichiers non présents par défaut dans Visual Studio),
  - Lib pour les fichiers librairie OpenGL (fichiers non présents par défaut 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 (compilation, ...).

Le contenu de la solution peut être visualisé dans Visual Studio en utilisant l'explorateur de solution. La solution fournie comprend un seul projet de développement nommé Exemple. Ce projet référence un seul fichier source Exemple.cpp et est préconfiguré pour une compilation utilisant OpenGL :
  - utilisation des fichiers d'entête (répertoire implicite ../../Include),
  - utilisation des fichiers librairie : OpenGL32.ms.lib et glu32.ms.lib dans les propriétés de configuration du projet et glut32.ms.lib par référence directe dans l'explorateur de solution,
  - copie post édition de liens dans le répertoire Bin de l'exécutable généré dans un sous-répertoire du répertoire Temp.
La génération (compilation puis édition de liens) 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 par défaut dans le système d'exploitation Windows) ainsi que la dll Glut32.dll (jamais présente par défaut dans le système d'exploitation Windows mais dont il existe une copie dans le répertoire Bin où est copié l'exécutable).

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

2) Le fichier code source GLUtMinimum.cpp illustre le fonctionnement événementiel de la librairie GLUt. On rappelle que nous allons utiliser cette librairie annexe à OpenGL pour construire l'interface utilisateur de nos programmes OpenGL, celui-ci ne contenant aucune fonction dédiée à cette fin.

Le fichier source GLUtMinimum.cpp contient le minimum d'appels possible à OpenGL tout en affichant quand-même quelque chose, de façon à mettre en évidence les fonctionnalités GLUt et non les fonctionnalités OpenGL.
La scène construite est constituée d'un unique tore muni du matériel par défaut d'OpenGL. Le calcul d'illumination est activé et une seule lumière est allumée. L'élimination des parties cachées est activée. La projection est réalisée en projection orthographique. Le contenu du volume cubique dont la diagonale est définie par les positions (-1.0,-1.0,-1.0) et (1.0,1.0,1.0) du repère de modélisation est affiché dans le viewport de visualisation en projection selon l'axe -z du repère de modélisation. Le viewport de visualisation est configuré pour occuper automatiquement (dynamiquement) l'intégralité de la fenêtre.
La fonction main organise les points suivants :
  - exécution d'une fonction (static void clean(void)) lorsque l'application est interrompue par exécution de la fonction standard exit,
  - configuration et création de la fenêtre de visualisation,
  - configuration des paramètres OpenGL qui doivent l'être et qui n'auront pas à être reconfigurés au cours de la vie du programme (appels regroupés dans la fonction init),
  - programmation de la gestion des événements,
  - affichage de la fenêtre de visualisation et lancement de la boucle infinie de gestion des événements.

Les événements suivants sont gérés "normalement" avec exécution de code OpenGL :
  - rafraichissement de la fenêtre de dessin (display),
  - modification de la taille de la fenêtre de dessin (reshape).
Les événements suivants sont gérés a minima par des échos écran en texte dans la console d'exécution de façon à permettre la trace du fonctionnement du programme :
  - frappe d'une touche alphanumérique du clavier (keyboard),
  - frappe d'une touche non-alphanumérique du clavier (special),
  - clic souris dans la fenêtre de dessin (mouse),
  - déplacement de la souris bouton appuyé dans la fenêtre de dessin (mouseMotion).
Le code de gestion des événements suivants est programmé pour une gestion a minima par affichages écran texte dans la console, mais ces événements ne sont pas activés (lignes laissées en commentaire) dans la fonction main :
  - aucun événement n'est en attente (idle),
  - déplacement de la souris bouton non appuyé devant la fenêtre de dessin (passiveMouseMotion).

   a) Télécharger et remplacer le fichier Exemple.cpp par le fichier GLUtMinimum.cpp dans le projet VisualStudio.

Le fichier GLUt-3-spec.pdf contient la documentation de référence de GLUt. Il pourra vous aider à implanter les réponses aux questions b) à f).
Précision : La programmation GLUt ne peut pas être réalisée sans utiliser des variables globales. Celles-ci permettent le partage d'informations entre les différentes fonctions implantées pour être exécutées en réponse aux événements. De façon à ne pas aller contre le fonctionnement événementiel de GLUt mais plutôt à s'inscrire dans son cadre, on évitera de placer des instructions OpenGL dans toutes les fonctions événementielles et on limitera un tel placement aux seules fonctions display (rafraichissement de la fenêtre de dessin) et reshape (changement de la taille de la fenêtre de dessin). Au lancement, GLUt exécute la fonction reshape, puis la fonction display et se met ensuite en attente d'événements. Il est naturel que ces deux fonctions aient à contenir de l'OpenGL car la fonction reshape devra configurer la caméra virtuelle de visualisation OpenGL et la fonction display devra modéliser la scène. Les événements peuvent arriver à n'importe quel instant et être de n'importe quel type lorsqu'ils arrivent y compris des reshape et des display. Placer des instructions OpenGL dans d'autres fonctions que reshape et display n'est pas interdit mais présenterait pour inconvénient de générer un flux OpenGL non déterministe, nous allons donc éviter de le faire.
Notre méthode de programmation consistera à utiliser des variables globales qui seront utilisées dans les fonctions reshape et display (principalement dans display) pour paramétrer la modélisation et ses paramètres et qui seront modifiées dans les autres fonctions événementielles. Opérant ainsi, le flux d'exécution des fonctions événementielles qui aurait par exemple été :
RDKDISRDMMMMKKDRDIDIDIDIKD
se réduira au flux :
RDDRDDRDDDDD
pour les seules fonctions qui contiennent de l'OpenGL à savoir reshape et display. Ce qui est plus facilement contrôlable quand il s'agit d'obtenir la cohérence d'exécution OpenGL.

   b) Implanter un contrôle clavier permettant de switcher entre les modes d'affichage plein et fil de fer en utilisant la touche de clavier Espace. Il convient de modifier la fonction keyboard du fichier source et d'utiliser la fonction OpenGL glPolygonMode pour le paramétrage du mode d'affichage dans la fonction display.

   c) Implanter une animation telle que le tore tourne sur lui-même autour de l'axe Ox à raison de 1° de rotation entre chaque image.
Il convient d'adapter la fonction idle et de programmer son exécution en tâche de fond dans la fonction main. La fonction OpenGL glRotatef sera utilisée dans la fonction display juste avant l'appel à la fonction scène pour réaliser la rotation de celle-ci. Appeler soi-même la fonction display ou, encore pire, programmer une boucle explicite autour d'un appel à la fonction display est totalement proscrit car cela contrecarrerait le fonctionnement événementiel. Dans la fonction idle on utilisera la fonction GLUt glutPostRedisplay pour poster un événement redisplay, entrainant ainsi l'exécution de la fonction display par GLUt sitôt que ce sera possible, obtenant ainsi un flux d'exécution événementiel qui sera IDIDIDIDIDIDIDID et dont il résultera une animation.

   d) Implanter un contrôle clavier permettant d'activer/désactiver l'animation au moyen de la touche Entrée. On s'inspirera de la méthode utilisée dans Exemple.cpp.

   e) Implanter un contrôle clavier permettant de faire tourner interactivement le tore sur lui-même autour de l'axe Oy dans un sens ou dans l'autre en utilisant les touches Flèche gauche et Flèche droite. Il convient d'adapter la fonction special.

   f) Implanter un contrôle permettant de faire tourner le tore sur lui-même autour de l'axe Oz en réaction aux mouvements horizontaux de la souris bouton appuyé à raison de 1° de rotation par pixel de déplacement. Il convient d'adapter les fonctions mouse et mouseMotion.

Solutions

 

GLUT

Fonctionnalités principales de GLUt :
 - création de fenêtres
 - gestion des événements :
   - fenêtre
   - clavier
   - souris

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 à celles des objets qu'ils remplacent.

Exercice n°3 (supplémentaire)

(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

TD n°2 : Modélisation par facettes

Exercice n°1

Modéliser par facettes une facette carrée percée d'un trou carré.
Cette facette est plongée dans le plan xOy, centrée sur l'origine du repère de modélisation, de cotés parallèles aux axes x et y et de cotés de longueur 2.0.
Le trou est carré, centré sur l'origine du repère de modélisation, de sommets placés aux positions (0.5,0.0,0.0), (0.0,0.5,0.0), (-0.5,0.0,0.0) et (0.0,-0.5,0.0).

Exercice n°2

(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°3 (supplémentaire)

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);

Question supplémentaire : 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

Facette carrée trouée d'un trou carré

Cubes et cylindres par facettes

TP n°3 : Modélisation géométrique à base de facettes et d'objets canoniques

Exercice n°1

Implanter et valider la fonction de modélisation d'une facette trouée d'un trou carré de l'exercice 1 du TD n°2.

Exercice n°2

Implanter et valider la fonction de modélisation d'un cube de l'exercice 2 du TD n°2.
Vérifier que le résultat obtenu est géométriquement identique au résultat obtenu en utilisant la fonction glutSolidCube de la librairie GLUt.

Exercice n°3

Lors du TD n°2, une étape importante de la modélisation géométrique a été laissée de coté : la modélisation des normales. En effet, c'est à partir des normales aux sommets d'une primitive graphique qu'OpenGL réalise les calculs d'éclairage lorsque le mode GL_LIGHTING est activé. Si on souhaite pouvoir éclairer les objets, la spécification des normales est obligatoire car OpenGL ne les calcule pas seul. Il existe dans OpenGL une variable d'environnement qui définit la valeur de normale qui sera affectée automatiquement à tout sommet créé. La fonction glNormal* permet de configurer la valeur de cette variable d'environnement.
Ajouter la modélisation des normales à la fonction de modélisation de cube de l'exercice n°2.

Solutions

 

GLUT

Facette carrée trouée d'un trou carré

Cubes et cylindres par facettes

TD n°3 : Paramètrage numérique d'une caméra OpenGL

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 sphérique de rayon 10.0.
Quelle ouverture doit-on donner à cette caméra pour visualiser cette scène en gros plan dans une fenêtre d'affichage carrée (viewport carré) ?
Définir le paramétrage numérique de la fonction OpenGL utilisée pour réaliser cette visualisation: glOrtho.

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 sphérique de rayon 10.0.
Quelle ouverture doit-on donner à cette caméra pour visualiser cette scène en gros plan dans une fenêtre d'affichage carrée (viewport carré) ?
Définir le paramétrage numérique de la fonction OpenGL utilisée pour réaliser cette visualisation: gluPerspective.

c) Dans le cadre d'une implantation OpenGL, décrire une solution permettant de s'assurer que l'intégralité de la scène sera visualisée quel que soit le ratio résolution horizontale sur résolution verticale adopté par le viewport d'affichage.

Solutions

 

GLUT

Ouverture d'une caméra orthographique

Ouverture d'une caméra en perspective

TP n°4 : Paramètrage numérique d'une caméra OpenGL

Le fichier code source ParametrageCamera.cpp contient un programme C+OpenGL complet réalisant la modélisation géométrique d'une scène et organisant incomplètement son affichage écran. Cette scène est constituée de 64 cubes de coté 0.5 placés en 4 plans de 4x4 cubes de façon à occuper un volume cubique de coté 6.5 centré sur le point de coordonnées (0.0,0.0,-100.0). Les cubes sont colorés en fonction de leur position dans la scène (de plus en plus rouge de gauche à droite, de plus en plus vert de bas en haut, de plus en plus bleu de l'arrière vers l'avant). L'affichage est incomplètement implanté avec pour conséquence que l'exécution est possible, mais que la scène n'est pas visible.
Télécharger et compiler ce fichier. Vérifier la bonne exécution de l'exécutable ainsi obtenu. Une fenêtre uniformément grise devrait être affichée.

a) Modifier la fonction reshape en décommentant la ligne glOrtho et en paramétrant cet appel de fonction pour visualiser la scène au moyen d'une caméra réalisant une projection parallèle orthographique, placée en position 0.0 et orientée selon l'axe -z.
Rappel : La caméra de visualisation en projection parallèle orthographique d'OpenGL est placée à l'origine et est orientée selon l'axe -z.

b) Modifier la fonction reshape en recommentant la ligne glOrtho, en décommentant la ligne gluPerspective et en paramétrant cet appel de fonction pour visualiser la scène au moyen d'une caméra réalisant une projection en perspective, placée en position 0.0 et orientée selon l'axe -z.
Rappel : La caméra de visualisation en projection en perspective d'OpenGL est placée à l'origine et est orientée selon l'axe -z.

c) On souhaite maintenant donner l'illusion que la caméra de visualisation en perspective n'est plus placée à l'origine, mais en position (0.0,0.0,-50.0) c'est à dire environ deux fois plus proche de la scène qu'initialement.
Décommenter la ligne d'appel à la fonction gluLookAt placée dans la fonction display et paramétrer cet appel pour réaliser cette configuration.
Attention : Il pourra être nécessaire d'ajuster les paramètres d'appel de la fonction gluPerspective pour que la visualisation soit correctement réalisée.
On se référera à la description de la fonction gluLookAt réalisée dans le chapitre de cours sur OpenGL pour les renseignements d'utilisation.

d) Déplacer de nouveau la caméra vers les positions (0.0,0.0,-90.0), (0.0,0.0,-95.0), (-5.0,-5.0,-95.0), (-10.0,-15.0,-90.0), (-10.0,-15.0,-120.0).

e) Implanter des contrôles clavier permettant de faire varier la position de la caméra au moyen des touches right et left pour les déplacements en x, up et down pour les déplacements en y, et page up et page down pour les déplacements en z.

Solutions

 

GLUT

Paramétrages d'une caméra OpenGL

TP n°5 : Paramètrage numérique d'un matériel et de lumières

Le fichier code source ParametrageMaterielEtLumieres.cpp contient un programme C+OpenGL complet réalisant la modélisation géométrique d'une scène et organisant incomplètement son affichage écran. Cette scène est constituée d'ellispoïdes organisés pour matérialiser les arêtes et les sommets d'un cube. L'affichage est incomplètement implanté avec pour conséquence que l'exécution est possible, mais que la scène n'est pas correctement éclairée.
Télécharger et compiler ce fichier. Vérifier la bonne exécution de l'exécutable ainsi obtenu.

a) Ajouter un contrôle clavier à ce programme permettant d'activer/désactiver la gestion de l'éclairage au moyen de la touche "Entrée".

b) Ajouter les contrôles claviers permettant d'activer/désactiver individuellement les 4 ptemières lumières d'OpenGL (lumières 0 à 3) au moyen des touches de fonction F1, F2, F3 et F4 (touches spéciales).

c) Configurer la lumière 1 selon les caractéristiques suivantes :
  - Lumière ponctuelle placée en position (2.0,2.0,2.0)
  - Emission diffuse rouge
  - Pas d'émission spéculaire
  - Pas d'émission ambiante

d) Configurer la lumière 2 selon les caractéristiques suivantes :
  - Lumière directionnelle de direction d'incidence (-2.0,0.0,4.0)
  - Emission diffuse verte
  - Emission spéculaire blanche
  - Pas d'émission ambiante

e) Configurer la lumière 3 selon les caractéristiques suivantes:
  - Spot placé en position (-3.0,-3.0, 15.0) et de direction d'éclairage (3.0, 3.0,-10.0)
  - Spot d'ouverture globale égale à 40°
  - Emission diffuse bleue
  - Emission spéculaire jaune
  - Pas d'émission ambiante

f) Configurer la lumière 4 selon les caractéristiques suivantes:
  - Lumière ponctuelle placée en position (0.0,0.0,0.0)
  - Pas d'émission diffuse
  - Pas d'émission spéculaire
  - Emission ambiante magenta

g) On aura remarqué que les émissions spéculaires des questions (d) et (e) semblent ne pas produire de résultat à l'écran. Ceci s'explique par le fait que le matériel par défaut d'OpenGL ne génère pas de réponse à ce type d'éclairage.
Configurer le matériel pour qu'il génère une réponse spéculaire blanche avec une réflectivité de 64.0 (valeur intermédiaire entre les valeurs générant les réponses maximales et minimales : 0.0 et 128.0). On utilisera la touche de fonction F5 pour permettre de switcher entre les valeurs par défaut et les valeurs indiquées ci-avant.

h) Implanter les contrôles clavier permettant de modifier les valeurs de réflexion diffuse, réflexion ambiante et émission du matériel au moyen des touches de fonction F6, F7 et F8 selon les modalités suivantes :
 - F6 permettra de switcher entre les valeurs par défaut et le magenta en diffus.
 - F7 permettra de switcher entre les valeurs par défaut et le cyan en ambiant.
 - F8 permettra de switcher entre les valeurs par défaut et le jaune en emission.

Solutions

 

GLUT

Paramétrages du matériel et des lumières

TD n°4 : Principes du plaçage de texture et application en OpenGL

Explication du fonctionnement du programme TD-PlacageTexture.cpp qui permet de placer une texture sur un rectangle.

TP n°6 : Plaçage de texture

OpenGL n'inclut pas de fonction permettant de réaliser l'importation d'une image depuis un fichier.

a) Télécharger l'archive ChargementImagePNG.zip. Cette archive contient les fichiers de code source nécessaires à la compilation d'une librairie contenant des fonctions d'importation et d'exportation d'images au format PNG 24 bits. L'utilisation de la fonction d'importation est montrée dans la fonction main du fichier ChargementImagePNG.cpp qui tente de charger une image. Si le chargement échoue, un message d'indique. Si le chargement aboutit, un message l'indique et la résolution de l'image est affichée. Ce programme n'affiche pas l'image. Il se contente de la télécharger en mémoire.
Extraire l'archive, intégrer les fichiers de code source qu'elle contient dans un projet de développement (Visual Studio ou autre), vérifier la bonne compilation et la bonne exécution du programme.

b) Récupérer le fichier de code source TD-PlacageTexture.cpp du TD n°4. Intégrer le code source de la fonction main du fichier ChargementImagePNG.cpp dans le fichier TD-PlacageTexture.cpp. Vérifier la compilation et l'exécution.

c) Remplacer l'image générée algorithmiquement dans le fichier TD-PlacageTexture.cpp par une image obtenue par téléchargement d'un fichier image PNG 24 bits.

d) Reprendre et adapter la fonction de modélisation de cube développée au TP n°3 pour qu'elle permette le placement d'une texture sur chacune des 6 faces d'un cube.
Cette fonction intégrera donc la modélisation des sommets, des normales et des coordonnées de texturage.

e) Adapter une seconde fois la fonction de modélisation de cube de façon qu'elle réalise le placement de textures différentes sur les 6 faces du cube.
On pourra utiliser les images suivantes : Emojis.zip.

Solutions

 

GLUT

Placage d'une texture sur un cube

Placage de 6 textures sur un cube

Chargement préalable
et placage de 6 textures sur un cube

Examen de TD n°1

Sujet

 
 
Objets à modéliser

Solutions

 

GLUT

Une marche d'escalier en colimaçon
et un escalier construit avec

TP n°7 : Animation

Le programme Animation.cpp modélise deux scènes. Les touches 'o' et 'O' permettent de switcher entre chacune des deux. Ces deux scènes modélisent des tunnels schématisés par une suite de tores. Les tunnels sont placés dans le plan xOz. Les tores qui les schématisent ont pour rayons 2.0 pour le tore lui-même et 0.1 pour le tube du tore. Les scènes sont centrées sur le repère de modélisation.
Dans la première scène le tunnel est formé de 4 portions rectilignes interconnectées par des coudes. Les portions rectilignes ont pour longueur 10.0 et forment un carré sans ses sommets. Les coudes ont pour rayon 5.0 (distance centre du coude/axe du tunnel).
Dans la seconde scène le tunnel schématise un "oméga" formé de deux porties circulaires de rayon 8.0 (distance centre/axe du tunnel) venant s'interpénétrer au niveau de l'origine du repère de modélisation.
En plus des tores, les 2 scénes incluent (en vert) la modélisation de l'axe du tunnel. Il est modélisé au moyen de cylindres et de portions de tores.

a) Importer le fichier Animation.cpp, l'intégrer à un projet de développement, le compiler et l'exécuter.

b) Implanter une animation dans chacune des deux scènes :
  - Scéne 1 : Une sphére de rayon 1.2 se déplace dans le tunnel.
  - Scéne 2 : Une sphére de rayon 1.2 se déplace dans le tunnel en passant tantôt dans la partie circulaire gauche tantôt dans la partie circulaire droite.
Vous pouvez choisir vous-même la vitesse de déplacement pour les 2 scènes.

 

c) La scène est maintenant immobile et on souhaite que l'animation porte sur la caméra. Celle-ci est donc en déplacement. Elle suivra la trajectoire définie par l'axe du tunnel dont il convient de désactiver l'affichage pour éviter que la caméra soit placée à l'intérieur de l'axe du tunnel. La caméra sera orientée selon la direction tangente à la courbe définie par l'axe de déplacement.

 

d) Au lieu d'utiliser glutIdleFunc, utiliser glutTimerFunc pour tester l'implantation d'un déplacement à vitesse constante quel que soit l'ordinateur utilisé pour l'exécution.

Solutions

 

GLUT

Animation de scène et animation de caméra

Animation avec glutTimerFunc

TD n°5 : Mathématiques

Coordonnées homogènes, test de planarité, transformations géométriques

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 coordonnées homogenes 3D nommée CH3D.

b) Dériver de la classe CH3D une classe position 3D nommée Pos3D utilisable pour le stockage de positions dans un espace à trois dimensions.

c) Dériver de la classe CH3D une classe direction 3D nommée Dir3D utilisable pour le stockage de directions dans un espace à trois dimensions.

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

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

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

g) Tester les classes ci-dessus sur les données ci-dessous.

Exercice n°3

a) Développer en C++ une classe transformation géométrique 3D en coordonnées homogènes. Cette classe sera nommée TG3D.

b) Dériver de la classe TG3D une classe translation 3D pour le stockage d'opérateurs de type translation de vecteur (tx, ty, tz). Cette classe sera nommée Tr3D.

c) Dériver de la classe TG3D 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. Cette classe sera nommée Rt3D.

d) Implanter une méthode de transformation d'une position 3D ou d'une direction 3D par une translation 3D ou une rotation 3D (voir l'exercice n°2 pour les classes Pos3D et Dir3D).

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

f) Tester les classes ci-dessus sur les données ci-dessous.

Solutions

 

CMD

Coordonnées homogènes et test de planarité

Transformations géométriques 3D

TP n°8 : Mathématique de l'Infographie

Implanter et valider les classes dont le développement a été amorcé au cours du TD n°5.

Solutions

 

CMD

Coordonnées homogènes et transformations géométriques

TP n°9 : Projet

TP n°10 : Projet

De façon à faciliter le développement du projet, réaliser le test des deux fichiers sources suivants:
  - DeuxFenetres.cpp
  - TestMemoire.cpp

Le fichier DeuxFenetres.cpp illustre la possibilité offerte par GLUt de gérer plusieurs fenêtres d'affichage OpenGL. La fonction int glutCreateWindow(void) permet de créer les fenêtres. Elle retourne un handle entier à mémoriser permettant de garder une référence sur chaque fenêtre ouverte. Les fenêtres sont individuellement munies de leurs fonctions display, reshape, keyboard, special, mouse, ... qui permettent de gérer leur fonctionnement événementiel. Attention, les fenêtres partagent une et une seule fonction idle. Chaque fenêtre peut recevoir en propre un ordre de rafraichissement en utilisant la fonction void glutPostWindowRedisplay(int f) où f est le handle de la fenêtre à rafraîchir. Dans chaque fenêtre est géré un environnement OpenGL complet pouvant/devant être intégralement paramétré : lumières, matériaux, textures, caméra, options d'affichage, ...

Le fichier TestMemoire.cpp montre une technique spécifique à VisualStudio permettant de contrôler les opérations de gestion dynamique de la mémoire : new, delete, calloc, malloc, free,... Le but de cette technique est de faciliter la détection des problèmes souvent constatés quant à la gestion dynamique de la mémoire : free ou delete dupliqué, pas de free pour un alloc, pas de delete pour un new, ... Il s'agit d'un équivalent à valgrind. Attention, les bibliothèques de compatibilté mfc doivent être installées (option non activée par défaut au moment de l'installation de VisualStudio) pour que TestMemoire.cpp puisse être compilé et donc exécuté.
Pour que le contrôle soit réalisé, il est nécessaire que la compilation soit réalisée en mode "Debug" et que l'exécution soit lancée sous debugger. Les directives de compilation incluses dans le code source font que la compilation et l'exécution sont possibles sans problème en mode release ou bien si un autre compilateur que VisualStudio est utilisé. Le code est instrumenté au début avec un certain nombre de #include et dans la fonction main avec les lignes suivantes :
#if defined(WIN32) || defined(WIN64)
  #if defined(_DEBUG)
    _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
    _crtBreakAlloc = 120;
  #endif
#endif

qui configurent l'outil d'analyse
(1) pour qu'à la fin d'exécution du programme sous debugger un rapport de l'utilisation dynamique de la mémoire soit établi et affiché dans la fenêtre "Sortie" de Visual Studio,
(2) pour qu'un point d'arrêt pour le debugger soit placé lors de la 120ème opération d'allocation dynamique de mémoire (new, malloc, calloc, ...).
Si on ne souhaite pas qu'un point d'arrêt soit réalisé, on pourra placer la ligne en commentaire.
La fenêtre de VisualStudio nommée "Pile des appels" permet de savoir où le point d'arrêt a été déclenché par le debugger.

a) Corriger le problème mémoire existant dans TestMemoire.cpp.

b) Ajouter l'ouverture d'une troisième fenêtre au programme DeuxFenetres.cpp permettant de visualiser la scène depuis un 3ème point de vue (au choix).

Solutions

 

GLUT

Trois fenêtres

Gestion dynamique de la mémoire

Examen de TD n°2

TP n°11 : Projet

TP n°12 : Projet

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