Les bases d'opengl Par Xavier Michelon



Documents pareils
Chapitre II : Infographie et bibliothèques graphiques

MEMENTO D'UTILISATION Du T.N.I. SmartBoard (Version )

DÉCOUVERTE DE CAPTURE ONE

Table des matières. F. Saint-Germain / S. Carasco Document réalisé avec OpenOffice.org Page 1/13

Tp_chemins..doc. Dans la barre "arche 2" couleur claire 1/5 21/01/13

Synthèse d'images. (1) Introduction

Choisir entre le détourage plume et le détourage par les couches.

Création de maquette web

Traitement numérique de l'image. Raphaël Isdant

Projet de traitement d'image - SI 381 reconstitution 3D d'intérieur à partir de photographies

Créer un diaporama avec Open Office. Sommaire

Utilisation d'interwrite avec un vidéoprojecteur interactif EPSON

Création d'un site dynamique en PHP avec Dreamweaver et MySQL

Utilisation de XnView

I. Introduction aux fonctions : les fonctions standards

Chapitre 2. Classes et objets

Utilisation du visualiseur Avermedia

l'ordinateur les bases

Tutoriel : logiciel de présentation Openoffice Impress

TBI-DIRECT. Bridgit. Pour le partage de votre bureau. Écrit par : TBI Direct.

Introduction à Adobe Illustrator pour la cartographie et la mise en page

Adobe Illustrator Logiciel de dessin vectoriel et de Cartographie Assistée par Ordinateur

PHOTOSHOP - L'AFFICHAGE

Java 7 Les fondamentaux du langage Java

Virtualisation de Windows dans Ubuntu Linux

Guide pour la réalisation d'un document avec Open Office Writer 2.2

Généralités sur le Langage Java et éléments syntaxiques.

Introduction au langage C

MEMENTO D'UTILISATION DE INTERWRITE 8 version

DE L ALGORITHME AU PROGRAMME INTRO AU LANGAGE C 51

PHPWEBSITE -Tutoriel image

Modules Multimédia PAO (Adobe)

Reaper : utilisations avancées

DOSSIER D'ACTIVITES SUR TUXPAINT Dessiner avec Tuxpaint. Objectifs :

Transférer et enregistrer les photos sur l'ordinateur

Saisir et traiter les engagements de coûts

Didacticiel de mise à jour Web

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Utilisation du logiciel Epson Easy Interactive Tools

LES NOUVEAUTÉS DE ARCON 15 PRO

Freeway 7. Nouvelles fonctionnalités

Prise en main du logiciel. Smart BOARD Notebook 10

Seance 2: En respectant la méthode de programmation par contrat, implémentez les autres fonctions de jeu.

Interwrite Workspace version 8 avec le projecteur Epson

StarDraw, le module de dessin de StarOffice 6/7

Création d'un questionnaire (sondage)

Qu'est ce que le Cloud?

Swyx Skin Editor - Guide de l'utilisateur. SwyxIt Skin Editor L éditeur de création des habillages individuels

Bien travailler sur plusieurs écrans

Chapitre 4 Pierre, papier, ciseaux

Guide de l'utilisateur de l'utilitaire d'installation de caméra Avigilon

modélisation solide et dessin technique

1. Introduction Création d'une macro autonome Exécuter la macro pas à pas Modifier une macro... 5

31. OOo Draw Réglages propres à Draw

Cours de D.A.O. Mécanique

MDI Chèque de Allégroupe Réclamation

Programmation système I Les entrées/sorties

pcon.planner 6 Préparer et présenter une implantation en toute simplicité

1. Introduction Création d'une requête...2

Formation > Développement > Internet > Réseaux > Matériel > Maintenance

Fête de la science Initiation au traitement des images

Créer un modèle Impress

Le langage C. Séance n 4

Guide d utilisation de fonctionnalités avancées de Beyond 20/20 (application à des données départementales issues de Sit@del2)

Un exemple avec WORKSPACE d'interwrite

Dessiner dans Galaad FRANÇOIS PALLUT

