Architecture d'un programme interactif graphique Objectifs: Organiser un projet selon Model-View-Controller Dessin 2D avec OPENGL Plan: - Les 3 types de dialogue utilisateur - Approche Model-View-Controller - OPENGL: du modèle au pixel - projection et buffers
Les 3 styles de dialogues avec l'utilisateur Les 3 styles de dialogues avec l'utilisateur: ligne de commande (commandes UNIX-LINUX) passage de paramètres au programme avec argc et argv Conversationnel (programmes semestre d'automne) printf, scanf, etc disponible dans la bibliothèque standard C Interface Graphique Utilisateur (Graphic User Interface) : widgets (boutons, etc...) disponible dans bibliothèques Bibliothèque (Library) : regroupe le code objet de plusieurs fichiers sources réalisant une tâche bien définie (exemple: interface graphique, dessin, etc...) API (Application Programming Interface) : prototypes des fonctions exportées par une bibliothèque dans un fichier en-tête (exemple: gl.h) = fichier d'interface de la bibliothèque
L'architecture MVC: Model-View-Controller(1) Objectifs : Permettre plusieurs styles de Visualisations et de Contrôle par l'utilisateur sur un Modèle. Contrôle S'adapter facilement à l'évolution rapide de la technologie des parties "Visualisation" et "Contrôle utilisateur" en gardant stable la partie "Modèle métier" Les compétences sont souvent focalisées sur un sous-système, rarement sur l'ensemble des trois. Visualisation Modèle sous-système
L'architecture MVC: Model-View-Controller(2) Simplifications dans le cadre du cours/projet : Contrôle Le Modèle exploite directement les fonctions mises à disposition dans graphic.c Modèle graphic.c :dépendances dessin Visualisation Le module graphic.c regroupe les dépendances de dessin vis-à-vis d'une bibliothèque externe (OPENGL). Il offre le moyen de dessiner des éléments simples en 2D.
Les bibliothèques à disposition GLUI : GLUT-based User Interface Library. Visualisation d une interface graphique utilisateur (Graphic User Interface) GLUT: Open GL Utility Toolkit Contrôle de la gestion des fenêtres et de la file d attente des évènements (clavier, souris, etc ). OPENGL : Visualisation de bas niveau pour le dessin.
View: dessin 2D avec la bibliothèque OPEN-GL Une bibliothèque pour afficher des objets 2D et 3D API d'environ 150 fonctions: exemple #include <GL/glut.h> ajouter la bibliothèque lgl dans le fichier Makefile (règle de dépendance de l'exécutable produisant une édition de liens) http://www.xmission.com/~nate/tutors.html
De l'espace du modèle à l'espace d'affichage Espace 2D continu Y top left right bottom X 1) Le "modèle" que l'on veut dessiner avec OPENGL doit est représentable à l'aide de points, lignes, polygones (plein ou vide), etc... Le programme a le contrôle sur les coordonnées (x,y) des points qu'il initialise et met à jour si nécessaire 2) cadrer = choisir une projection orthographique qui définit les bornes left, right, bottom, top de l'espace qui sera dessiné dans la fenètre graphique. Si on ne précise rien OPENGL dessine [0,1] x [0,1] height 3) Il faut préciser quelle partie de la fenêtre (=viewport) va recevoir le dessin. En général on indique toute la fenêtre avec glviewport(0,0,width, height) 4) dessiner = appeler les fonction OPENGL de dessin width Espace fini et discret de la fenêtre graphique exprimé en pixels: width x height
L'espace OpenGL par défaut (1) 1 Y top Si aucune projection orthographique n'est définie seul le contenu de cet espace sera visualisé dans la fenètre graphique left (0,0) bottom X 1 right L'origine de l'espace est dans le coin inférieur gauche L axe des x croît vers la droite, sur l'intervalle [0., 1.] L'axe des y croît vers le haut, sur l'intervalle [0., 1.] C'est un espace continu (coordonnées avec des float)
L'espace OPENGL par défaut (2) Y (1,1) (0,0) X Espace GL dessiné par défaut Ce qui apparaît dans la fenètre d affichage GL affiche seulement les objets, ou morceaux d objets, contenus dans l espace [0,1] x [0,1]
Définir l espace visible avec la projection orthographique glortho( ) Y top 1 Y (1,1) (0,0) X bottom -1 X left 0 2 right Ce qui apparaît dans la fenètre d affichage Les bornes minimum et maximum de la projection orthographique peuvent être modifiées avec: glortho(left, right, bottom, top, -1, 1); Dans l exemple ci-dessus: glortho( 0, 2, -1, 1, -1, 1);
Conséquence d'une différence de proportions entre glortho et la fenêtre Y largeur 1 Y (1,1) hauteur hauteur (0,0) X largeur -1 X 0 2 Ce qui apparaît dans la fenètre d affichage Si l espace GL n a pas les mêmes proportions «largueur/hauteur» que la fenêtre d affichage, le dessin subit une distorsion. Dans l exemple ci-dessus l espace GL est de proportion 1. tandis que la fenêtre est de proportion 2. Le dessin subit une homothétie de 2 selon X.
Il faut garantir un même aspect-ratio La projection orthographique est modifiée pour avoir un aspect-ratio de 2 identique à celui de la fenêtre d affichage 0.5 Y Y (0,0) (1,1) X -0.5 0 2 X Ce qui apparaît dans la fenètre d affichage 1) Toujours garantir les mêmes proportions largeur/ hauteur = aspect-ratio pour ne pas introduire de distorsion. 2) Si la taille de la fenêtre change, il faut ajuster la rapport largeur/hauteur de la projection orthographique pour avoir le même aspect-ratio. 3) Faire un choix parmi l'infinité de possibilités pour cet ajustement, par ex doubler la largeur au lieu de diviser la hauteur par 2.
Dessiner avec OpenGL (1) Machine à état: Commandes de modification d'attributs: couleur, épaisseur du trait, etc... Dessine avec ces attributs jusqu'à la prochaine modification Variable d état Valeur par défaut Fonction GL pour modifier l état Épaisseur du trait 1 pixel gllinewidth(nb_pixel) couleur du fond noir glclearcolor(r,g,b,0.) couleur du dessin blanc glcolor3f(r,g,b) Composition additive des couleurs Triplets (Red,Green,Blue) avec 0.< R,G,B < 1. (1, 0, 0) = rouge (0, 1, 0) = vert (0, 0, 1) = bleu (1, 1, 0) = jaune (1, 0, 1) = magenta (0, 1, 1) = cyan
Dessiner avec OpenGL (2) 1. Effacer la fenètre: glclearcolor et glclear 2. Re-initialiser les transformations: glloadidentity 3. Projection du domaine 2D: glortho 4. Optionel: (re)définir les attributs: couleur,épaisseur de trait 5. Dessin: glbegin( mode ) énumérer les points de l'objet avec glvertex2f(x,y) glend() 6. si double buffer actif glutswapbuffer()
Méthode du double-buffer But: présenter une image stable sur l'écran (front buffer) pendant que le dessin est réalisé progressivement dans une autre mémoire d'image (le back-buffer). 3 étapes: 1. Effacer le back-buffer (invisible) 2. Dessiner (implicite) dans le back-buffer 3. Intervertir "instantanément" les 2 buffers avec glutswapbuffers Le dessin est construit progressivement dans le back-buffer
Méthode du double-buffer But: présenter une image stable sur l'écran (front buffer) pendant que le dessin est réalisé progressivement dans une autre mémoire d'image (le back-buffer). 3 étapes: 1. Effacer le back-buffer (invisible) 2. Dessiner (implicite) dans le back-buffer 3. Intervertir "instantanément" les 2 buffers avec glutswapbuffers Le dessin est construit progressivement dans le back-buffer Ce qu'on voit à l'écran (= front buffer)
Exemple: avec et sans double buffer Avec le double-buffering: Sans double-buffering: une image en cours de calcul peut être affichée au cours d'une animation faisant alors clairement apparaître la génération progessive du résultat final.
Résumé En vertu du principe de séparation des fonctionalités nous adoptons l'approche Model-View-Controller pour l'architecture d'une application interactive. Le sous-système de Contrôle pilote celui de Visualisation et celui du Modèle du problème traité. La bibliothèque GLUT est utilisée pour le Contrôle de l'interaction avec l'utilisateur (souris, clavier ). La visualisation de l'interface graphique utilisateur exploite GLUI tandis que la visualisation du Modèle exploite la bibliothèque OPENGL OPENGL : La proportion largeur/hauteur de l'espace visualisé du Modèle doit être la même que celle de la fenêtre de dessin pour éviter les distorsions.