Programmation Graphique : TP séance 01
Rendu du TP
Pour rendre votre travail :
-
Créez un répertoire
pgra-TPxx-NOM1-NOM2
, en replaçantxx
par le numéro de la séance,NOM1
par votre nom de famille,NOM2
par le nom de famille de votre binôme oumono
si vous êtes seul(e). Il ne doit y avoir aucun espace ou apostrophe dans le nom du répertoire. -
Recopiez tous vos fichiers sources dans ce répertoire, ainsi que le
Makefile
éventuel, mais pas les fichiers compilés !Dans chaque fichier il doit y avoir au début en commentaire : vos NOMS Prénoms ainsi que ceux de votre binôme éventuel.
-
Compressez le répertoire sous la forme d'une archive au format
tgz
puis téléversez l'archive sur la page Ametice, même si vous n'avez pas fini la planche de TP.
Dans le cas où le TP n'est achevé, il vous est demandé de le terminer chez vous, puis de re-téléverser l'archive dans sa version finale, sans changer son nom, avant le début de la séance suivante.
Compresser le répertoire
Pour compresser le répertoire, vous pouvez faire clic droit / compresser dans le gestionnaire de fichier, ou taper dans le terminal :
(cd .. && tar cvfz pgra-TPxx-NOM1-NOM2.tgz --ignore-failed-read \
pgra-TPxx-NOM1-NOM2/{Makefile,*.?pp,*.[ch],*.glsl,*.png} && ls)
Vous pouvez également recopier cette fonction dans le terminal, qui utilise directement le nom du répertoire courant comme nom de fichier :
mysvg() (
local p=$(pwd) # le chemin absolu
local d=${p##*/} # le répertoire courant
echo "Sauvegarde de '$d/' dans '$d.tgz' ..."
cd .. || return 1
tar cvfz "$d.tgz" --ignore-failed-read \
"$d"/{Makefile,*.?pp,*.[ch],*.glsl,*.png} 2>/dev/null
ls -ls "$d.tgz"
)
puis l'utiliser en tapant :
mysvg
Note : les fichiers .glsl
sont les fichiers source des shaders,
les fichiers .png
sont utilisés pour les textures.
Exercice 1. Dessin de roues dentées
Le but est de dessiner des roues dentées, de différentes tailles, couleurs et épaisseur, de les emboîter les unes dans les autres et de les faire tourner.
Cet exercice est à réaliser avec la librairie GLFW en C++.
Commencez par récupérer ce Makefile ainsi que
l'exemple fw15-tetra.cpp
dans votre répertoire.
Vérifiez que vous pouvez compiler et exécuter l'exemple (au besoin, voir 3.1. Installation et compilation dans le CM 01).
La touche a
déclenche une animation, la touche p
change le type de
projection, c
change le cube repère, h
affiche l'aide pour les réglages
de la projection.
Pour des explications techniques sur le programme, lire 3. Premiers pas en GLFW. Tout ce dont vous avez besoin de savoir en OpenGL pour réaliser ce TP est expliqué dans 4. Découverte d'OpenGL.
1.1. Paramètres d'une roue
Recopiez le fichier d'exemple sous un nouveau nom, par exemple roues.cpp
;
rajoutez vos noms et prénom au début en commentaire.
En vous inspirant de la classe Tetra
présente dans l'exemple, déclarer
une classe Roue
avec les données membre suivantes, en rajoutant
le préfixe m_
:
- le nombre de dents
nb_dents
(dans l'exemple il y en a 10) ; - le rayon intérieur
r_trou
(la distance dans la figure ci-dessous) ; - le rayon de la roue
r_roue
(le rayon du grand cercle jaune qui passe entre et ) ; - la hauteur des dents
h_dent
(la différence de rayons entre le cercle rose qui passe par et , et le cercle rose qui passe par , , ) ; - la couleur
(coul_r, coul_v, coul_b)
; - l'épaisseur
ep_roue
(en ).
Rajouter un constructeur prenant tous ces paramètres ; la classe sera instanciée
dans MyApp::displayGL()
.
1.2. Dessin d'un bloc de dent
La roue est centrée à l'origine et composée de blocs de dents ; le bloc de dent initial est en rouge dans le schéma.
Écrivez une méthode dessiner_bloc_dent
qui dessine dans le plan GL_LINE_LOOP
composé des sommets draw()
de la classe, qui sera elle-même appelée dans
MyApp::displayGL()
.
Pour calculer les coordonnées nb_dents
, et considérez les droites
passant par
(points et ), (point ), (points et ), (point ), (points et ).
Les distances à l'origine (pour multiplier les cosinus et sinus) sont :
r_trou
(pour r_roue - h_dent/2
(pour r_roue + h_dent/2
(pour
1.3. Dessin d'un côté de roue
Écrivez une méthode dessiner_cote_roue
qui dessine le côté d'une roue
à partir des blocs de dents en leur faisant subir des rotations d'angle croissant
(avec glRotated
).
Pensez à utiliser glPushMatrix
et glPopMatrix
. On obtient quelque
chose comme la figure à droite (sans le cercle ni les droites matérialisant
l'angle
1.4. Remplissage de la roue
Gérez un flag flag_fill
avec une touche du clavier, et en fonction du
flag, remplacez éventuellement GL_LINE_LOOP
par GL_POLYGON
pour remplir.
Problème : le bloc de la dent n'est pas convexe → utiliser GL_TRIANGLE_FAN
en partant de C.
1.5. Deuxième roue provisoire
Dessinez le côté de la première roue en rouge, et le côté d'une deuxième roue
en vert, emboîtée dans la première. La deuxième roue est décalée à droite à
l'aide d'une translation horizontale, et légèrement tournée (de
1.6. Animation
La touche a
permet déjà de faire tourner la scène.
Inspirez-vous de l'exemple fw04-clavier.cpp
pour que la touche espace provoque
une rotation légère des deux roues dans le sens contraire ; en maintenant la
touche espace enfoncée on obtient une animation.
Réglez l'espacement horizontal entre les deux roues pour que les dents de l'une ne pénètrent pas dans l'autre, et que leurs dents restent (à peu près) visuellement en contact lorsqu'elles tournent.
1.7. Épaisseur
Écrivez une méthode dessiner_roue
qui appelle dessiner_cote_roue
avec une translation en +ep_roue/2
, et une seconde fois avec
une translation en -ep_roue/2
.
Utilisez comme couleur les paramètres (coul_r, coul_v, coul_b)
de
la roue. Il reste à dessiner les facettes (dans le sens de l'épaisseur) des
dents et des creux, ainsi que du trou central de la roue, dans des couleurs
légèrement différentes pour qu'elles soient bien visibles ; on le fait section
suivante.
1.8. Facettes
Écrivez une méthode dessiner_facettes_bloc
qui dessine les facettes
d'un bloc de dent. Notons ep_roue/2
,
et -ep_roue/2
. Il s'agit simplement
de dessiner les quadrilatères (GL_QUADS
)
Comme indiqué dans la section précédente, utilisez des couleurs légèrement
différentes, par exemple (coul_r*0.8, coul_v*0.8, coul_b*0.8)
pour les
facettes perpendiculaires à l'axe de rotation, et
(coul_r*0.6, coul_v*0.6, coul_b*0.6)
pour les facettes obliques.
Effectuez ensuite des rotations de ces facettes (avec glRotated
) pour chaque
bloc de dent, de manière à ce que la roue dentée soit entièrement dessinée en
3D.
1.9. Troisième roue
Augmentez l'épaisseur de la deuxième roue, ainsi que le rayon de son trou.
Rajoutez une troixième roue bleue, avec un rayon deux fois plus grand et deux fois plus de dents, un autre rayon de trou et une épaisseur plus fine. Placez cette roue en dessous de la roue rouge, et adaptez la variation de l'angle pour l'animation.