DOCUMENTATION VISUALISATION UNIT

Projet ISN - dossier réalisé par Randrianarimanana Stéphanie. Titre du projet : Site de rencontre. le nom de notre site de rencontre : Linkymeet

1. Aperçu des fonctionnalités Page Vérification de l activation du mode Tablet PC Page 3

Gestion de projet. GanttProject Didacticiel V novembre Gérard Gervois Frédéric Giamarchi

GESTION DU PARC INFORMATIQUE

Publication Assistée par Ordinateur

TRUCS & ASTUCES SYSTEME. 1-Raccourcis Programme sur le Bureau (7)

Traitement par lot redimensionner des images

Comment créer un diagramme de Gantt avec OpenOffice.org

Synthèse d'images I. Venceslas BIRI IGM Université de Marne La

Compression de Données - Algorithme de Huffman Document de Conception

Manuel d utilisation NETexcom

COPIER, COUPER, COLLER, SELECTIONNER, ENREGISTRER.

BADPLUS V5 MANUEL D'UTILISATION. Imports de données joueurs à partir de la base fédérale en ligne Poona. Stéphan KIEFFER - Dominique BOSSERT

INSERER DES OBJETS - LE RUBAN INSERTION... 3 TABLEAUX

TRAVAILLER SUR LES ORDINATEURS DU LYCEE

Parcours FOAD Formation EXCEL 2010

Guide Draw. Chapitre 5 Combiner plusieurs objets

MANUEL TBI - INTERWRITE

Ressources pour débutant du logiciel SMART Notebook

Ressources pour débutant du logiciel SMART Notebook

TRAVAUX DIRIGES D'INFORMATIQUE INITIATION A LA MANIPULATION DE WINDOWS 98

Note de cours. Introduction à Excel 2007

Rapidolect Les Productions de la Columelle ( ) Page 1

Séance 0 : Linux + Octave : le compromis idéal

Mise en scène d un modèle dans l espace 3D

YAPBA M. Logiciel libre de suivi de vos comptes

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

Service Informatique et Télématique (SITEL), Emile-Argand 11, 2009 Neuchâtel, Tél ,

Dans la série. présentés par le site FRAMASOFT

Personnalisation Fiche Annuaire

Transcription:

Les bases d'opengl Par Xavier Michelon Introduction Après notre présentation d'opengl, nous passons aujourd'hui à la pratique, avec l'étude d'un exemple classique qui peut être considéré comme le "Hello World" d'opengl. Le but est d'aborder les mécanismes standards de la programmation OpenGL en C : création de fenêtre avec glut, gestion des événements, description de la scène 3D. L'exemple que nous allons étudier aujourd'hui est relativement simple : notre but est d'afficher à l'écran un carré coloré. En guise de petit plus, et afin d'aborder la gestion des événements, nous donnerons à l'utilisateur la possibilité de modifier la méthode d'affichage du carré (carré plein, fil de fer, ou sommets seuls) par l'intermédiaire du clavier. Pour l'instant, nous nous contenterons d'un carré en deux dimensions, car un passage à la troisième dimension pour l'affichage d'un cube nous obligerait à considérer des notions de projection perspective et de placement de la caméra virtuelle qui feront l'objet de plusieurs didacticiels. Notre scène 3D Avant de commencer à coder, je vous propose de visualiser sur la figure 1 la scène que devra représenter notre petit programme. Le résultat final est sur la figure 2. Figure 1 : La scène 3D Préparatifs : 1

