Sujets et Corrections |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
TP n°1 : Premières implantations OpenGL Exercice n°1
Télécharger le fichier archive IG-2019-2020.zip. Ce fichier archive contient une "solution" Visual Studio
2015.
La solution comprend un seul projet nommé Exemple. Ce projet référence un seul fichier source Exemple.cpp et est configuré pour une compilation utilisant
OpenGL: 1) Extraire l'archive IG-2019-2020.zip. Lancer Visual Studio 2015 et charger la solution. Vérifier la compilation et l'exécution du projet Exemple. 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 à OpenGL 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. 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.
Les événements suivants sont gérés "normalement" avec exécution de code OpenGL: 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 suivantes. 2) Télécharger et remplacer le fichier Exemple.cpp par le fichier GLUtMinimum.cpp dans le projet VisualStudio. Précision liminaire : La programmation GLUt ne peut être réalisée sans utiliser des variables globales. Celles-ci permettent le partage d'informations entre les différentes fonctions implantée pour être exécutées en réponse aux événements. a) 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 et d'utiliser la fonction glPolygonMode. b) 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'adpater la fonction idle et de programmer son exécution en tâche de fond. La fonction glRotatef est utilisée dans la fonction display pour réaliser la rotation. c) 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. d) Implanter un contrôle clavier permettant de faire tourner 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". e) 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 à raison de 1° de rotation par pixel de déplacement. Il convient d'adapter les fonctions mouse et mouseMotion.
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: (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:
Exercice n°2
(1) Programmer la scène OpenGL modélisant un bras robot simplifié composé d'un bras et d'un avant-bras.
(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.
(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).
Solutions
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 centré 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 1.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.
(2) Modifier la modélisation de la question précédente pour ajouter la gestion des normales.
Exercice n°3 (supplémentaire)
Modéliser par facettes un cylindre selon les caractéristiques suivantes:
Question supplémentaire: Ajouter un découpage latéral (selon l'axe y) pour une valeur nl.
Solutions TP n°3 : Modélisation par facettes et modélisation par objets géométriques Exercice n°1 Implanter la fonction de modélisation par facettes d'un cube vue au TD n°1-2. Exercice n°2 Implanter la scéne constituée de 4 cubes à faces orientées vers l'origine vue au TD n°1-2. Implanter la scéne constituée d'un bras robot simplifié vue au TD n°1-2. On munira le programme de contrôles clavier permettant de faire varier les angles r1 et r2. Exercice n°3 Récupérer la fonction de modélisation de cylindre par facettes proposées lors du TD n°1-2 et transformer les parallélipipèdes du bras robot par des cylindres. Munir d'une pince le bras robot (modélisation libre, exemple ci-dessous).
Modélisation d'une pince au bout du bras robot :
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 sphérique de rayon 10.0.
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. 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
TP n°4 : Caméras virtuelles
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 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 l'origine du repère de modélisation. 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 réalisé en projection parallèle orthographique de façon à ce que l'intégralité de la zone d'affichage
de la fenêtre soit utilisée pour le viewport OpenGL. On rappelle que la direction de visualisation est la direction -z.
a) Lorsque la fenêtre de visualisation est modifiée par l'utilisateur pour adopter une résolution en x différente de la résolution en y, les objets affichés sont déformés.
Résoudre ce problème de façon que cette déformation disparaisse et que la scène reste intégralement visible quel que soit le ratio résolution en x / résolution en y.
b) Modifier le code source pour que l'affichage ne soit plus réalisé en projection parallèle orthographique mais en projection en perspective.
On placera la caméra virtuelle en position (0.0,0.0,100.0). On l'orientera de façon qu'elle regarde l'origine du repère de modélisation
(sur laquelle la scène est centrée). On choisira la direction y comme direction de la verticale.
c) Modifier une nouvelle fois le code source pour que la caméra virtuelle soit maintenant placée en position (0.0,0.0,10.0).
d) Modifier une dernière fois le code source pour qu'il soit possible de contrôler la position de la caméra en utilisant le clavier:
Question supplémentaire: On a placé l'appel à gluLookAt entre les appels aux fonctions glLightfv et scene. Déplacer l'appel à gluLookAt juste avant l'appel à glLightfv et tester le programme ainsi obtenu. La scène affichée est géométriquement identique mais les couleurs issus des calculs d'éclairage sont différents. Pourquoi?
Solutions
TP n°5 : Lumières et matériaux
Le fichier source LumieresEtMaterielBase.cpp implante un programme d'affichage OpenGL
dans lequel, à l'exception d'une, toutes les instructions spécifiques à la gestion des matériaux et des lumières ont été omises. L'instruction
conservée se trouve dans la fonction init. Elle a pour but de supprimer (configurer à noir) la lumière ambiante existant par défaut au sein d'OpenGL
(configurée par défaut à (0.2,0.2,0.2,1.0)) en plus des lumières classiques (GL_LIGHT0 à GL_LIGHT7). A noter : Dans la fonction display, les fonctions OpenGL glPushAttrib et glPopAttrib sont utilisées pour sauvegarder dans une pile ad hoc et restaurer de façon rapide l'intégralité de la configuration des lumières et du matériel. Le paramètre de glPushAttrib dédié à cette sauvegarde est GL_LIGHTING_BIT.
Le but du TP consiste à placer les instructions de configuration des calculs d'illumination dans le respect des questions posées. a) Activer l'utilisation des calculs d'éclairage.
b) Activer et configurer la lumière 0 selon les caractéristiques suivantes:
c) Désactiver la lumière 0. Activer et configurer la lumière 1 selon les caractéristiques suivantes:
d) Désactiver la lumière 1. Activer et configurer la lumière 2 selon les caractéristiques suivantes:
e) Activer simultanément les lumières 0, 1 et 2.
f) On aura remarqué que les émissions spéculaires des questions (c) et (d) 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.
g) Modifier le matériel des tores selon les caractéristiques suivantes:
Questions optionnelles
1) Tester la possibilité offerte par OpenGL de créer des lumières ponctuelle ou spot intégrant une atténuation de l'éclairage fonction de la
distance entre la lumière et le point qu'elle éclaire : atténuation linéaire, atténuation quadratique. 2) Réaliser une animation où les lumières tournent autour de l'origine et la scène reste immobile. 3) Tester l'influence du nombre de facettes de modélisation sur les éclairages et la vitesse d'animation.
4) Tester l'utilisation de valeurs supérieures à 1.0 pour les coefficients des "couleurs" pour les lumières et les matériels. Solutions
TP n°6 : Plaçage de texture L'archive zip ChargementImagePNG.zip contient les fichiers "code source" d'une librairie de gestion de fichiers "image" au format png accompagnés d'un exemple d'utilisation sous la forme d'une fonction main tentant deux chargements d'image successifs : Inconnu.png (qui n'existe pas) et Emojis.png (qui existe).
Plus précisément, une fonction d'importation et une fonction d'exportation sont décrites dans le fichier
ChargePngFile.h.
a) Télécharger et désarchiver ce fichier zip. b) Développer un programme OpenGL permettant d'afficher une scéne composée d'un rectangle de coté 7.5 x 5.0. On pourra utiliser comme base le code développé au cours du TP n°4.
c) Modifier le code source de la question (b) pour que le rectangle soit muni d'une texture le recouvrant entièrement utilisant l'image contenue dans le fichier Emojis.png.
d) Reprendre la fonction de modélisation de cylindre de l'exercice n°2 du TD n°3 pour y ajouter les instructions permettant de le recouvrir d'une texture. Dans le programme de la question (c), remplacer le rectangle par un cylindre de hauteur 5.0 et de rayon 2.5.
Solutions
Utiliser plusieurs textures
Les programmes ci-dessous montrent l'utilisation de plusieurs textures pour dessiner un cube où chacune des 6 faces est texturée au moyen d'une
image différente de celles des 5 autres faces.
TD n°5 : 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 coordonnees 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.
Solutions
TP n°7 : Lancement du projet Description du travail à réaliser
De façon à faciliter le développement du projet, réaliser le test des deux fichiers sources suivants: 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é. 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
TD n°6 : Transformations géométriques en coordonnées homogènes Exercice n°1 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 TD n°5 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. Solutions
TP n°8 : Coordonnées homogènes et transformations géométriques Exercice n°1 Télécharger le fichier zip suivant Mathematiques2.zip (il s'agit de la solution du TD n°6), extraire les fichiers qu'il contient, les compiler et vérifier la bonne exécution du résultat obtenu. Exercice n°2
a) On ne dispose plus des opérateur OpenGL glTranslate, glRotate et glScale (c'est le cas par exemple en OpenGL ES ou en OpenGL standard lorsque
l'on développe des VertexShaders). A partir des classes de l'exercice n°1, développer une fonction permettant de composer dans cet ordre
une translation, une rotation et un zoom de façon à obtenir une transformation géométrique représentative de la suite de transformations que l'on
réalise sur le repère courant lorsque l'on doit placer, orienter et dimensionner un objet canonique (ou non) modélisé géométriquement.
b) Utiliser la fonction de la question (a) pour développer un programme OpenGL dans lequel est modélisé un cube représenté en fil de fer placé, orienté
et dimensionné. On développera une fonction void modeliseCubeEnFilDeFer(TG3D *tg) qui modélisera le cube de coté 1.0 centré sur l'origine après
transformation par la TG3D tg.
On pourra s'aider des déclarations suivantes :
Pos3D pCube[8] = { Pos3D( 0.5F, 0.5F, 0.5F), Pos3D(-0.5F, 0.5F, 0.5F),
Le tableau pCube contient les coordonnées des 8 sommets d'un cube de coté 1.0 centré sur l'origine. Le tableau iCube contient les couples
d'indices des douze arête d'un cube, ces indices référant à des positions dans le tableau pCube. c) Reprendre le développement réalisé aux (a) et (b) pour développer une classe TRZ3D dérivant de TG3D permettant d'assurer le même traitement. Solutions
TP n°9 : Courbes lissées
On considère la liste de positions trois dimensions suivante : a) Réaliser un programme permettant d'afficher la ligne polygonale formée par ces 37 sommets.
Si vous le souhaitez, vous pouvez vous aider du code source suivant BSplineEtBezierBase.cpp qui implante toute la partie OpenGL du code nécessaire, la déclaration des 37 points ci-dessus, mais où la fonction scene() se limite à afficher le segment de droite qui va du point d'indice 0 au point d'indice 36 c'est à dire le segment qui correspond au trou dans les images ci-dessus. Notre but est maintenant de superposer cette ligne polygonale et une courbe lissée obtenue en l'utilisant comme liste de points de contrôle.
b) Développer une fonction permettant de modéliser une courbe de Bézier. Cette fonction pourrait avoir comme prototype
On notera le peu d'attractivité de la ligne polygonale sur la courbe de Bézier. On notera aussi que les points de la courbe de Bézier ne sont pas uniformément répartis sur la courbe même si on fait varier t uniformément. En effet, ils sont plus resserrés là où les points de contrôle sont plus resserrés.
c) Développer une fonction permettant de trouver la position d'un point de lissage, pour une valeur t donnée, sur une courbe B-Spline définie
par 4 points de contrôle et une matrice de base donnée.
d) Utiliser la fonction développée à la question (c) pour développer une fonction permettant de modéliser une courbe B-Spline. Cette fonction pourrait
avoir comme prototype
Solutions
TP n°10 : Remplissage d'un triangle 2D a) Télécharger le programme source RemplissageTriangle2DBase.cpp. Compiler et exécuter le.
Ce programme implante l'affichage d'un quadrillage 2D destiné à représenter un écran bitmap. La taille des pixels virtuels est de 16x16
pixels réels. La fonction permettant d'afficher le quadrillage est la fonction void quadrillage(void);.
Outre la fonction fond, ce programme comprend une fonction void pixel(int
x,int y); qui permet le dessin d'un pixel aux coordonnées (x,y) passées en paramètres. Cette fonction est utilisée 3 fois pour
dessiner 3 pixels de couleur respectives rouge, verte et jaune. Les coordonnées à fournir à cette fonction sont considérées dans le cadre du repère
virtuel associé au quadrillage et sont comptées en valeurs entières en cellules du quadrillage. La cellule de coordonnées (0,0) est située tout en
bas, tout à gauche. L'axe des x est orienté vers la droite. L'axe des y est orienté vers le haut. Si la fenêtre d'affichage est agrandie,
le quadrillage est agrandi d'autant sans subir de zoom ou de déformation.
b) Modifier le programme de la question (a) pour y intégrer une fonction de dessin d'un segment de droite par algorithme de Bresenham et la tester
sur le tracé des segments de droite (15,2)-(4,19) et (2,5)-(17,15). Le prototype de cette fonction sera
c) Modifier le programme de la question (a) pour y intégrer une fonction de rasterisation d'un triangle défini par 3 sommets et la tester sur
les triangles (15,2)-(2,4)-(19,14) et (1,6)-(18,16)-(4,19). Le protoype de cette fonction sera
Indications de développement Le principe de la méthode de rasterisation consiste à tracer les unes après les autres les trames horizontales de pixels recouvrant le triangle. Le parcours est réalisé de la trame inférieure correspondant à la valeur minimale des y des 3 sommets du triangle jusqu'à la trame supérieure correspondant à la valeur maximale des y des 3 sommets du triangle. Par simplification, on va considérer que le sommet P1 dont les coordonnées (x1,y1) sont transmises en premiers paramètres est le sommet dont la coordonnée y possède la valeur minimale parmi y1, y2 et y3 et que le sommet P3 dont les coordonnées (x3,y3) sont transmises en derniers paramètres est le sommet dont la coordonnée y possède la valeur maximale parmi y1, y2 et y3. P2 de coordonnées (x2,y2) est donc le sommet intermédiaire en y. Dit autrement, on peut considérer que la propriété y1 <= y2 <= y3 est vérifiée de manière certaine. Méthode 1 pour la détermination des trames horizontales
Tracer une trame horizontale de pixels nécessite de connaître l'abscisse xg du pixel le plus à gauche et l'abscisse xd du pixel le plus à
droite sur cette trame. Une simple itération de xg à xd inclus permettra le tracé de la trame. Le problème de détermination des valeurs xg et xd
sur chaque trame d'ordonnée y peut être vu comme un problème de parcours des bords gauche et droit du triangle. La détermination de ces bords
est donc nécessaire. On sait que le coté P1‑P3 est le coté qui va du sommet le plus bas au sommet le plus haut et que donc il constituera à
lui seul soit le bord droit soit le bord gauche. Le sommet P2 est situé soit à droite soit à gauche de la droite P1‑P3. S'il est à gauche,
le bord gauche est constitué des deux cotés P1‑P2 et P2‑P3 et le bord droit du seul coté P1‑P3. S'il est à droite, le bord
droit est constitué des deux cotés P1‑P2 et P2‑P3 et le bord gauche du seul coté P1‑P3. Le problème est donc de déterminer de quel
coté de la droite P1‑P3 est placé le sommet P2. Indice : produit vectoriel. Méthode 2 pour la détermination des trames horizontales Tracer une trame horizontale de pixels nécessite de connaître les abscisses xmin et xmax des pixels initiaux et finaux de cette trame. Une fois ces valeurs connues, une simple itération de xmin à xmax inclus permettra le tracé de la trame. Le problème de détermination des valeurs xmin et xmax sur chaque trame d'ordonnée y peut être vu comme un problème de rasterisation des cotés du triangle. Cette rasterisation n'a pas pour but direct le tracé, mais la détermination de xmin et xmax pour chaque y à partir des pixels déterminés par rastérisation sur le principe qu'aucun pixel du triangle ne saurait être extérieur au triangle et donc extérieur par rapport à ses cotés. On utilisera ici un algorithme directement issu de l'algorithme de Bresenham. Conseil : Quoi que peu optimal du point de vue des temps de calcul (encore que), le développement gagne beaucoup en simplicité et en lisibilité si on utilise des tableaux d'entiers xmin[y] et xmax[y] remplis par une fonction de rasterisation des cotés qui sera appelée 3 fois, c'est à dire une fois sur P1‑P2 sur xmin et sur xmax, une fois sur P2‑P3 sur xmin et sur xmax et une fois sur P1‑P3 sur xmin et sur xmax. Une fois ces tableaux remplis, le dessin effectif peut être réalisé. Solutions
TP n°11 : Lancer de rayons : Calcul des directions de réflexion et transmission
Parmi l'ensemble des problèmes devant être résolus pour l'implantation de l'algorithme de lancer de rayons, on trouve le calcul des rayons
réfléchis spéculairement et transmis lors d'un changement de milieu subi par un rayon. Ce TP porte sur l'implantation de ces calculs. Les
formules mathématiques peuvent être trouvées dans le cours sur le lancer de rayons.
a) Concevoir une méthode de la classe Dir3D permettant de calculer la direction d'un rayon réfléchi spéculairement.
b) Concevoir une méthode de la classe Dir3D permettant de calculer la direction d'un rayon transmis à l'interface entre deux milieux lors
du passage entre ces deux milieux.
Précision : Les valeurs des figures ci-dessous sont des valeurs arrondies à 4 chiffres après la virgule. Il faut donc s'attendre à ce que vos
résultats présentent des différences par rapport à ceux affichés ci-dessous. Elles devraient être mineures.
c) Télécharger le fichier ReflexionEtTransmission.zip. Extraire les fichiers qu'il contient. Créer un projet de développement intégrant les fichiers .cpp du fichier zip et les fichiers .cpp des questions (a) et (b). Effectuer la compilation du projet. L'exécution devrait conduire aux affichages réalisés aux figures 1, 2 et 3.
d) Télécharger le fichier RayTracing.zip (fonction main dans RayTracing.cpp). Extraire les fichiers
qu'il contient. Créer un projet de développement intégrant les fichiers .cpp du fichier zip et les fichiers .cpp des questions (a) et (b). Effectuer
la compilation de votre projet. L'exécution devrait conduire aux affichages réalisés ci-dessous. Ce programme implante un calcul d'images
par lancer de rayons. Les scènes sont constituées de sphères. Le programme ouvre deux fenêtres. Dans la première, un Z-Buffer est utilisé pour l'affichage.
Dans la seconde, la même scène est affichée en lancer de rayons. Les contrôles implantés sont les suivants :
Solutions
TP n°12 : Calcul de la quantité d'énergie diffusée en un point éclairé par une source lumineuse
Les calculs de diffusion sont fondamentaux en informatique graphique. En effet, une large part du fait que les objets de nos scènes soient visibles
est le résultat de phénomènes de réflexion diffuse. C'est en particulier ce phénomène qui est majoritairement responsable de la "couleur"
apparente des objets.
On considère les classes Rvb, Couleur, Energie suivantes :
a) On considère les classes Lumiere et LumiereDirectionnelle suivantes : Développer une méthode permettant de calculer la quantité d'énergie diffusée sous l'éclairage d'une LumiereDirectionnelle en une Position3D sur un objet où la normale est connue sous la forme d'une Direction3D. Les coefficients de diffusion de la surface sont définis par la donnée d'une Couleur. La formule de calcul à utiliser est la formule de Lambert : L = Ip Kd (.).
Sphère éclairée par une lumière directionnelle
Pour cette question, il convient de développer une méthode purement virtuelle dans la classe Lumiere qui sera implantée concrètement dans la classe
LumiereDirectionnelle. Son prototype est:
b) On considère la classe LumierePonctuelle suivante : Développer une méthode permettant de calculer la quantité d'énergie diffusée sous l'éclairage d'une LumierePonctuelle en une Position3D extraite d'une surface où la normale est connue sous la forme d'une Direction3D. Les coefficients de diffusion de la surface sont définis par la donnée d'une Couleur.
Sphère éclairée par une lumière ponctuelle Pour cette question, il convient de développer une nouvelle implantation de la méthode de calcul de diffusion dans la classe LumierePonctuelle.
c) On pourra utiliser le programme DiffusionsLambertiennes.cpp pour tester les deux méthodes
développées. Ce programme n'a pas à être modifié. Il utilise les méthodes de calcul de diffusion selon les prototypes définis ci-dessus.
Remarque: Ce code source montre comment GLUt permet d'utiliser deux (plusieurs par extension) fenêtres ainsi que les menus popup. Solutions
Hiérarchie de classes
|