Aller au contenu

Programmation Graphique : TP séance 01

Rendu du TP

Pour rendre votre travail :

  • Créez un répertoire pgra-TPxx-NOM1-NOM2, en replaçant xx par le numéro de la séance, NOM1 par votre nom de famille, NOM2 par le nom de famille de votre binôme ou mono 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

Roue 5

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 OA dans la figure ci-dessous) ;
  • le rayon de la roue r_roue (le rayon du grand cercle jaune qui passe entre C et D) ;
  • la hauteur des dents h_dent (la différence de rayons entre le cercle rose qui passe par D et E, et le cercle rose qui passe par B, C, F) ;
  • la couleur (coul_r, coul_v, coul_b);
  • l'épaisseur ep_roue (en z).

Rajouter un constructeur prenant tous ces paramètres ; la classe sera instanciée dans MyApp::displayGL().

Roue 1

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 z=0 un GL_LINE_LOOP composé des sommets A à H. Testez la méthode en l'appelant dans la méthode draw() de la classe, qui sera elle-même appelée dans MyApp::displayGL().

Pour calculer les coordonnées x,y des sommets, utilisez l'angle α=AOG^=360/ nb_dents, et considérez les droites passant par O et dont l'angle avec Ox est :

  • 0 (points A et B),
  • α/4 (point C),
  • 2α/4 (points H et D),
  • 3α/4 (point E),
  • α (points G et F).

Les distances à l'origine (pour multiplier les cosinus et sinus) sont : r_trou (pour A, H et G), r_roue - h_dent/2 (pour B, C et F), r_roue + h_dent/2 (pour D et E).

1.3. Dessin d'un côté de roue

Roue 2

É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.

Roue 4

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 α/4) pour permettre l'emboîtement.

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 z de +ep_roue/2, et une seconde fois avec une translation en z de -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

Roue 6

Écrivez une méthode dessiner_facettes_bloc qui dessine les facettes d'un bloc de dent. Notons A à H les sommets du bloc pour z=ep_roue/2, et A à H les sommets du bloc pour z=-ep_roue/2. Il s'agit simplement de dessiner les quadrilatères (GL_QUADS) AHHA, HGGH, BCCB, CDDC, DEED, EFFE.

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.