Figure 2 : Le résultat final ( en couleur! ) A la manière d'un modeleur 3D, nous utiliserons en OpenGL le concept de caméra virtuelle. Virtuelle parce qu'elle n'est pas à proprement parler un objet de la scène 3D, mais elle nous indique le point de vue de l'observateur, la direction du regard et l'inclinaison de la caméra. Comme nous n'aborderons pas les modifications de point de vue et de perspective dans cet article, le point de vue sera celui qu'opengl offre par défaut : la caméra est située sur l'axe Z, pointe vers l'origine du repère (le point O), et la verticale de la caméra correspond à l'axe Y du repère. La vue de la scène se fait grâce à une projection orthogonale (pas de point de fuite pour les objets) qui permet de visualiser dans la fenêtre tous les points dont les coordonnées en X et Y sont comprises entre 1 et +1. En définissant notre carré par les 4 points indiqués sur la figure 1, on obtient la vue représentée sur la figure 2. Conventions de noms de fonctions Les fonction OpenGL sont régies par un certain nombre de règles : Tous les noms de fonctions OpenGL sont préfixés : les noms de fonction OpenGL commencent par 'gl'. Pour les bibliothèques annexes telles que GLU et GLX, les préfixes respectifs sont 'glu' et 'glx'. En guise d'exercice, je vous laisse déterminer le préfixe pour les fonctions glut ;). Certaines commandes OpenGL existent en plusieurs variantes, suivant le nombre et le type de paramètres qu'admet la variante. Ainsi, la fonction glvertex3f() prend trois paramètres ('3') de type Float ('f'), alors que glvertex2i() fonctionne avec 2 entiers. Certaines fonctions possèdent une version suffixée par un 'v'. Les paramètres sont passés à ces fonctions par l'intermédiaire d'un pointeur sur un tableau. OpenGL redéfinit des types de données numériques : GLint correspond aux entiers, GLfloat aux flottants, GLbyte aux caractères non signés... Il est préférable d'utiliser ces types de données plutôt que les types standards du C. A l'attaque! Votre session emacs est ouverte? Allons y! Première chose à faire : inclure les fichiers d'en tête OpenGL. Il en existe plusieurs, mais heureusement glut les appelle pour nous. On se contentera donc d'un simple #include <GL/glut.h> La bibliothèque OpenGL est conçue comme une machine à états. Par conséquent, une des premières choses à faire est d'initialiser cette machine. Le nombre de variables d'état accessibles est assez impressionnant. Le mode de dessin, la couleur de fond et le type d'éclairage en sont des exemples. Au cours de cette série d'articles, nous introduirons progressivement les états les plus couramment utilisés. Bien sûr, OpenGL dispose d'un état par défaut, et nous nous contenterons donc dans la phase d'initialisation de régler 2 états : la couleur de fond, et la taille d'un point. Les fonctions à utiliser sont les suivantes: void glclearcolor(glclampf rouge,glclampf vert,glclampf bleu,glclampf alpha); void glpointsize(glfloat taille); glclearcolor() permet de spécifier la couleur de remplissage utilisée lors d'un effacement de la scène. On peut donc l'assimiler à la couleur du fond. Le mode de spécification de couleur est le classique RGB avec une composante supplémentaire alpha, utilisée pour la gestion de la transparence des objets. Nous ne l'utiliserons pas ici et lui 2

affecterons systématiquement la valeur 0. Chacune des 4 composantes doit être comprise entre 0 et 1. Si vous avez l'habitude de travailler avec des entiers compris entre 0 et 255, une simple division de chaque composante par 255 vous permettra de trouver la bonne valeur. Ainsi glclearcolor(1.0,1.0,1.0,0.0) nous donne un fond blanc, et glclearcolor(0.0,0.0,0.0,0.0) un fond noir. Par défaut, lorsqu'on choisit de représenter les objets simplement par leurs sommets, la taille des sommets à l'écran est de 1 pixel. Afin de les rendre plus visible, nous réglerons la taille des sommets à 2 pixels : glpointsize(2.0); Initialisation de glut et création de la fenêtre : Comme vous nous l'avons vu le mois dernier, c'est glut qui gère les interactions entre OpenGL et le serveur X. La phase d'initialisation va nous permettre de créer notre fenêtre. Un des atouts de glut est sa grande simplicité. L'initialisation de glut se fait de la manière suivante : glutinit( glutinitdisplaymode(glut_rgb); glutinitwindowposition(200,200); glutinitwindowsize(250,250); glutcreatewindow("ogl1"); Si vous suivez la rubrique "Programmation GTK" de David Odin dans Linux Magazine, vous avez peut être une idée de ce que fait la fonction glutinit(). Elle analyse les données passées en paramètres au programme et initialise la bibliothèque glut, notamment en établissant la communication avec le serveur X. La fonction glutinitdisplaymode est celle qui vous paraîtra sans doute la plus obscure. Elle permet de régler les paramètres liés à l'affichage : type d'image (palette indexée ou RVB), utilisation d'un tampon de profondeur (plus connu sous le nom de Z buffer ou depth buffer), utilisation du double buffering... Aujourd'hui un simple tampon d'image en mode RVB défini par la constante GLUT_RGB nous suffira. Afin de satisfaire les plus anglophobes, je vais quand même préciser que les fonctions glutinitwindowposition() et glutinitwindowsize() permettent respectivement de définir la position du coin supérieur gauche de la fenêtre OpenGL par rapport au coin supérieur gauche de l'écran, et de spécifier la largeur et la hauteur de la fenêtre. La fenêtre est créée grâce à l'appel à glutcreatewindow() et son nom doit être transmis sous forme de chaîne de caractères. Il s'agit du nom qui apparaîtra notamment dans la décoration de la fenêtre, gérée par le window manager. Si la fenêtre est bel et bien créée, elle ne sera affichée à l'écran que lors de l'entrée dans la boucle de gestion des événements. Mise en place des fonctions de rappel : Le système de gestion des événements offert par glut est relativement similaire à celui de GTK. Des fonctions sont associées aux différents types d'événements envoyés par le serveur X, puis une boucle d'attente est lancée. A chaque fois qu'un événement est émis par le serveur X, la fonction de rappel associée à l'événement est appelée. Vous devez associer au moins une fonction de rappel, la fonction d'affichage, qui est celle dans laquelle vous devez décrire votre scène 3D. Vous pouvez associer des fonctions de rappel aux événements liés : au clavier à la souris à des périphériques d'entrée répandus en infographie (spaceballs, boîtes de potentiomètres, tablettes graphiques...) à la modification de la configuration de la fenêtre Il existe par ailleurs deux fonctions de rappel spéciales qui permettent d'enregistrer des fonctions qui seront appelées à intervalles de temps réguliers ou pendant les temps d'oisiveté (idle), c'est à dire lorsque le gestionnaire n'a aucun événement à traiter. Ces deux fonctions sont extrêmement pratiques pour la création de scènes animées. Dans notre programme, en plus de la fonction d'affichage obligatoire, nous allons mettre en place une fonction de rappel pour le clavier. Les deux appels suivants permettent de spécifier quelles seront les fonctions respectivement associées à l'affichage et au clavier : 3

glutdisplayfunc(affichage); glutkeyboardfunc(clavier); Après cela, il ne nous reste plus qu'à lancer la boucle d'attente des événements : glutmainloop(); La fonction d'affichage : La fonction d'affichage constitue le coeur du programme. C'est ici que nous allons décrire la scène. Pour être plus exact, la fonction d'affichage contient la procédure à appliquer pour redessiner notre scène dans la fenêtre, en commençant par un remplissage de la fenêtre avec la couleur de fond que nous avons défini dans la phase d'initialisation. On utilise pour cela void glclear(glbitfield masque); OpenGL travaille avec plusieurs zone tampons en plus de la zone d'image (tampon de profondeur, d'accumulation...). Le paramètre masque permet de spécifier les tampons que l'on souhaite effacer. Nous n'utilisons aujourd'hui que le tampon d'image. Notre masque vaudra GL_COLOR_BUFFER_BIT. Il nous faut ensuite décrire la scène 3D. La méthode de représentation d'un scène d'opengl est la plus classique qui soit : une scène est constituée d'objets. Un objet est défini par un ensemble de polygones. Un polygone est un ensemble de points de l'espace reliés entre eux par des arêtes. Si vous êtes un de fan de Quake 3, vous savez sans doute que cette méthode de description n'est pas la seule : OpenGL autorise l'utilisation de courbes de Bézier et autres NURBS pour la description des objets. Oublions ceci pour l'instant. Pour spécifier notre scène 3D, nous allons devoir énumérer la liste des polygones. La méthode est la suivante : on indique le début de la description du polygone, on explicite chaque point du polygone, puis on indique la fin de l'énumération. A chaque déclaration de points, on peut modifier certaines variables d'état, comme la couleur active. Notre scène ne comportant qu'un polygone, la description sera vite faite. glbegin(gl_polygon); glcolor3f(1.0,0.0,0.0); glvertex2f( 0.5, 0.5); glcolor3f(0.0,1.0,0.0); glvertex2f(0.5, 0.5); glcolor3f(0.0,0.0,1.0); glvertex2f(0.5,0.5); glcolor3f(1.0,1.0,1.0); glvertex2f( 0.5,0.5); glend(); Chaque description de polygone commence par un appel à void glbegin(glenum mode); Le paramètre mode auquel nous donnons la valeur GL_POLYGON indique la technique utilisée pour relier par des arêtes les différents points du polygone. En mode GL_POLYGON, chaque sommet et relié à son prédécesseur, et pour fermer le polygone, le dernier point est relié au premier. La primitive de spécification d'un sommet du polygone est glvertex(). comme nous travaillons dans le plan d'équation z=0, nous utiliserons la variante à deux arguments de type GLfloat : void glvertex2f(glfloat x,glfloat y); Bien entendu, x et y sont les coordonnées cartésiennes du sommet. La commande glcolor3f() modifie la couleur dite active. Son prototype est : void glcolor3f(glfloat r, GLfloat v,glfloat b); 4

Chaque sommet d'un polygone possède une couleur, qui est la couleur active lors de la création du sommet avec glvertex(). En associant à chaque point de notre carré une couleur différente, et compte tenu du mode de remplissage de polygone proposé par défaut, notre carré sera rempli en interpolant les couleurs des sommets. En termes simples, on obtient un dégradé. La fin de la description d'un polygone est marquée par un simple glend().dans le cadre d'un cube, il faudrait réitérer 5 fois l'opération de description de polygone. Pour nous simplifier la tâche, OpenGL dispose d'un certain nombre des fonctionnalités comme des liste d'affichage. Pour terminer notre fonction d'affichage, un glflush() permet de s'assurer que toutes les commandes ont bien été transmises au serveur. La fonction de rappel du clavier : Nous avons enregistré précédemment une fonction nommée clavier() grâce à la fonction glutkeyboardfunc(). La dernière étape de la création de notre programme va consister à écrire cette fonction. Son prototype est défini par glut : void clavier(unsigned char touche,int x,int y); Lorsque l'utilisateur appuiera sur une touche du clavier, la boucle de gestion effectuera un appel à clavier(). La variable touche contiendra le caractère correspondant à la touche pressée, x et y indiqueront la position de la souris lors de la frappe sur le clavier. x et y sont données relativement à la fenêtre OpenGL. Dans la plupart des cas, la fonction de rappel pour les événements de type clavier est constituée d'une structure switch dont la clause de test porte sur le caractère passé en paramètre. Voici notre fonction clavier : void clavier(unsigned char touche,int x,int y) switch (touche) case 'p': /* affichage du carre plein */ glpolygonmode(gl_front_and_back,gl_fill); case 'f': /* affichage en mode fil de fer */ glpolygonmode(gl_front_and_back,gl_line); case 's' : /* Affichage en mode sommets seuls */ glpolygonmode(gl_front_and_back,gl_point); case 'q' : /*la touche 'q' permet de quitter le programme */ exit(0); La touche 'q' est associée à la fonction exit() permettant de quitter le programme. Cette méthode n'est pas très 'propre', et nous l'améliorerons le mois prochain. Les touches 'p','f' et 's' vont permettre à l'utilisateur de choisir le mode de tracé des polygones. Pour cela, il suffit de modifier l'état de la machine OpenGL, par un appel à la fonction void glpolygonmode(glenum face,glenum mode); chaque polygone possède une face avant et une face arrière définie par l'ordre de saisie des sommets du polygone. Il est possible d'associer un mode de dessin différent pour la face avant et arrière d'un polygone. Le paramètre face indique la face dont on veut changer le mode de dessin : GL_FRONT : face avant GL_BACK : face arrière GL_FRONT_AND_BACK : les deux faces Le paramètre mode définit le mode de dessin souhaité pour la ou les faces choisies : GL_FILL : le polygone est entièrement rempli. 5

GL_LINE : seuls les contours du polygone sont dessinés (mode fil de fer) GL_POINT : seuls les sommets du polygone sont affichés. En changeant la valeur d'une variable d'état, nous modifions le processus de rendu de notre image, il est donc nécessaire d'effectuer une demande de réaffichage de la scène en appelant glutpostredisplay(), dont l'effet et de générer un événement qui va amener la boucle de gestion des événements à lancer la fonction d'affichage. Conclusion : Nous voilà arrivés au terme de cet article. Le code source complet du programme est fourni. Voici la commande nécessaire à la compilation. gcc ogl1.c o ogl L/usr/X11R6/lib lgl lglu lglut lx11 lxmu lxi lm Le mois prochain, nous corrigerons quelques petits défauts du programme, notamment le phénomène de distorsion du carré lors d'un redimensionnement de la fenêtre OpenGL. Nous aborderons également les techniques de base de l'animation. D'ici là, amusez vous bien! Références : OpenGL 1.2 www.opengl.org www.mesa3d.org reality.sgi.com/mjk/glut3 Woo, Neider, Davis et Shreiner Campus Press Référence La traduction française de la dernière édition du livre de référence en matière de programmation OpenGL Le site officiel d'opengl. Tout y est : présentation, documents de spécification, liens vers des didacticiels, bibliographie le site de Mesa, l'implémentation libre d'opengl la plus utilisée sous Linux la page de glut. Vous y trouverez le manuel de référence glut Code source: /********************************************************/ /* ogl1.c */ /********************************************************/ /* Premiers pas avec OpenGL. */ /* Objectif : afficher a l'ecran un carre en couleur */ /********************************************************/ /* inclusion des fichiers d'en tete Glut */ #include <GL/glut.h> void affichage(); void clavier(unsigned char touche,int x,int y); int main(int argc,char **argv) /* initialisation de glut et creation de la fenetre */ glutinit( glutinitdisplaymode(glut_rgb); glutinitwindowposition(200,200); glutinitwindowsize(250,250); glutcreatewindow("ogl1"); /* Initialisation d'opengl */ glclearcolor(0.0,0.0,0.0,0.0); 6

glcolor3f(1.0,1.0,1.0); glpointsize(2.0); /* enregistrement des fonctions de rappel */ glutdisplayfunc(affichage); glutkeyboardfunc(clavier); /* Entree dans la boucle principale glut */ glutmainloop(); return 0; void affichage() /* effacement de l'image avec la couleur de fond */ glclear(gl_color_buffer_bit); /* Dessin du polygone */ glbegin(gl_polygon); glcolor3f(1.0,0.0,0.0); glvertex2f( 0.5, 0.5); glcolor3f(0.0,1.0,0.0); glvertex2f(0.5, 0.5); glcolor3f(0.0,0.0,1.0); glvertex2f(0.5,0.5); glcolor3f(1.0,1.0,1.0); glvertex2f( 0.5,0.5); glend(); /* on force l'affichage du resultat */ glflush(); void clavier(unsigned char touche,int x,int y) switch (touche) case 'p': /* affichage du carre plein */ glpolygonmode(gl_front_and_back,gl_fill); case 'f': /* affichage en mode fil de fer */ glpolygonmode(gl_front_and_back,gl_line); case 's' : /* Affichage en mode sommets seuls */ glpolygonmode(gl_front_and_back,gl_point); case 'q' : /*la touche 'q' permet de quitter le programme */ exit(0); 7