Diapositive 1 - HAPCO
Transcription
Diapositive 1 - HAPCO
Histoire OpenGL (Open Graphics Library) est une spécification qui définit une API multi plate-forme pour la conception d'applications générant des images 3D (mais également 2D). La spécification s’est traduite en une librairie graphique 3D/2D. • • 1. 2. M. AMMI [email protected] Histoire • Spécification gérées par l’ARB (Architecture Review Board) • • Membres fondateurs en 1992 : SGI, Microsoft, HP. Membres suivants: 3Dlabs, Apple Computer, ATI, Dell, Evans & Sutherland, IBM, Intel, Matrox, nVidia et Sun Microsystems. • • Microsoft s'est retiré en mars 2003. L’ARB a annoncé en 2006 sa décision de transférer le contrôle de la spécification OpenGL au Khronos Group (consortium de standardisation industriel). Histoire Microsoft tente d'imposer sa technologie d'affichage Direct3D, au détriment de son concurrent OpenGL en lui conférant une place privilégiée dans Windows Vista. • Direct3D est la principale technologie d'affichage 3D du système Aero Glass. • Microsoft n‘as pas implémenté directement OpenGL dans Vista • Vista traduisait les données OpenGL au standard Direct3D pour les traiter • Problème : 50% de performances en moins. Mobilisation mondiale pour OpenGL. • • • Microsoft a fait machine arrière Il faut désactiver Aero Glass pour utiliser OpenGL • Histoire Histoire • • • OpenGL 3.0 • • • Sortie de la spécification prévue en décembre 2007. Sortie de la librairie ? Fonctionnera sur des cartes « GeForce 8 Series » et plus. On lui donne des ordres de tracé de primitives graphiques (facettes, etc.) directement en 3D, une position de caméra, des lumières, des textures à plaquer sur les surfaces, etc. OpenGL se charge ensuite de faire les changements de repère, la projection en perspective à l'écran, le clipping, l'élimination des parties cachées, d'interpoler les couleurs, et de rasteriser (tracer ligne à ligne) les faces pour en faire des pixels (image finale) • • GL: Librairie graphique standard de Silicon Graphics (orientée visualisation). Développé à partir de 1989 pour ses stations de travail Irix ainsi que sur les stations d'autres constructeurs (sous licence). OpenGL: Sous-ensemble de GL ne nécessitant pas une licence SGI (orienté visualisation) SGI met à chaque fois dans le domaine public la version N-1 de GL, bibliothèque graphique de GL. Cette approche marketing • • • décourage la concurrence : OpenGL étant gratuit et ouvert, pourquoi développer autre chose dissuade la modification d'OpenGL : car tout ajout serait à recommencer dans la version d'OpenGL suivante donne aux stations SGI un avantage concurrentiel substantiel, puisque GL a toujours une longueur d'avance sur OpenGL. 1 Principales fonctionnalités • • • • • • • • • • • • • • • • • • • Exemple Spécification de la version 2.1 (2006) • Environ 250 instructions distinctes #include <gl.h> …. void main() { ... Primitives Géométriques Vous permettent de construire des descriptions mathématiques d'objets à partir de points, lignes, polygones, images et bitmaps. Codage de couleur en RGBA (Rouge-Vert-Bleue-Alpha) ou en mode index de couleur. Visualisation et Modelage permettent d'arranger les objets dans une scène tri-dimensionelle, de bouger les caméras dans l'espace et de choisir le point de vue d'ou sera visualisé la scène. Projection de Texture apporte du réalisme au modèle en donnant un aspect réaliste au surfaces des polygones. Eclairage des Matériaux est une partie indispensable de tout infographie 3D. OpenGL fournit les commandes pour calculer la couleur de n'importe quel point à partir des propriétés des matériaux et des sources de lumières dans la pièce. Double Tampon élimine les clignotement dans les animations. Chaque image de l'animation est construite dans une mémoire tampon séparée et affichée quand le tracé est terminé. Anti-repliement reduitles lignes en zig-zag sur les écrans. Elles apparaissent surtout en basse résolution. L'anti-repliement est une technique classique qui consiste à modified la couleur et l'intensité des pixels en bordure de ligne pour attenuer l'effet de zig-zag. Ombrage de Gouraud est une technique qui applique des ombrages réguliers aux objets 3D et donne de subtiles différences de couleurs sur la surface. Tampon-Z mémorise la coordonnée Z d'un objet 3D. Le tampon Z sert à mémoriser la proximité d'un objet par rapport à l'.observateur. Sa fonction est aussi cruciale pour la suppression des parties cachées. Effets Atmosphériques comme le brouillard, la fumée et le voilage rendent les images numériques plus réalistes. Sans ces effets, les images apparaissent parfois trop piquées et top bien définies. Fog est un terme qui décrit un algorithme qui simule la brume, le crachin, la fumée, la pollution ou simplement l'air en ajoutant de la profondeur à l'image. Mélange Alpha utilise la valeur Alpha (valeur de diffusion du matériau) du code RGBA afin de combiner la couleur d'un fragment en cours de traitement avec celle d'un pixel déjà stocké dans le tampon d'image. Imaginez par exemple devoir tracer une fenetre transparente bleue devant une boite rouge. Le mélange Alpha permet de simuler la transparence de la fenetre de telle sorte que la boite vue à travers la vitre soit violette. Plans masqués restreint le tracé à certaines portions de l'écran. Listes d'affichage permettent le stockage de commandes de tracé dans une liste pour un affichage ultérieur. Avec une utilisation correcte, les listes d'affichages peuvent améliorer nettement les performances. Evaluateurs Polynomiaux supportent les Splines non uniformes rationelles-B. Cela permet de tracer des courbes régulières avec quelques points ce qui évite d'en stocker de nombreux intermédiaires. Retour, Selection et Choix sont des possibilités qui permettent aux applications d'autoriser l'utilisateur à selctionner une région de l'écran ou de choisir un objet dessiné à l'écran. Le mode Retour, permet au developpeur d'obtenir les résultats des calculs d'affichage. Primitives d'Affichage (Octets de l'affichage et rectangles de pixels) Opérations sur les Pixels Transformations: rotation, echelles, translations, perspectives en 3D, etc. glClearColor(0.0,0.0,0.0,0.0) ; glClear(GL_COLOR_BUFFER_BIT) ; glOrtho(-1.0,1.0,-1.0,1.0,-1.0,1.0) ; glColor3f(1.0,1.0,1.0) ; glBegin(GL_POLYGON) ; glVertex2f(-0.5,-0.5) ; glVertex2f(-0.5,0.5) ; glVertex2f(0.5,0.5) ; glVertex2f(0.5,-0.5) ; glEnd() ; glFlush() ; ... } Ce programme dessine un carré blanc au centre d’une fenêtre de fond noir OpenGL & le système d’exploitation OpenGL & le système d’exploitation • Des bibliothèques construites au dessus d'OpenGL fournissent des fonctions de plus haut niveau : • GLUT • GLX • AUX Donnée à afficher • etc. OS : Affichage & événements • • • • • Librairies Intermédiaires OpenGL : Calculs 3D Événements Programmation simplifiée Indépendants de l'OS Ne font pas officiellement partie d'OpenGL Gestion des fenêtres, clavier et souris Primitives avancées : Cube, sphères, etc. Bibliothèques d'OpenGL Bibliothèques d'OpenGL • • OpenGL Library (GL) • Librairie standard proposant les fonctions de base pour l'affichage en OpenGL • Pas de fonction pour la construction d'une interface utilisateur (fenêtres, souris, clavier, ...) • Préfixe des fonctions: gl (glVertex3f) OpenGL Utility Library (GLU) • Librairie standard proposant des commandes bas-niveau écrites en GL: certaines transformations géométriques triangulation des polygones rendu des surfaces paramétriques et quadriques • ... • • • • Préfixe des fonctions: glu (gluPerspective) 2 Bibliothèques d'OpenGL • Bibliothèques d'OpenGL OpenGL extension to X-Windows (GLX) Utilisation d’OpenGL en association avec X Windows pour l'interface utilisateur • Préfixe des fonctions: glX (glXCreateWindow) • • • Auxiliary Library (Aux) Bibliothèque écrite pour rendre simple la programmation de petites applications dans le cadre d'interfaces graphiques interactives simples: • gestion d'une fenêtre d'affichage • gestion de la souris • gestion du clavier • ... • Préfixe des fonctions: aux (auxInitWindow) • Organisation d’une application OpenGL main() { // Initialisation de l’application: 1 // - Ouverture d’une fenêtre 2 // - Chargement & definition des textures, matériaux, etc. 3 4 while(pas fini) { 5 // Specification du code de la trame en cours: // - Effacer l’écran // - Specification de la position & propertiés de la caméra // - Specification de l’ éclairage (activation, etc) trame en cours for(chaque objet) { // Specification du code correspondant à l’objet // - Specification de la position & orientation (matrix) de l’objet for(chaque matériau) { // Specification des properties des matériaux // - propriétés d’éclairage // - propriétés des textures for(chaque primitive) { // Rendre la primitive (glBegin, glVertex3f…) } } } // Finalisation du code de la trame en cours (glSwapbuffers()…) } // Code de sortie } Organisation d’une application OpenGL int main(int argc, char **argv) { glutInit(&argc, argv); glutInitWindowSize(largeur,hauteur); glutInitWindowPosition(10,100); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); glutCreateWindow(argv[0]); /* Routines de rappel */ glutReshapeFunc(reshape); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); /* Autres initialisation */ initGL(); OpenGL Utility Toolkit (GLUT) • Équivalent à Aux • Interface utilisateur programmable plus élaborée (multifenêtrage, menus popup) -> plus grande complexité • Préfixe des fonctions: glut (glutInitWindowSize) • La plus utilisée en association avec OpenGL Organisation d’une application OpenGL Fonction principale Fonction d’initialisation de GL •Initialisation et création de la fenêtre •Intégration des Buffers : Z, Double,... •Spécification des routines de rappel •Etc. •Activation des Buffers •Définition des textures, matériaux,... •Activation de l’éclairage •Etc. Application OpenGL Routines de rappel associées à la fenêtre Fonction de dessin : •Fonction exécutée en boucle •Spécification : géométrie, texture,... Fonctions de gestion d’événements : Clavier, souris,... •Fonctions appelées à chaque cliques, déplacement,... •Capture et renvoi les événements à l’application Fonction de redimensionnement •Fonction appelée à chaque redimensionnement de la fenêtre •Cadrage de la sortie du Pipline 3D avec la fenêtre d’affichage 2D Organisation d’une application OpenGL void initGL(void) { glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightModelfv(GL_AMBIENT, LAmbientValue); glLightfv(GL_LIGHT0, GL_POSITION, Lposition1); glLightfv(GL_LIGHT0, GL_AMBIENT, LAmbientValue); glLightfv(GL_LIGHT0, GL_DIFFUSE, LDiffuseValue); glLightfv(GL_LIGHT0, GL_SPECULAR, LSpecularValue); glShadeModel(GL_SMOOTH); glEnable(GL_CULL_FACE); } /* Lancement de la boucle principale */ glutMainLoop(); return 0; } 3 Organisation d’une application OpenGL Organisation d’une application OpenGL void display(void) { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POLYGON) ; glColor4fv(couleurRouge()) ; glVertex2f(-0.5F,-0.5F) ; glColor4fv(couleurVert()) ; glVertex2f(-0.5F,0.5F) ; glColor4fv(couleurBlanc()) ; glVertex2f(0.5F,0.5F) ; glColor4fv(couleurBleu()) ; glVertex2f(0.5F,-0.5F) ; glEnd() ; void reshape(int large, int haut) { glViewport(0, 0, large, haut); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)large/(GLfloat)haut, 0.1, 128.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } glFlush(); } glutSwapBuffers(); Format des instructions Organisation d’une application OpenGL • void Keyboard(unsigned char key, int x, int y) { printf("vous avez appuyé sur %c ",key); if (key==27) exit(0); } void Keyboard(unsigned char key, int x, int y) { Switch (key) { Case : "A" view_rotx=+0.1; break(); Case : "B" view_roty=+0.1; break(); } glRotatef(view_rotx,1.0,0.0,0.0); glRotatef(view_roty,0.0,1.0,0.0); Format des instructions glVertex3fv( v ) Nombre de données 2 - (x,y) 3 - (x,y,z) 4 - (x,y,z,w) } Type de donnée b ub s us i ui f d - byte unsigned byte short unsigned short int unsigned int float double Vecteur Ne pas mettre “v” pour la version scalaire glVertex2f( x, y ) Syntaxe Ex: void glVertex2d( GLdouble x, GLdouble y ) void glVertex3f( GLfloat x, GLfloat y, GLfloat z ) void glVertex4i( GLint x, GLint y, GLint z, GLint w ) void glVertex4sv( const GLshort *v ) Type OpenGL Dans une fonction Representation Type de donnée GLbyte b 8-bit integer signed char GLshort s 16-bit integer short GLint, GLsizei i 32-bit integer long GLfloat f 32-bit float float GLdouble d 64-bit float double GLubyte, GLboolean ub 8-bit unsigned integer unsigned char GLushort us 16-bit unsigned short unsigned short GLunit, GLenum, GLbitfield ui 32-bit unsigned integer unsigned long 4 Syntaxe Syntaxe EX: • GLfloat R,G,B; R = 0.0; G = 0.0; B = 1.0; glColor3f(R,G,B); Les constantes (#define ou enum) sont données en majuscule et commencent par le préfixe GL_ : • • • • Ou encore • GLfloat blue[] = {0.0, 0.0, 1.0}; glColor3fv(blue); GL_COLOR_BUFFER_BIT : Ox00004000 GL_NO_ERROR : Ox0 GL_TEXTURE_2D : Ox0DE1 etc. Ex : glClearColor (1.0, 1.0, 1.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); OpenGL Rendering Pipeline OpenGL Rendering Pipeline Application • OpenGL intègre une série d'étapes de traitement appelée OpenGL Rendering Pipeline. • • • Assemblage de sommets Les données géométriques (sommets, lignes et polygones) suivent leur progression à travers un certain nombre d'étapes de traitement (évaluateurs et opérations sur les sommets) Les données pixels (pixels, images et bitmaps) sont traitées différemment pour une partie du processus. Opérations sommets Assemblage de primtives Opérations primitives Les deux types de données suivent les mêmes étapes finales (conversion en mode point et opérations sur les fragments) avant l'écriture dans le buffer des données pixels finales. Rasterization Operations fragment Framebuffer Affichage Assemblage de sommets Application struct { float x,y,z,w; float r,g,b,a; } vertex; Assemblage de sommets Opérations sommets Assemblage de sommets glColor3f(0, 0.5, 0); glVertex2i(11, 31); glColor3f(0, 0.5, 1.0); glVertex2i(37, 71); … Assemblage de primtives • • • Assemblage des sommets avec les états associés • couleurs, coordonnées textures, etc. Conversion au format interne Initialisation de certaines valeurs • z=0, w=1, etc. Opérations primitives Rasterisation Affichage Opérations sommets Assemblage de primtives struct { float x,y,z,w; // 11, 31, 0, 1 float r,g,b,a; // 0, 0.5, 0, 1 } vertex; Operations fragment Framebuffer Application Assemblage de sommets Opérations primitives Rasterisation Operations fragment struct { float x,y,z,w; // 37, 71, 0, 1 float r,g,b,a; // 0, 0.5, 1.0, 1 } vertex; Framebuffer Affichage 5 Opérations sur les sommets Assemblage de primitives Application • • • • • Transformations de modélisation • Application des transformations de composition de scène : Passage du système de coordonnées local de chaque objet 3D vers un repère global. Transformations d’affichage • Passe des coordonnées du monde à celles du point de vue (repère caméra). Transformation écran (Projection) • Les sommet 3D sont projetées sur l'espace image 2D. • Passage en coordonnées normalisées : • NDC : normalized device coordinates. Calcul d’éclairement au niveau des sommets • Composante ambiante, spéculaire, etc. Calcul des coordonnées textures au niveau des sommets Application struct { float x,y,z,w; float r,g,b,a; } vertex; Assemblage de sommets Opérations sommets Assemblage de primtives Opérations primitives Ou Rasterisation Operations fragment Ou Assemblage de primitives Application Regrouper les sommets en primitives • • Triangles, lignes, sommets Décomposition des polygones en triangles • Duplications des sommets glBegin(GL_TRIANGLE_STRIP); glColor(green); glVertex2i(…); // 0 glVertex2i(…); // 1 glColor(red); glVertex2i(…); // 2 glVertex2i(…); // 3 glEnd(); 1 • Opération de Clipping Assemblage de sommets • Opérations sommets • Opérations primitives • • Operations fragment • 2 struct { short int x,y; float depth; float r,g,b,a; } fragment; Permet de fixer la taille et la position de l'image sur la fenêtre d'affichage afin de mapper l’image calculées sur la fenêtre finale Elimination des faces cachées : • Opérations primitives Rasterisation Operations fragment Framebuffer Affichage Application Assemblage de sommets Opérations sommets Assemblage de primtives Opérations primitives Rasterisation Operations fragment Back-face Culling Framebuffer Affichage Affichage Rasterisation Application struct { vertex v0,v1,v2 } triangle; Assemblage de primtives Framebuffer Rasterisation struct { float x,y,z,w; float r,g,b,a; } vertex; Éliminer les primitives qui se trouvent à l’extérieur du Fursutm normalisé (Clipping 2D). Possibilité de créer de nouveaux sommets si il y interaction entre une primitives et le Fursutm de visualisation. Transformation de fenêtrage (Viewport) Rasterisation 0 Opérations sommets Opérations sur les primitives Assemblage de primtives 3 struct { vertex v0,v1; } line; struct { vertex v0; } point; Framebuffer Affichage • struct { vertex v0,v1,v2; } triangle; Assemblage de sommets • Assemblage de sommets Opérations sommets • Déterminer quels pixels appartiennes à la primitives Génération d’un fragment pour chaque pixel • Assemblage de primtives • Calcul de la couleur (R,G,B,A) Calcul de la profondeur (z) Application Assemblage de sommets Opérations sommets Assemblage de primtives Opérations primitives Opérations primitives Rasterisation Rasterisation Operations fragment Operations fragment Framebuffer Framebuffer Affichage Affichage 6 Opérations sur les fragments Framebuffer Application • • • Avant que les valeurs ne soient réellement stockées dans la mémoire tampon, une série d'opérations est effectuée pour modifier voire supprimer certains fragments. • Z test • Scissor test • Alpha test • Stencil test • Opérations logiques • … L'échec de l'un des tests activés peut mettre fin au traitement du fragment. Toutes ces opérations peuvent être activées ou désactivées struct { float x,y,z,w; float r,g,b,a; } vertex; Assemblage de sommets Opérations sommets struct { vertex v0,v1,v2 } triangle; struct { short int x,y; float depth; float r,g,b,a; } fragment; Assemblage de primtives Opérations primitives Rasterisation Operations fragment Application Affichage Assemblage de sommets Operations pixel Opérations primitives Rasterisation Operations fragment Framebuffer Affichage • Opérations primitives Fromatage pixel • Assemblage de primtives • • Les pixels sont transformés à partir des formats externe au format d’OpenGL : RGBA Operations pixel Opérations de facteur d’échelle, décalage, alignement, masque … Rasterisation pixel • Mémoire texture Assemblage de primtives Pipeline sommet Opérations sommets Rasterisation pixel Opérations sommets OpenGL Rendering Pipeline • Fromatage pixel Assemblage de sommets struct { int depth; byte r,g,b,a; } pixel; Framebuffer OpenGL Rendering Pipeline Pipeline pixel Application Discrétiser le pixel dans l’espace image Rasterisation primitives Operations fragment Framebuffer Display Les Buffers d’OpenGL Les Buffers d’OpenGL Framebuffer • Le framebuffer est une zone de la mémoire vidéo dans laquelle l'image est écrite (sous forme d'un bitmap) avant d'être envoyée vers le moniteur 7 Les Buffers d’OpenGL • • • • À chaque fragment est associé des coordonnées qui correspondent à un pixel, une couleur, profondeur, valeur alpha, etc. Ces informations sont interpolées à partir des valeurs aux sommets Le stockage de ces diverses informations est faite dans des buffers : • color buffer • depth buffer • stencil buffer • accumulation buffer • … Ces buffers servent aux support d'opérations spéciales avant que les pixels soient finalement écrits dans le color-buffer visible Les Buffers d’OpenGL Frame buffer = color buffer + depth buffer + stencil buffer + ... Les Buffers d’OpenGL • • Les Buffers d’OpenGL Chaque buffer est défini par sa résolution spatiale (n x m) et sa profondeur k en bit/pixel La quantité de mémoire vidéo limite la résolution maximale et le nombre de couleurs des images • • Il y en a plusieurs • front-left, front-right, back-left, back-right et quelque buffers auxiliaires • les buffers left, right et auxiliaires sont optionnels Y bpp nbCoul Mémoire 200 1 2 7,8Ko 320 200 8 256 64Ko 64Ko 640 480 4 16 150Ko 256Ko 800 600 4 16 235Ko 512Ko 640 480 8 256 300Ko 512Ko 768 4 16 384Ko 512Ko 800 600 8 256 468,7Ko 512Ko 640 480 16 65536 600Ko 1Mo 1280 1024 4 16 640Ko 1Mo 1024 768 8 256 768Ko 1Mo 640 480 24 16M 900Ko 1Mo 800 600 16 65536 937Ko 1Mo 1280 1024 8 256 1,25Mo 2Mo 800 600 24 16M 1,3Mo 2Mo 1024 768 16 65536 1,5Mo 2Mo 1024 768 24 16M 2,25Mo 3Mo Les Buffers d’OpenGL • Le double-buffering nécessite un front (visible) et un back buffer Ce sont les buffers dans lesquels on dessine • ils contiennent l'information de couleur pour chaque pixel • soit sous la forme d'un triplet (RGB) • soit d'un quadruplet (RGBA). A pour Alpha : l'opacité En openGL on a moyen de jouer avec 2 Color buffers, celui qui est actuellement afficher, pendant qu’on calcule dans le suivant ce qui sera affichée à l’image suivante. 8Ko 1024 1 1 2 • Carte Les capacités sont à doubler si on emploie la technique dite du double-buffer. Les Buffers d’OpenGL Color buffers X 320 Front Buffer 4 2 8 16 4 8 16 Back Buffer Display 8 Les Buffers d’OpenGL • Les Buffers d’OpenGL Pour l'affichage stéréoscopique on a besoin de front-right, front-left, bac k-right, back-left buffers pour les images droites et gauches • Au minimum il faut le front-left color buffer HMD 1 2 1 4 8 2 1 4 16 8 2 16 L. Front Buffer 1 4 8 16 2 4 8 1 1 2 16 Front Buffer L. Back Buffer R. Front Buffer 4 2 8 16 4 8 16 Back Buffer R. Back Buffer Display Display Display Les Buffers d’OpenGL • Depth buffer (ou Z-buffer) • stocke une valeur de profondeur pour chaque pixel • utiliser pour la suppression des parties cachées Les Buffers d’OpenGL • Stencil buffer • Permet de faire du clipping non rectangulaire en utilisant un buffer additionnel • Stocke des informations pour restreindre le dessin à certaines parties de l'écran (masquage de régions) • 1 Color Buffer 2 1 4 8 16 2 4 8 16 Application : ombres simples et reflets sur les miroirs. Depth Buffer • • Display Les Buffers d’OpenGL • Les Buffers d’OpenGL Accumulation buffer • • • accumule les données RGBA d'une série d'images afin d'obtenir une image finale composite à la fin de l'accumulation, le contenu du buffer est copié dans un color buffer pour l'affichage Utilisé pour l'antialiasing, simuler la profondeur de champ, calculer des ombres douces ou les effets de motion blur Mettre les pixels correspondants à la surface de réflexion à 1 dans le stencil buffer Copier dans le Color buffer uniquement les pixels pour lesquels le stencil buffer est égale à 1 • • Une fois que les fragments sont générés, plusieurs traitements interviennent pour déterminer comment ou si un fragment particulier sera dessiné comme pixel dans le framebuffer Les tests sont • scissor test • alpha test • stencil test • depth test • blending • dithering • opération logique 9 Les Buffers d’OpenGL • Scissor Test • • Les Buffers d’OpenGL Alpha Test et Blending • Restreint le dessin des fragments à une région rectangulaire de l'image (Clipping 2D rectangulaire) Ne nécessite pas de buffer particulier La 4ème composante d'une couleur RGBA est l'« alpha » ou opacité Deux applications principales de la composante alpha • • le blending (mélange) • • • Permet de combiner les composantes du fragment avec les valeurs courantes du framebuffer utilisé pour rendre les objets transparents le alpha test • • Permet de rejeter certains fragments en fonction de la valeur de leur composante alpha Utilise l'information qui se trouve dans le Color buffer • Les Buffers d’OpenGL • Les Buffers d’OpenGL Stencil Test • • • • le fragment n'est gardé que si la valeur du stencil du pixel franchit le test. S'il échoue, on peut laisser une trace spécifique dans le stencil plane. les fragments qui ne passe pas le « stencil test » ne seront pas dessinés Les valeurs du stencil sont mises à jour dépendant du passage des tests de stencil et de depth Depth Test • le fragment n'est gardé que s'il est accepté par le Z-buffer • • Le pixel courant est devant le contenu précédant du pixel. Il existe d’autres tests de profondeur affichage des valeurs d'un stencil buffer dans lequel ont été dessinés un carré et un triangle Les Buffers d’OpenGL • Dithering • • s'utilise quand la carte n'affiche qu'un petit nombre de couleurs (peu fréquent de nos jours) place des points de couleur côte à côte pour simuler un plus grand nombre de couleurs Les Buffers d’OpenGL • Opérations logiques • Permet de combiner les fragments avec des opérateurs logiques • and, or, xor, not, etc. Opération logique Pixel source & Pixel lu Pixel résultant Color Buffer 10 Les Buffers d’OpenGL • Accumulation Buffer • • • Les images générées dans les color buffers sont accumulées une à une dans l'accumulation buffer via des opérations arithmétiques et logiques +,x, and, etc. Quand l'accumulation est finie, le résultat est recopié dans le color buffer pour l'affichage Il n'y a pas de test lui correspondant Les Buffers d’OpenGL • La partie Test donne des réponses booléennes • Les autres opérations transformes le fragment • vrai → le test passe → le fragment est dessiné Framebuffer Stencil Buffer Depth Buffer Accum. Buffer Scissor Alpha Stencil Depth Test Test Test Test Mouvement • Selon la taille du tampon, le vider peut constituer une opérations lourde en temps d’exécution. • • Pour en bénéficier, il faut : 2. • Spécifier les valeurs à écrire dans chaque tampon à vider Effectuer le vidage • • void glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ); void glClearIndex( GLfloat index ); void glClearDepth( GLclampd depth ); void glClearStencil( GLint s); void glClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); Les paramètres correspondent aux valeurs de vidage Vider les Buffers • Pour procéder au vidage, utiliser : glClear(GLbitfield mask) • • avec comme valeur de « mask », un OU logique parmi : • GL_COLOR_BUFFER_BIT • GL_DEPTH_BUFFER_BIT • GL_STENCIL_BUFFER_BIT • GL_ACCUM_BUFFER_BIT Lors du vidage du tampon chromatique, tous les tampons chroma tiques activés en écriture sont vidés. Color Buffer Pour définir les valeurs de vidage des tampons, utiliser les commandes suivantes : • Certaines implémentations d'OpenGL permettent de vider plusieurs tampons en même temps. 1. Logical Operations Vider les Buffers • • Dithering Fragment Vider les Buffers • Blending Vider les Buffers void display(void) { // Initialiser le buffer de couleur avec la couleur noir glClearColor(0.0F,0.0F,0.0F,0.0F) ; glClear(GL_COLOR_BUFFER_BIT) ; glColor3f(1.0F,1.0F,1.0F) ; // Dessin du carre glBegin(GL_POLYGON) ; glVertex2f(-0.5F,-0.5F) ; glVertex2f(-0.5F,0.5F) ; glVertex2f(0.5F,0.5F) ; glVertex2f(0.5F,-0.5F) ; glEnd() ; glFlush() ; } 11 Masquer les Buffers • • Masquer les Buffers Avant que le pipe n'écrive les données dans les buffuer de couleur, de profondeur ou stencil, une opération de masquage est appliquée aux éléments du fragment. void display(void) { // Initialiser le buffer de couleur avec la couleur noir glClearColor(0.0F,0.0F,0.0F,0.0F) ; glClear(GL_COLOR_BUFFER_BIT) ; Les fonctions correspondant sont • glIndexMask (Bool state) • glColorMask (Bool state) • glDepthMask (Bool state) • glStencilMask (Bool state) // Primitives opaques... … glDepthMask( GL_FALSE ); //Tampon en lecture seul // Primitives transparente... … glDepthMask( GL_TRUE ); //Retour du tampon en mode lecture / écriture … glFlush() ; state : • • • GL_FALSE : buffers en lecture seulement GL_TRUE : buffers en lecture-écriture } Fonctions de manipulation directe des variables d'état Variables d'état • OpenGL est une machine d’états : state-machine. • • Ex : la couleur (que ce soit la couleur de 'fond' que la couleur de la primitive dessinée), la gestion de l'éclairage (activée ou désactivée, et combien de lumière sont activés), la gestion de la transparence (quelles fonctions pour calculer la transparence), les transformations de projection (perspective ou cavalière), la matrice active (projection, modélisation-visualisation ou texture), • • • • • Tous ces états peuvent être changés à n'importe quel moment. • Ceux-ci resteront actifs (utilisés à cette valeur) jusqu'à être changés (couleurs de tracé, matrices de transformation, activation du de l'élimination des parties cachées, ...). Les variables d’état possède des valeurs par défaut • • • Des instructions existent pour placer le système dans certains états. • • glEnable(GLenum pname) OpenGL possède un ensemble de valeurs (ou états) qui définissent un ensemble de comportements. Ex : la couleur de vidage du buffer de couleur est par défaut le noir (glClearColor(0.0, 0.0, 0.0, 0.0)) ou encore la lumière est par défaut désactivé (glDisable(GL_LIGHTING)). Chaque fois que le dessin d'un objet est demandé, l'ensemble de ces variables définit la manière avec laquelle l'objet est dessiné. • Activation d'une variable d'état booléenne pname: variable d'état à activer Exemples : • glEnable(GL_LIGHTING) -> activation de la gestion des lumières et des matériaux • glEnable(GL_DEPTH_TEST) -> activation de l'élimination des parties cachées glDisable(GLenum pname) • • Inhibition d'une variable d'état booléenne pname: variable d'état à désactiver L'ensemble de ces variables d'états constitue l’environnement OpenGL. Fonctions de manipulation directe des variables d'état • Consultation partielle des variables d'états • • Fonctions de manipulation directe des variables d'état • glGetBooleanv(GLenum pname,GLboolean *param) glGetIntegerv(GLenum pname,GLinteger *param) • • glGetFloatv(GLenum pname,GLfloat *param) • glGetDoublev(GLenum pname,GLdouble *param) • • pname: variable d'état consultée param: résultat (pointeur si une seule valeur, tableau si plusieur s valeurs) • GLboolean glIsEnabled(GLenum pname) • Consultation de variables d'états booléennes • pname: variable d'état consultée glPushAttrib(GLbitfield mask) • Sauvegarde de variables d'état par empilement dans une pile • mask: variables d'état à sauvegarder glPopAttrib() • Restauration de variables d'état par dépilement 12 Pile d’Attributs (stack attribute) Mask • • • • • • • • • • • • • • • • GL_ACCUM_BUFFER_BIT GL_ALL_ATTRIB_BITS GL_COLOR_BUFFER_BIT GL_CURRENT_BIT GL_DEPTH_BUFFER_BIT GL_ENABLE_BIT GL_EVAL_BIT GL_FOG_BIT GL_HINT_BIT GL_LIGHTING_BIT GL_LINE_BIT GL_LIST_BIT GL_PIXEL_MODE_BIT GL_POINT_BIT GL_POLYGON_BIT GL_POLYGON_STIPPLE_BIT Attribute Group accum-buffer color-buffer current depth-buffer enable eval fog hint lighting line list pixel point polygon polygon-stipple Fonctions de manipulation directe des variables d'état void initGL(void) { glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightModelfv(GL_AMBIENT, LAmbientValue); glLightfv(GL_LIGHT0, GL_POSITION, Lposition1); glLightfv(GL_LIGHT0, GL_AMBIENT, LAmbientValue); glLightfv(GL_LIGHT0, GL_DIFFUSE, LDiffuseValue); glLightfv(GL_LIGHT0, GL_SPECULAR, LSpecularValue); glShadeModel(GL_SMOOTH); glDepthFunc(GL_LEQUAL); glEnable(GL_CULL_FACE); } Fonctions de manipulation directe des variables d'état void display(void) { glClearColor(0.0F,0.0F,0.0F,0.0F) ; glClear(GL_COLOR_BUFFER_BIT) ; Instructions de base d'OpenGL glColor3f(1.0F,0.0F,0.0F) ; // Primitives 1 // Sommet 1 // Sommet 2 // … // Primitives 2 … // Primitives 3 … } glColor3f(0.0F,0.0F,1.0F) ; // Primitives 4 … glFlush() ; Sommets, lignes et polygones • • • Sommets, lignes et polygones Sommet : Ensemble de trois coordonnées représentant une position dans l'espace • OpenGL travaille en coordonnées homogènes. Ligne : Segment rectiligne entre deux sommets • Polygone : Surface délimitée par une boucle fermée de lignes • Par définition, un polygone OpenGL ne se recoupe pas et n'a pas de trou. • Si on veut représenter un polygone ne vérifiant pas ces conditions, on devra le subdiviser en un ensemble de polygones convenables. • GLU propose des fonctions pour gérer les polygones spéciaux. • Les polygones OpenGL ne doivent pas forcément être plans. • En revanche, le résultat à l'affichage n'est pas déterministe en cas de non planarité. • Déclaration d’une position • glVertex{234}{sifd}[v](TYPE coords) ; • Coords : coordonnées de la position Cette fonction sert uniquement à la déclaration de sommets au sein d'une primitive graphique. 13 Sommets, lignes et polygones • Déclaration d'une primitive graphique • • • Primitives géométriques • glBegin • GL_POINTS GL_LINES • GL_LINE_STRIP • GL_LINE_LOOP • GL_TRIANGLES • GL_TRIANGLE_STRIP • GL_TRIANGLE_FAN • GL_QUADS • GL_QUAD_STRIP • GL_POLYGON glEnd () Une primitive graphique est constituée d'un ensemble de sommets. • Elle est créée par la réalisation successive des instructions glVertex permettant la définition des positions de ses sommets. • La primitive est délimitée au début et à la fin par : void glBegin(GLenum mode) ; • et Mode : GL_POINTS, GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP, GL_POLYGO N, GL_QUADS, GL_QUAD_STRIP, GL_TRIANGLES, GL_TRIANGLE_STRIP ou GL _TRIANGLE_FAN void glEnd(void) ; Type de primitive graphique (GLenum mode) Annonce le début d’une série de sommets 3D. La nature des primitives générées varie en fonction du mode choisi : Sommets, lignes et polygones Création d'un polygone GL_POINTS GL_LINES GL_TRIANGLES GL_QUADS GL_LINE_STRIP GL_TRIANGLE_STRIP GL_QUAD_STRIP GL_LINE_LOOP GL_TRIANGLE_FAN GL_POLYGON Sommets, lignes et polygones • Un cercle : glBegin(GL_LINE_LOOP); for(float a=0 ; a<2*PI ; a+=0.1f) glVertex2f( cosf(a), sinf(a) ); glEnd(); glBegin(GL_POLYGON); glVertex2f(0.0F,0.0F) ; glVertex2f(2.0F,1.0F) ; glVertex2f(1.0F,3.0F) ; glVertex2f(5.0F,0.5F) ; glVertex2f(-.5F,2.0F) ; glVertex2f(1.5F,2.5F) ; glEnd() ; Sommets, lignes et polygones int c[8][3] = {{0,0,0},{1,0,0},{1,1,0},{0,1,0},{0,0,0},{1,0,0},{1,1,0},{0,1,0}}; glBegin(GL_QUAD_STRIP); glVertex3iv(c[0]); glVertex3iv(c[4]); glVertex3iv(c[1]); glVertex3iv(c[5]); glVertex3iv(c[2]); glVertex3iv(c[6]); glVertex3iv(c[3]); glVertex3iv(c[7]); glVertex3iv(c[0]); glVertex3iv(c[4]); glEnd(); glBegin(GL_QUADS); glVertex3iv(c[0]); glVertex3iv(c[1]); glVertex3iv(c[2]); glVertex3iv(c[3]); glVertex3iv(c[7]); glVertex3iv(c[6]); glVertex3iv(c[5]); glVertex3iv(c[4]); glEnd(); 14 Sommets, lignes et polygones • Sommets, lignes et polygones La définition d'une primitive peut faire appel à d'autres informations que ses seuls points. Celles-ci sont aussi renseignées via des appels à des fonctions particulières. glVertex*() Coordonnées du sommet glColor*() Couleur associée au sommet glIndex*() Indexe de la couleur glNormal*() Vecteur normal au sommet glEvalCoord*() Génération de coordonnées glCallList() Coordonnées textures glTextCoord*() Textura koordináták glEdgeFlag*() Contrôle du tracé d’un coté glMaterial*() Matériau associé au sommet glShadeModel(GL_SMOOTH); glBegin(GL_QUADS); glColor3f (1.0,0.0,0.0); glVertex3f(0.0,0.0,0.0); glColor3f (0.0,1.0,0.0); glVertex3f(1.0,0.0,0.0); glColor3f (0.0,0.0,1.0); glVertex3f(1.0,1.0,0.0); glColor3f (1.0,1.0,0.0); glVertex3f(0.0,1.0,0.0); glEnd(); Sommets, lignes et polygones glShadeModel(GL_FLAT); glBegin(GL_QUADS); glColor3f (1.0,0.0,0.0); glVertex3f(0.0,0.0,0.0); glColor3f (0.0,1.0,0.0); glVertex3f(1.0,0.0,0.0); glColor3f (0.0,0.0,1.0); glVertex3f(1.0,1.0,0.0); glColor3f (1.0,1.0,0.0); glVertex3f(0.0,1.0,0.0); glEnd(); Normales • • Pour le rendu des surfaces, une direction normale est associée à chaque sommet. La normale est propre aux sommets et pas aux polygones Sommets, lignes et polygones Déclaration d'un ensemble de facettes #define X .525731112119133606 #define Z .850650808352039932 • void glFrontFace (GLenum mode); • • Défini l’orientation des polygones. mode : GL_CCW (defaut), GL_CW static GLfloat vdata[12][3] = { {-X,0,Z},{X,0,Z},{-X,0,-Z}, {X,0,-Z},{0,Z,X},{0,Z,-X}, {0,-Z,X},{0,-Z,-X},{Z,X,0}, {-Z,X,0},{Z,-X,0},{-Z,-X,0}} ; static GLint t[20][3] = { {0,4,1},{0,9,4},{9,5,4},{4,5,8}, {4,8,1},{8,10,1},{8,3,10},{5,3,8}, {5,2,3},{2,7,3},{7,10,3},{7,6,10}, {7,11,6},{9,2,5},{0,1,6},{6,1,10}, {9,0,11},{9,11,2},{11,0,6}, {7,2,11}}; for ( i = 0 ; i < 20 ; i++ ) { • void glCullFace (GLenum mode); • glBegin(GL_TRIANGLES) ; glNormal3fv(&vdata[t[i][0]][0]); glVertex3fv(&vdata[t[i][0]][0]); • • Défini le culling. mode : GL_BACK, GL_FRONT, GL_FRONT_AND_BACK void glEnable / glDisable (GL_CULL_FACE); • Demande à OpenGL de (dés)activer le culling : élimination les faces. glNormal3fv(&vdata[t[i][1]][0]); glVertex3fv(&vdata[t[i][1]][0]); glNormal3fv(&vdata[t[i][2]][0]); glVertex3fv(&vdata[t[i][2]][0]); glEnd() ; } 15 Fonction diverses Fonction diverses • • void glPointSize(GLfloat size) ; • • Configure la taille de tracé (par défaut 1) des sommets. void glLineStipple(GLint facteur, GLushort motif) ; • Configure le motif de tracé des lignes. • Le motif est une série de 16 bits (poids faible à poids fort) où les 1 représentent des pixels allumés et des 0 des pixels non modifiés. • Le facteur (de 1 à 255) permet l'étirement du motif par multiplication • L'utilisation des motifs pour les segments est subordonnée à autorisation via un : glEnable(GL_LINE_STIPPLE). void glLineWidth(GLfloat width) ; • Configure la largeur de tracé (par défaut 1) des segments de ligne. Fonction diverses Fonction diverses • void display(void) { GLfloat y; // Storage for varying y coordinate GLint factor = 1; // Stippling factor GLushort pattern = 0x5555; // Stipple patter 0101010101010101 … // Enable Stippling glEnable(GL_LINE_STIPPLE); void glPolygonStipple(GLubyte *mask) ; • Définit le motif de remplissage courant des polygones. mask est un pointeur sur une bitmap de 32x32 pixels interprétée comm e un masque de bits (128 octets). Si un 1 est présent, le pixel est dessiné, sinon, il ne l'est pas. • L'utilisation des motifs pour les polygones est subordonnée à autorisation via un glEnable(GL_POLYGONE_STIPPLE). static GLubyte fly[] = { 0x03,0x80,0x01,0xC0, 0x06,0xC0,0x03,0x60, ... } // Step up Y axis 20 units at a time for(y = -90.0f; y < 90.0f; y += 20.0f) { glEnable(GL_POLYGON_STIPPLE); glPolygonStipple(fly); // Reset the repeat factor and pattern glLineStipple(factor,pattern); glBegin(GL_POLYGON) ; glColor3f(0.0F,0.0F,1.0F) ; glVertex3f(-7.0F,4.0F,0.0F) ; glVertex3f(-3.0F,7.0F,0.0F) ; glVertex3f(5.0F,8.0F,0.0F) ; glVertex3f(8.0F,-1.0F,0.0F) ; glVertex3f(2.0F,-4.0F,0.0F) ; glVertex3f(-1.0F,-8.0F,0.0F) ; glEnd() ; // Draw the line glBegin(GL_LINES); glVertex2f(-80.0f, y); glVertex2f(80.0f, y); glEnd(); } factor++; } Fonction diverses • void glPolygonMode(GLenum face, GLenum mode) ; • Configure le dessin des faces avant et arrières des polygones. face peut être GL_FRONT, GL_BACK ou GL_FRONT_AND_BAC K. mode peut être GL_POINT, GL_LINE ou GL_FILL pour un d essin des sommets, en fil de fer ou avec remplissage. Déclaration d'un ensemble de facettes • • Utilisation fréquente de surfaces polygonales (ensembles de facettes adjacentes) pour modéliser des objets complexes. Recommandations • Conserver constante l'orientation des polygones • Eviter les facettes non triangulaires • Trouver un bon équilibre entre le nombre de polygones et la vitesse et la qualité d'affichage • Multiplier le nombre de polygones sur la silhouette des objets • Éviter des intersections en T 16 Modèles complexes Mode direct • Un maillage c'est: • Une liste de sommets attribués • Une liste de faces (triangulaires) • un triangle = indices des trois sommets typedef struct sommet_s { GLfloat position [3]; GLfloat normale [3]; GLubyte couleur [4]; GLfloat texcoord [2]; }sommet_t; sommet_t sommets[nbrSommets]; • Une liste de faces (triangulaires) • un triangle = indices des trois sommets GLuint faces[3][nbrFaces]; Mode direct • Vertex array En mode direct #define Num 12500 // Nombre de sommets glBegin(GL_TRIANGLES); for(size_t i=0; i<nbrFaces; ++i) for(short j=0; j<3; ++j) { //Création des tableaux : sommets, couleurs, coordonnées de texture static GLint sommets[]={ 25,56,65, … 87,98, 25}; glNormal3fv (sommets[faces[j][i]].normale); glColor3ubv (sommets[faces[j][i]].couleur); glTexCoord2fv(sommets[faces[j][i]].texcoord); glVertex3fv (sommets[faces[j][i]].position); static GLfloat couleurs[]={ 1.0, 0.1,0.5, … ,0.4,0.4,0.8}; } GlEnd; • static GLfloat texture[]={ 0.1,0.8, … 0.5,0.9 } En pratique le mode direct n'est jamais utilisé (et va être supprimé)! • préférer les vertex array Vertex array Vertex array //Activation des tableaux : sommets, couleurs, coordonnées de texture glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); • //Déclarer à OpenGL les tableaux où sont stockés les sommets, couleurs, coordonnées de texture glVertexPointer(3, GL_INT, 0, sommets); glColorPointer(3, GL_FLOAT, 0, couleurs); glTexCoordPointer(2, GL_FLOAT, 0, texture); //Construit une séquence de primitives géométriques contenant les éléments des tableaux activés glDrawArrays(GL_TRIANGLES, 0, Num); //Désactivation des tableaux glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); • glEnableClientState (GLenum mode) Active un tableau parmi les 6 possibles : • GL_VERTEX_ARRAY • GL_NORMAL_ARRAY • GL_COLOR_ARRAY / GL_INDEX_ARRAY • GL_TEXTURE_COORD_ARRAY • GL_EDGE_FLAG_ARRAY glDisableClientState(GLenum mode) Désactive le tableau indiqué par « mode » 17 Vertex array • • Les listes d’affichage glVertexPointer (size, type, stride, ptr) size : nombre de coordonnées type : types de données stride : nbre d'octets entre le début de deux données ptr : pointeur sur le tableau de données Déclare le tableau où sont stockés les sommets : • glNormalPointer • glColorPointer • glIndexPointer • glTexCoordPointer • glEdgeFlagPointer • • • • glDrawArrays(GLenum mode, GLint premier, GLsizei nombre) construit une séquence de primitives géométriques contenant les éléments des tableaux activés, de « premier » à « premier + nombre – 1 ». Le type de primitive géométrique est indiqué par mode de la même manière que dans glBegin() • Une liste d'affichage est une suite de commandes OpenGL stockées pour une utilisation future. Les commandes d'une liste d'affichage sont les mêmes que les commandes d'affichage immédiat (mode direct). Quand une liste d'affichage est invoquée, les commandes qu'elle contient sont exécutées dans l'ordre où elles ont été stockées. Les commandes sont non seulement compilées dans la liste d'affichage, mais peuvent aussi être exécutées immédiatement pour obtenir un affichage Les listes d'affichages sont des macros et, à ce titre, ne peuvent pas être modifiées ou paramétrées à part en la détruisant et en la redéfinissant. Les listes d’affichage #define CERCLE 1 void cercle() { GLint i ; GLfloat cosinus,sinus ; glBegin(GL_POLYGON) ; for ( i = 0 ; i < 100 ; i++ ) { cosinus = cos(i*2*PI/100.0); sinus = sin(i*2*PI/100.0); glVertex2f(cosinus,sinus) ; } glEnd() ; } void cercle() { GLint i ; GLfloat cosinus,sinus ; glNewList(CERCLE,GL_COMPILE) ; glBegin(GL_POLYGON) ; for ( i = 0 ; i < 100 ; i++ ) { cosinus = cos(i*2*PI/100.0); sinus = sin(i*2*PI/100.0); glVertex2f(cosinus,sinus) ; } glEnd() ; glEndList() ; } glCallList(CERCLE) ; Les listes d’affichage • glNewList(GLuint list, GLenum mode); • Début d’une liste glGenLists (Glsizei range) ; • • • Les listes d’affichage • générer une suite de nouveaux numéros de liste L’utilisation d’une liste d’affichage permet : • • Une bonne organisation des données une amélioration de la performance : • • retourne GL_TRUE si le numéro est déjà utilisé • Appel et exécute une liste d'affichage • • • glDleteLists (Gluint list, Glsizei range) ; • Efface une suite de listes GL_COMPILE : la liste d'affichage est compilé et prêt à être utilisée. le s instructions ne sont pas exécutées lors de l'enregistrement. GL_COMPILE_AND_EXECUTE : les instructions que vous entrez dans l a liste sont enregistrées et exécutées immédiatement. Fin de la liste glCallList(listName) • variable de type entier non-signé qui contient l'indice de la liste précéd emment récupérer avec la commande glGenList(...). glEndList(); • • mode : mode de compilation. • glIsList (Gluint list) ; • • • • • list : index de la liste. • Les listes d’affichage • • • définition d’une géométrie qui a besoin d’être affichée à plusieurs reprises dans un programme définition d’une série de transformations (déplacements, mise à l ’échelle, etc…) qui ont besoin d’être appliquées à plusieurs reprises source lumineuse, propriétés des matériaux et modèles d ’illumination : définition de matériaux et de conditions d’illumination dans des listes d’affichage pour accélérer le rendu d’une scène dans un modèle client-serveur les listes d ’affichage sont gérées par le serveur d’où une réduction du coût de transmission des données à travers le réseau une liste d ’affichage peut être mémorisée dans une mémoire dédiée ou sous forme optimisée plus compatible avec le matériel graphique. texture et patrons de remplissage: l’image de la texture est placée dans une mémoire dédiée alors la conversion de format est effectuée lors de la compilation de la liste d’affichage. formats de données: le format spécifié n’est pas toujours compatible avec le matériel graphique. Lors de la compilation d’une liste d’affichage OpenGL transforme les données dans une représenta tion compatible avec le matériel graphique d’où un gain significatif dans la vitesse d’affichage. L'inconvénient principal des listes d'affichage est qu'elles peuvent occuper beaucoup de place en mémoire. 18 Visualisation sous OpenGL x y z w Visualisation sous OpenGL Modelview Matrix Sommets exprimés dans le repère local de l'objet (3D) Projection Matrix Sommets exprimés dans le repère de la caméra normalisé (3D) Sommets exprimés dans le repère de la caméra (3D) Visualisation sous OpenGL Transformations de modélisation Repère objet Illumination (Shading) Repère scène Perspective Division Viewport Transformation u v Coordonnées écran (entier entre [0..w] , 2D) Coordonnées écran normalisées (réel entre [-1..1] , 2D) Visualisation sous OpenGL Processus de visualisation Quatre transformations successives utilisées au cours du processus de création d'une image: Transformation de modélisation (Model) • Permet de créer la scène à afficher par création, placement et orientation des objets qui la composent. • Transformations d’affichage Transformation de visualisation (View) • Permet de fixer la position et l'orientation de la caméra de visualisation. • Clipping Repère caméra Transformation écran (Projection) Pixelisation (Rasterization) Transformation de projection (Projection) • Permet de fixer les caractéristiques optiques de la caméra de visualisation (type de projection, ouverture, ...). • Repère caméra normalisé (NDC) Transformation d'affichage (Viewport) • Permet de fixer la taille et la position de l'image sur la fenêtre d'affichage. • Espace écran Visibilité / Affichage Les matrices sous OpenGL Choix de la transformation de travail • a11 a12 a 21 a22 a31 a32 0 0 a13 a14 a23 a24 a33 a34 0 1 Forme théorique a11 void glMatrixMode(GLenum mode); • mode : transformation sur laquelle les transformations géométriques à venir vont être composées de manière incrémentale : • • • GL_MODELVIEW : Positionne et oriente les objets ou la caméra GL_PROJECTION : Projette les objets de la scène sur le plan image. Pour réaliser un affichage, glMatrixMode est généralement appelé successivement une fois sur chacun des deux paramètres de manière à établir les matrices modelview et projection. a21 a31 0 a12 0 a11 a21 a31 1 Sous OpenGL 19 Transformations d'utilité générale • • • void glLoadIdentity(void); • Affecte la transformation courante avec la transformation identité. void glLoadMatrix{f d}(const TYPE *m); • Affecte la transformation courante avec la transformation caractérisée mathématiquement par la matrice m (16 valeurs en coordonnées homogènes). Transformation de modélisation void glMultMatrix{f d}(const TYPE *m); • Compose la transformation courante par la transformation de matrice m (16 valeurs en coordonnées homogènes). Transformation de modélisation Transformation de modélisation Y • void glTranslate{f d}(TYPE x,TYPE y,TYPE z); • • X Important : • Compose la transformation courante par la rotation d'angle a degrés autour de l'axe (dx,dy,dz) passant par l'origine. • X void glScale{f d}(TYPE rx,TYPE ry,TYPE rz); • • Y void glRotate{f d}(TYPE a,TYPE dx,TYPE dy,TYPE dz); • • Compose la transformation courante par la translation de vecteur (x,y,z). La multiplication n’est pas commutative il faut lire les opérations effectuées sur l’objet dans l’ordre inverse de leur apparition dans le code (propriétés du produit matriciel) Y Compose la matrice courante par la transformation compositi on des affinités d'axe x, y et z, de rapports respectifs rx, ry et rz selon ces axes. X Transformation de modélisation /* matrice de transformation */ glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glTranslatef(0, 5, 0); glRotatef(45, 1, 0, 0); /* objet qui subira la transformation*/ dessineBoite(); 1 0 0 Transformation de modélisation /* matrice de transformation */ glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glRotatef(45, 1, 0, 0); glTranslatef(0, 5, 0); /* objet qui subira la transformation*/ dessineBoite(); Z 1 0 0 1 0 0 0 0 1 0 0 0 0 1 T T.R R Y 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 R R R.T Y T T X Z X 20 Description hiérarchique d’un objet Description hiérarchique d’un objet Segment_2 H_S2 Segment_1 H_S1 O_S2 /oX O_S1 /oX H_B Base O_B /oY Description hiérarchique d’un objet Description hiérarchique d’un objet glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glRotate(O_B, 0.0, 1.0, 0.0); base(); base() { glBegin(GL_TRIANGLES); … GlEnd; } Segement_1&2() { glBegin(GL_TRIANGLES); … GlEnd; } Description hiérarchique d’un objet glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glRotate(O_B, 0.0, 1.0, 0.0); base(); glTranslate(0.0, H_B, 0.0); glRotate(O_S1, 1.0, 0.0, 0.0); Segment_1(); Description hiérarchique d’un objet glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glRotate(O_B, 0.0, 1.0, 0.0); base(); glTranslate(0.0, H_B, 0.0); glRotate(O_S1, 1.0, 0.0, 0.0); Segment_1(); glTranslate(0.0, H_S1, 0.0); glRotate(O_S2, 1.0, 0.0, 0.0); Segment_2(); 21 Description hiérarchique d’un objet Description hiérarchique d’un objet • • • Description hiérarchique d’un objet OpenGL dispose d’une pile de matrices de modélisation • Description hiérarchique d’un objet complexe • Permet d’appliquer la même transformation à un assemblage glPushMatrix () Enregistre la matrice actuelle (du mode actuel) et prépare un nouveau contexte (avec la même matrice). glPopMatrix () Restaure le contexte précédent. Description hiérarchique d’un objet glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glTranslate3f(x,y,0); glRotatef(θ1,0,0,1); DrawBody(); 2 4 5 1 3 1 y y x Description hiérarchique d’un objet 1 x Description hiérarchique d’un objet glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glTranslate3f(x,y,0); glRotatef(θ1,0,0,1); DrawBody(); glPushMatrix(); glTranslate3f(0,7,0); DrawHead(); glPopMatrix(); 2 1 y x y glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glTranslate3f(x,y,0); glRotatef(θ1,0,0,1); DrawBody(); glPushMatrix(); glTranslate3f(0,7,0); DrawHead(); glPopMatrix(); glPushMatrix(); glTranslate(2.5,5.5,0); glRotatef(θ2,0,0,1); DrawUArm(); glPopMatrix(); x 22 Description hiérarchique d’un objet 2 1 y x 3 Description hiérarchique d’un objet glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glTranslate3f(x,y,0); glRotatef(θ1,0,0,1); DrawBody(); glPushMatrix(); glTranslate3f(0,7,0); DrawHead(); glPopMatrix(); glPushMatrix(); glTranslate(2.5,5.5,0); glRotatef(θ2,0,0,1); DrawUArm(); glTranslate(0,-3.5,0); glRotatef(θ3,0,0,1); DrawLArm(); glPopMatrix(); 2 4 5 1 3 y x Description hiérarchique d’un objet glMatrixMode (GL_MODELVIEW); glLoadIdentity() ; glTranslate3f(x,y,0); glRotatef(θ1,0,0,1); DrawBody(); glPushMatrix(); glTranslate3f(0,7,0); DrawHead(); glPopMatrix(); glPushMatrix(); glTranslate(2.5,5.5,0); glRotatef(θ2,0,0,1); DrawUArm(); glTranslate(0,-3.5,0); glRotatef(θ3,0,0,1); DrawLArm(); glPopMatrix(); ... (draw other arm) Description hiérarchique d’un objet Transformation de visualisation • glMatrixMode (GL_MODELVIEW) • la matrice active doit être la matrice de modélisation • • • Transformation de visualisation • GL_MODELVIEW : modélisation & vision Position relative de la caméra par rapport à la scène Les transformations de visualisation et de modélisation n'en forment qu'une pour OpenGL (transformation modelview). Multiplier la matrice courante par une matrice de transformation du repère scène vers le repère caméra y y x z x z 23 Transformation de visualisation Transformation de visualisation Y • Configuration initiale de la caméra • Position : Origine du repère global • Orientation : -z Positionner et orienter la caméra void gluLookAt( GLdouble eX, GLdouble eY, GLdouble eZ, GLdouble cX, GLdouble cY, GLdouble cZ, GLdouble uX, GLdouble uY, GLdouble uZ); X y • x z • • x .e Dans la pratique, gluLookAt place et oriente la scène devant la caméra de telle manière que la caméra semble placée et orientée selon les paramètres d'entête. gluLookAt est une fonction de la bibliothèque GLU Deux styles de navigation: • Pilote • Polaire (tourner autour d'un objet) Transformation de visualisation Transformation de visualisation • .c z [eX, eY, eZ] : Position de la caméra [cX, cY, cZ] : Point visé (centre de l’objet observé) [uX, uY, uZ] : Vecteur qui nous informe de la direction du haut de la caméra. (par défaut : 0.0,1.0,0.0) z glMatrixMode(GL_MODELVIEW); glLoadIdentity( ); glTranslatef(-50.0, 0.0, -100.0); glRotatef(-90.0, 0.0, 1.0, 0.0); Scene(); u y gluLookAt(10.0,15.0,10.0,3.0,5.0,-2.0,0.0,1.0,0.0) • • • place la caméra en position (10.0,15.0,10.0), l'oriente pour qu'elle vise le point (3.0,5.0,-2.0) et visualisera la direction (0.0,1.0,0.0) de telle manière qu'elle apparaisse verticale dans la fenêtre de visualisation. gluLookAt(0, 0, 4, 1, 0, 0, 0, 1, 0) gluLookAt(0, 0, 4, 0, 0, 0, 0, 1, 0) • gluLookAt(10.0,15.0,10.0,3.0,5.0,-2.0,1.0,0.0,0.0) gluLookAt(0, 0, 4, -1, 0, 0, 0, 1, 0) Transformation de projection • Les Matrices de PROJECTION du MODELVIEW peuvent être modifiées indépendamment pour permettre une indépendance des scènes modélisées vis à vis des caractéristiques de la « caméra » de visualisation. • Manipulation de la matrice de projection • L’étape de projection consiste à définir : • Transformation de projection • • glMatrixMode( GL_PROJECTION ); Les paramètres optiques de projection : focale Le volume de visualisation : clipping Plans de projection Volume de visualisation Focale 24 Transformation de projection Transformation de projection left • void glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); Projection perspective • • • • Transformation de projection glFrustum(); N'est pas trés intuitive • bottom right zFar Sommet : l'origine O Orientée selon l'axe –z Plan supérieur défini par la diagonale (left, bottom,- zNear) & (right, top,-zNear). zNear et zFar doivent avoir une valeur positive et respecter zNear < zFar car il s'agit de distances à l'origine selon l'axe -z. Transformation de projection aspect • w fovY Projection orthographique h zNear zFar Compose la transformation courante par la transformation de projection en perspective de volume de visualisation défini par la pyramide tronquée : • • • • • • zNear zNear et zFar sont les distances entre l'origine et les plans de clipping proche (- zNear en z) et éloignés (-zFar en z). • void gluPerspective( GLdouble fovY, O GLdouble aspect, GLdouble zNear, GLdouble zFar); O Compose la transformation courante par la transformation de projection en perspective de volume de visualisation défini par la pyramide tronquée • • top Sommet : l'origine O Orientée selon l'axe –z Possédant l'angle fovY comme angle d'ouverture verticale, L’ « aspect » ratio (rapport largeur(w)/hauteur(h)) Les plans de clipping proche et éloignés - zNear et - zFar. zNear et zFar doivent avoir une valeur positive et respecter zNear < zFar car il s'agit de distances à l'origine selon l'axe -z. Transformation de projection void glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); left Transformations de projection glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0,1.5,50.0,100.0); top O glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //Dessin scène// zNear bottom right zFar • • Compose la transformation courante par la transformation de projection orthographique selon l'axe -z et définie par le volume de visualisation parallélépipèdique (left, bottom, right, top,- zNear,- zFar). zNear et zFar peuvent être positifs ou négatifs mais doivent respecter zNear < zFar. • Configure une caméra de visualisation en perspective • • • • • avec un angle d'ouverture verticale de 40.0°, un angle d'ouverture horizontale de 40.0*1.5 = 60.0°, un plan de clipping qui élimine tous les objets ou morceaux d'objet situés en z > -50.0 un plan de clipping qui élimine tous les objets ou morceaux d'objets situés en z < -100.0. Ces valeurs sont considérées dans le repère global. 25 Transformation d'affichage • Définit le rectangle de pixels dans la fenêtre d'affichage dans lequel l'image calculée sera affichée. Exo Opengl Transformation d'affichage y x height width • void glViewport(GLint x, GLint y, GLsizei width, GLsizei height); • Transformation d'affichage • • Par défaut le viewport a la taille de la fenêtre Le ratio du viewport doit être le même que celui du volume de vision, sinon déformations Utilisation de toute la surface de la fenêtre d'affichage Utilisation d'une partie seulement de la fenêtre d'affichage Visualisation en OpenGL void reshape( int w, int h ) { glViewport( 0, 0, (GLsizei) w, (GLsizei) h ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 65.0, (GLdouble) w / h,1.0, 100.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); gluLookAt( 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); } Fonction indépendante de la matrice de PROJECTION et du MODELVIEW Transformation d'affichage • La transformation d'affichage peut s'exprimer sous forme matricielle float v[16] = { width*0.5f, 0, 0, x+0.5f*width, 0, height*0.5f, 0, y+0.5f*height, 0, 0, 0.5f, 0.5f, 0, 0, 0, 1}; Visualisation en OpenGL void reshape( intw, inth ) { glViewport( 0, 0, (GLsizei) w, (GLsizei) h ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 65.0, (GLdouble) w/h,1.0, 100.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.0, 0.0, -5.0 ); } 26 Visualisation en OpenGL Visualisation en OpenGL perspective et vue « pilote » perspective et vue « polaire » void reshape( int w, int h ) { glViewport( 0, 0, (GLsizei) w, (GLsizei) h ); void reshape( int w, int h ) { glViewport( 0, 0, (GLsizei) w, (GLsizei) h ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 60.0, (GLfloat) w / h, 1.0, 100.0 ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); gluPerspective( 60.0, (GLfloat) w / h, 1.0, 100.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glRotated(-twist, 0.0, 0.0, 1.0); glRotated(-incidence, 1.0, 0.0, 0.0); glRotated(azimuth, 0.0, 0.0, 1.0); glTranslated(0.0, 0.0, -distance); } glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslated(-x, -y, -z); glRotated(roll, 0.0, 0.0, 1.0); glRotated(pitch, 0.0, 1.0, 0.0); glRotated(heading, 1.0, 0.0, 0.0); } Visualisation en OpenGL /*1 : Transformation de modélisation seulement (Model) */ /*2 : Transformation visualisation & modélisation () */ /*3 : Transformation de projection */ /*4 : Transformation d'affichage */ void reshape(int w, int h) { glViewport(0,0,w,h); /*4*/ glMatrixMode(GL_PROJECTION); /*3*/ glLoadIdentity(); /*3*/ glFrustum(-1.0,1.0, -1.0,1.0, 1.5,20.); /*3*/ glMatrixMode(GL_MODELVIEW); /*2*/ glLoadIdentity(); /*2*/ gluLookAt( 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ); /*2*/ } void display(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0,1.0,1.0); glTranslatef(0.0,0.0,-5.0); glRotatef(rotx,1.0,0.0,0.0); glRotatef(roty,0.0,1.0,0.0); glRotatef(rotz,0.0,0.0,1.0); glScalef(1.0,2.0,3.0); auxWireCube(1.0); glFlush(); } Clipping Additionnel /*1*/ /*1*/ /*1*/ /*1*/ /*1*/ Plans de clipping additionnels • En plus des plans de clipping définis par le Frustum de visualisation, OpenGL propose 6 plans additionnels • • • Accélération des calculs : scènes complexes Réduire l’espace de projection Vue en coupes d’objets 3D O Plans de clipping additionnels • void glClipPlane(GLenum plane,const GLdouble *equ); • • Définit un plan de clipping 3D. equ: tableau de quatre coefficients (a,b,c,d) qui définissent l'équation du plan de clipping : ax+by+cz+d = 0. • Tous les points supérieur ou égale à cette équation de plan seront rendus. • plane: GL_CLIP_PLANEi avec i compris entre 0 et 5. • glClipPlane(plane,equ) est à utiliser en association avec glEnable(plane) et glDisab le(plane) pour autoriser/interdire la gestion du plan de clipping plane. 27 Plans de clipping additionnels void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); … glEnable(GL_CLIP_PLANE0); glEnable(GL_CLIP_PLANE1); Élimination des parties cachées double equ0[] = { 1.1,1.2,0.9,0.8 } ; double equ1[] = { -1.3,1.8,1.5,2.5 } ; glClipPlane(GL_CLIP_PLANE0,equ0); glClipPlane(GL_CLIP_PLANE1,equ1); Sphere(); glDisable(GL_CLIP_PLANE0); glDisable(GL_CLIP_PLANE1); … } Élimination des parties cachées Élimination des parties cachées • L’algorithme d’élimination des parties cachées sous openGL et le Z-Buffer (Tampon de profondeur) • Deux zones mémoire sont concernées : • tampon couleur (Color Buffer) • tampon profondeur (Z Buffer) • • 3 composantes : R, G, B Valeurs : [0.0,1.0] par défaut initialisé à 1.0 tampon couleur tampon profondeur Étapes d’activation et d’utilisation du Z-Buffer Élimination des parties cachées 0,7,5 Initialiser le tableau PROF à -∞ Initialiser de tableau COUL à la couleur de fond Pour chaque objet o à représenter Pour chaque pixel p=(x,y) de o Calculer la profondeur z de p=(x,y) ; Si z > PROF(x,y) alors 5 5 PROF(x,y) = z ; COUL(x,y) = couleur(o,x,y) ; 5 5 5 5 Finsi 5 5 Finpour 4 5 Finpour 3 4 2 3 6,7,5 Intégration du Z-Buffer 0,6,7 glutInitDisplayMode Sélection de la valeur d’effacement Z-buffer glClearDepth 0,1,5 5 5 5 5 5 5 4 5 5 5 5 7 6 5 5 5 5 7 6 5 5 7 Initialisation du Z-Buffer 0,1,2 5 5,1,7 glClear Sélection du critère du Z-Buffer glDepthFunc Activation du test du Z-Buffer glEnable(GL_DEPTH_TEST) Tests 28 Élimination des parties cachées Élimination des parties cachées void glClearDepth( GLclampd depth ) ; • Spécifie la valeur de profondeur utilisée quand le buffer de profondeur est effacé: La valeur initiale est 1. • • Intégration du Z-Buffer avec GLUT : • void glutInitDisplayMode ( unsigned int mode ); • glClearDepth(1.0); mode : • • • • GLUT_RGBA / GLUT_INDEX GLUT_STENCIL … GLUT_DEPTH void glClear(unsigned intmask); • Effacer le Buffer par la valeur indiquée/défaut • Intmask : • • • glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); • • GL_COLOR_BUFFER_BIT GL_STENCIL_BUFFER_BIT ... GL_DEPTH_BUFFER_BIT glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); Élimination des parties cachées • void glDepthFunc(GLenum fonction) • • Indique la fonction de comparaison de profondeurs à utiliser Fonction : indique les conditions dans lesquelles le pixel sera dessiné • GL_NEVER • • Le pixel est dessiné si son z est plus petit que le z du tampon. • GL_EQUAL • GL_LEQUAL • GL_GREATER • GL_NOTEQUAL • • • • Le pixel est dessiné si son z est égal au z du tampon. Le pixel est dessiné si son z est inférieur ou égal au z du tampon. Activation / désactivation du test de profondeur • • glEnable(GL_DEPTH_TEST) glDisable(GL_DEPTH_TEST) Le pixel est dessiné si son z est différent du z du tampon. GL_GEQUAL • GL_ALWAYS • • Le pixel est dessiné si son z est supérieur au z du tampon. • • • Le pixel n'est jamais dessiné. GL_LESS • • Élimination des parties cachées Le pixel est dessiné si son z est supérieur ou égal au z du tampon. Le pixel est toujours dessiné La valeur par défaut est GL_LESS. Initialement, le test de profondeur est désactivé. Élimination des parties cachées … glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); … static int mode = 0 ; // Variable manipulée //par clavier void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); … if ( mode ) glEnable(GL_DEPTH_TEST) ; glBegin(GL_TRIANGLES) ; glColor4fv(couleurBleu()) ; glVertex3f(1.0F,-1.5F,-0.5F) ; glVertex3f(1.5F,1.5F,0.5F) ; glVertex3f(-1.1F,-0.2F,0.2F) ; glColor4fv(couleurVert()) ; glVertex3f(-1.0F,-1.5F,-0.5F) ; glVertex3f(-1.5F,1.5F,0.5F) ; glVertex3f(0.5F,-0.5F,0.2F) ; glColor4fv(couleurRouge()) ; glVertex3f(-1.2F,1.3F,-0.5F) ; glVertex3f(1.2F,1.1F,0.5F) ; glVertex3f(0.1F,-0.5F,0.3F) ; glEnd() ; …. glDisable(GL_DEPTH_TEST) ; Eclairement et ombrage } 29 Eclairement et ombrage • 3 Composantes : • • • Sources lumineuses : conditions d’éclairage Matériaux des objets : réactions à la lumière Modèle d’ombrage : Plat, Gouraud, Phong. Sources lumineuses • • • • Sources lumineuses • • • • • GL_AMBIENT : composante ambiante GL_DIFFUSE : composante diffuse GL_SPECULAR : composante spéculaire « valeurs » : composantes (R,G,B,A) Utiliser les versions vectorielles de glLight : glLight{if}v Sources lumineuses • • • • • propriete : propriété manipulée • composantes : ambiante, diffuse, spéculaire • position • direction • etc. valeur ou valeurs : valeur(s) attribuée à « propriete » (scalaire/vecteur) Sources lumineuses void init(){ … GLfloat lum_ambiante [] = { 0.0, 0.0, 0.0, 1.0); /* {Black, 1.0}; */ GLfloat lum_diffuse [] = { 1.0, 0.0, 0.0, 1.0); /* {Red, 1.0}; */ GLfloat lum_speculaire [] = { 0.0, 0.0, 1.0, 1.0); /* {Blue, 1.0}; */ … glLightfv ( GL_LIGHT0, GL_AMBIENT, lum_ambiante); glLightfv ( GL_LIGHT0, GL_DIFFUSE, lum_diffuse); glLightfv ( GL_LIGHT0, GL_SPECULAR, lum_speculaire); … } Sources lumineuses Position • • light : Identifiant de la source de lumière • GL_LIGHTi avec i < GL_MAX_LIGHTS. • OpenGL dispose de 8 lumières (GL_LIGHT0, ..., GL_LIGHT7) 3 composantes : ambiante, diffuse, spéculaire « propriete » : • • Définition des propriétés d'une source de lumière void glLight{if}[v](GLenum light, GLenum propriete, TYPE[*] valeur[s]); contrôle la position et le type de lumière « propriete » : GL_POSITION « valeurs » : position (x,y,z,w) Source omni-directionnelle (w≠0) : émission isotropique Source directionnelle (w=0) : direction (-x,-y,-z) Défaut : (0,0,1,0) void init(){ … GLfloat lum_ambiante [] = { 0.0, 0.0, 0.0, 1.0); GLfloat lum_diffuse [] = { 1.0, 0.0, 0.0, 1.0); GLfloat lum_speculaire [] = { 0.0, 0.0, 1.0, 1.0); GLfloat lightposition[4]={1.0f,1.0f,1.0f,1.0f}; /* {Black, 1.0}; */ /* {Red, 1.0}; */ /* {Blue, 1.0}; */ … glLightfv ( GL_LIGHT0, GL_AMBIENT, lum_ambiante); glLightfv ( GL_LIGHT0, GL_DIFFUSE, lum_diffuse); glLightfv ( GL_LIGHT0, GL_SPECULAR, lum_speculaire); glLightfv( GL_LIGHT0, GL_POSITION, lightposition); … } 30 Sources lumineuses Sources lumineuses Atténuation de la source lumineuse • Variation de l'intensité en fonction de la distance • Comme pour les objets, les sources de lumière sont sujettes aux matrices de transformations. • plus un objet est éloigné d'une source de lumière, moins il est éclairé par cette dernière : Ke : GL_CONSTANT_ATTENUATION • kl : GL_LINEAR_ATTENUATION • La position et la direction sont affectées par la matrice MODELVIEW courante et stockées en coordonnées caméra. • • • Défaut : 1.0. f Défaut : 0.0. • kq : GL_QUADRATIC_ATTENUATION • d distance par rapport à la lumière • Défaut : 0.0. d Objet Sources lumineuses void init(){ … GLfloat lum_ambiante [] = { 0.0, 0.0, 0.0, 1.0); /* {Black, 1.0}; */ GLfloat lum_diffuse [] = { 1.0, 0.0, 0.0, 1.0); /* {Red, 1.0}; */ GLfloat lum_speculaire [] = { 0.0, 0.0, 1.0, 1.0); /* {Blue, 1.0}; */ GLfloat lightposition[4]={1.0f,1.0f,1.0f,1.0f}; GLfloat LinearFacort = 1.0f ; … glLightfv ( GL_LIGHT0, GL_AMBIENT, lum_ambiante); glLightfv ( GL_LIGHT0, GL_DIFFUSE, lum_diffuse); glLightfv ( GL_LIGHT0, GL_SPECULAR, lum_speculaire); glLightfv( GL_LIGHT0, GL_POSITION, lightposition); glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,LinearFacort); … Sources lumineuses • Définition d'un cône lumineux : Spot • Direction: • « propriete » : GL_SPOT_DIRECTION • « valeurs » : (x,y,z) • Défaut : (0,0,1) • • • • • • GL_SPOT_CUTOFF Angle d'ouverture : « propriete » : GL_SPOT_CUTOFF « valeurs » : • • } Valeurs : [0,90] et 180 Défaut : 180 (degrés) Fonction d'atténuation « propriete » : GL_SPOT_EXPONENT « valeurs » : • • Valeurs : [0,128] Défaut : 0 5 Sources lumineuses void myinit(void) { … static float o0 = 10.0F; static float o1 = 10.0F; GLfloat rouge[] = { 1.0F,0.0F,0.0F,1.0F }; GLfloat vert[] = { 0.0F,1.0F,0.0F,1.0F }; GLfloat l_pos0[] = { 1.0F,0.0F,2.0F,1.0F }; GLfloat l_dir0[] = { -1.0F,0.0F,-2.0F,1.0F }; GLfloat l_pos1[] = { -1.0F,0.0F,2.0F,1.0F }; GLfloat l_dir1[] = { 1.0F,0.0F,-2.0F,1.0F }; … … glLightfv(GL_LIGHT0,GL_DIFFUSE,rouge); glLightfv(GL_LIGHT0,GL_POSITION,l_pos0); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,l_dir0); glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,o0); glLightfv(GL_LIGHT1,GL_DIFFUSE,vert); glLightfv(GL_LIGHT1,GL_POSITION,l_pos1); glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,l_dir1); glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,o1); … } 1 k e kl d k q d 2 10 20 30 128 Sources lumineuses • Activation/désactivation de l’éclairage • • glEnable/Disable(GL_LIGHTING); Activation/désactivation d’une source de lumière i • glEnable/Disable(GL_LIGHTi); • • i< GL_MAX_LIGHTS Huit sources de lumières au maximum 31 Sources lumineuses Sources lumineuses Paramètres généraux • • … glLightfv(GL_LIGHT0,GL_DIFFUSE,rouge); glLightfv(GL_LIGHT0,GL_POSITION,l_pos0); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,l_dir0); glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,o0); void myinit(void) { … static float o0 = 10.0F; static float o1 = 10.0F; GLfloat rouge[] = { 1.0F,0.0F,0.0F,1.0F }; GLfloat vert[] = { 0.0F,1.0F,0.0F,1.0F }; GLfloat l_pos0[] = { 1.0F,0.0F,2.0F,1.0F }; GLfloat l_dir0[] = { -1.0F,0.0F,-2.0F,1.0F }; GLfloat l_pos1[] = { -1.0F,0.0F,2.0F,1.0F }; GLfloat l_dir1[] = { 1.0F,0.0F,-2.0F,1.0F }; … glLightfv(GL_LIGHT1,GL_DIFFUSE,vert); glLightfv(GL_LIGHT1,GL_POSITION,l_pos1); glLightfv(GL_LIGHT1,GL_SPOT_DIRECTION,l_dir1); glLightf(GL_LIGHT1,GL_SPOT_CUTOFF,o1); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); … } Non spécifiques à chaque source void glLightModel{if }[v] (GLenum propriete, TYPE valeurs); Lumière ambiante globale : Spécifier l’intensité de la lumière ambiante globale « propriete » : GL_LIGHT_MODEL_AMBIENT « valeurs » : composantes RGBA • • • • Défaut : (0.2,0.2,0.2,1.0) Gestion des faces arrières : Choisir entre l'éclairage d'un seul côté ou des deux côtés « propriete » : GL_LIGHT_MODEL_TWO_SIDE « valeurs » : GL_TRUE, GL_FALSE • • • • Défaut : GL_FALSE Calcul des reflets spéculaires : Spécifie comment les angles pour la réflexion spéculaire seront calculés. « propriete » : GL_LIGHT_MODEL_LOCAL_VIEWER « valeurs » : GL_TRUE, GL_FALSE • • • • Défaut : GL_FALSE Pile d’Attributs • Les variables d’états peuvent être sauvegardées et restaurées dans une pile avec les commandes glPushAttrib(mask) et glPopAttrib(mask) • • • Les matériaux Dans le cas des sources d’éclairage : mask : GL_LIGHTING_BIT GL_LIGHTING_BIT fait référence aux variables d’états concer nant l’éclairage : couleur des matériaux, intensité émise, amb iente, diffuse et spéculaire de la lumière, une liste de sources actives, la direction des spots lumineux. Matériaux • Sous OpenGL pour définir le comportement d'un objet vis-à-vis d'une couleur RVB, il suffit de dire quel pourcentage de chaque composante est réfléchi • • • • un matériau avec les pourcentages (R=100%, V=50%, B=0%) (R=1, V=0.5, B=0) éclairé avec une lumière blanche (R=1,V=1,B=1) réfléchi un rayon de couleur (R=1,V=0.5,B=0) : orange il absorbe le reste (théoriquement) (R=0,V=0.5,B=1) Matériaux • • • • • un matériau avec les pourcentages (R=100%, V=50%, B=0%) (R=1, V=0.5, B=0) éclairé avec une lumière bleu (R=0,V=0,B=1) réfléchi un rayon de couleur noir (R=0,V=0,B=0) il absorbe tout (théoriquement) (R=1,V=1,B=1) : absence de lumière. Un matériau • pourcentage réfléchi de chaque composante de couleur 32 Matériaux • • Matériaux La spécification d'un matériau pour un objet se fait par l'intermédiaire de 5 paramètres : • La couleur diffuse : couleur “de base” • La couleur ambiante : couleur des zones non éclairées directement • La couleur émise : couleur émise par le matériau • La couleur spéculaire : couleur des reflets spéculaires • Le coefficient de brillance : coefficient de brillance Combinaison lumières & matériaux • ambient = (ambient Materiau) * (ambient Lumière) • diffuse = (diffuse Materiau) * (diffuse Lumière) • … Composante ambiante Composante diffuse Composante spéculaire Matériaux Matériaux void glMaterial{if}[v](GLenum face, GLenum propriete, TYPE[*] valeur[s]) • « face » : faces où la matière doit être appliquée : face avant, face arrière ou les deux côtés de la face. • • • • GL_FRONT GL_BACK GL_FRONT_AND_BACK GL_AMBIENT :0.1,0.1,0.3,1.0 GL_SPECULAR : 0.0 ,0.5,0.5,1.0 GL_SHININESS : 100 GL_DIFFUSE : 0.3,0.1,0.5,1.0 GL_AMBIENT :0.5,0.1,0.3,1.0 « propriete » : composantes du matériau • GL_AMBIENT • GL_DIFFUSE • • • • GL_SPECULAR : 0.4 ,0.4,0.4,1.0 GL_SHININESS : 100 Défaut :(1.0, 1.0, 1.0, 1.0) Défaut :(0.0, 0.0, 0.0, 1.0) Défaut ( 0.0, 0.0, 0.0, 1.0) GL_SHININESS: • GL_DIFFUSE : 0.5,0.1,0.3,1.0 GL_AMBIENT :0.3,0.1,0.5,1.0 GL_EMMISSION • • Défaut : (0.2, 0.2, 0.2, 1.0) GL_SPECULAR • • GL_DIFFUSE : 0.0,0.0,0.9,1.0 GL_SPECULAR : 0.4 ,0.4,0.4,1.0 Défaut : 0.0 => [0, 128] GL_SHININESS : 10 « valeur[s] » : valeur (scalaire ou vecteur (R, G, B & A)) de la propriété « propriete » manipulée Matériaux Matériaux void myinit(void) { … GLfloat noir[] = { 0.0F,0.0F,0.0F,1.0F }; GLfloat blanc[] = { 1.0F,1.0F,1.0F,1.0F }; GLfloat grismoyen[] = { 0.5F,0.5F,0.5F,1.0F }; GLfloat position[] = {0.0F,3.0F,2.0F,0.0F}; GLfloat local_view[] = {0.0F}; … glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); … glLightfv(GL_LIGHT0,GL_AMBIENT, noir); glLightfv(GL_LIGHT0,GL_DIFFUSE, blanc); glLightfv(GL_LIGHT0,GL_POSITION,position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, grismoyen); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER,local_view); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); … } 33 Matériaux void display(void) { … GLfloat no_mat[] = { 0.0F,0.0F,0.0F,1.0F }; GLfloat mat_ambient[] = { 0.7F,0.7F,0.7F,1.0F }; GLfloat mat_diffuse[] = { 0.1F,0.5F,0.8F,1.0F }; GLfloat mat_specular[] = { 1.0F,1.0F,1.0F,1.0F }; GLfloat no_shininess[] = { 0.0F }; GLfloat low_shininess[] = { 5.0F }; GLfloat high_shininess[] = { 100.0F }; GLfloat mat_emission[] = {0.3F,0.2F,0.2F,0.0F}; … Matériaux glPushMatrix(); glTranslatef(-3.75F,3.0F,0.0F); glMaterialfv(GL_FRONT,GL_AMBIENT,no_mat); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,no_mat); glMaterialfv(GL_FRONT,GL_SHININESS,no_shininess); glMaterialfv(GL_FRONT,GL_EMISSION,no_mat); Sphere(); glPopMatrix(); glPushMatrix(); glTranslatef(1.25F,3.0F,0.0F); glMaterialfv(GL_FRONT,GL_AMBIENT,no_mat); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_SHININESS,high_shininess); glMaterialfv(GL_FRONT,GL_EMISSION,no_mat); Sphere(); glPopMatrix(); glPushMatrix(); glTranslatef(-1.25F,3.0F,0.0F); glMaterialfv(GL_FRONT,GL_AMBIENT,no_mat); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_SHININESS,low_shininess); glMaterialfv(GL_FRONT,GL_EMISSION,no_mat); Sphere(); glPopMatrix(); glPushMatrix(); glTranslatef(3.75F,3.0F,0.0F); glMaterialfv(GL_FRONT,GL_AMBIENT,no_mat); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,no_mat); glMaterialfv(GL_FRONT,GL_SHININESS,no_shininess); glMaterialfv(GL_FRONT,GL_EMISSION,mat_emission); Sphere(); glPopMatrix(); Matériaux Matériaux void glColorMaterial (GLenum face, GLenum mode) • Autre méthode : « Color Material » • Pour simplifier la définition d’un matériau • • • spécifier la propriété active que vous souhaitez modifier avec glColor*() • Utiliser la couleur des sommets comme une des composantes du matériau Piste les valeurs spécifiées par glColor* et met à jour automatique ment les composantes correspondantes du matériau « face » : faces où la propriété doit être appliquée : face avant, face arrière ou les deux côtés de la face. • • • • GL_FRONT GL_BACK GL_FRONT_AND_BACK « mode » propriété manipulée • • • • GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_EMMISSION glEnable/Disable(GL_COLOR_MATERIAL) • Matériaux Activer/Desactiver l'état GL_COLOR_MATERIAL Matériaux Composante ambiante void display(void) { … glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_DIFFUSE); glColor3f(1.0, 1.0, 0.0); // Composante diffuse glBegin(GL_QUADS); ... glEnd(); glColor3f(1.0, 0.0, 1.0); // Composante diffuse glBegin(GL_TRIANGLES); ... glEnd(); glDisable(GL_COLOR_MATERIAL); … } GLfloat fMatAmbient[4] = {a,b,c,1}; Glfloat fMatDiffuse[4] = {1,1,1,1}; GLfloat fMatSpecular[4] = {1,1,1,1}; glMaterialfv(GL_FRONT, GL_AMBIENT, fMatAmbient); glMaterialfv(GL_FRONT, GL_DIFFUSE, fMatDiffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, fMatSpecular); glColor3f(a,b,c); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT); Composantes ambiante et diffuse Glfloat fMatAmbient[4] = {a,b,c,1}; Glfloat fMatDiffuse[4] = {a,b,c,1}; Glfloat fMatSpecular[4] = {1,1,1,1}; glMaterialfv(GL_FRONT, GL_AMBIENT, fMatAmbient); glMaterialfv(GL_FRONT, GL_DIFFUSE, fMatDiffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, fMatSpecular); glColor3f(a,b,c); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); Composante spéculaire Glfloat fMatAmbient[4] = {1,1,1,1}; Glfloat fMatDiffuse[4] = {1,1,1,1}; Glfloat fMatSpecular[4] = {a,b,c,1}; glMaterialfv(GL_FRONT, GL_AMBIENT, fMatAmbient); glMaterialfv(GL_FRONT, GL_DIFFUSE, fMatDiffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, fMatSpecular); glColor3f(a,b,c); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT,GL_SPECULAR); 34 Matériaux Le modèle d’illumination complet Remarques • • • • • Inconvénients • Ne permet pas de rendre des surfaces de tous types (plastique brillant, bois mat, verre translucide…) • • • • • Les matériaux ne sont actifs que quand l'illumination de la scène est activée glColor court-circuite GL_AMBIENT et GL_DIFFUSE lorsque GL_LIGHTING est activé Pour utilisé glColor on doit désactiver GL_LIGHTING Pas de réflexions Pas de transparence La définition d’un matériau en termes de composante ambiante, diffuse, émissive et spé culaire est un modèle pour représenter une réalité plus complexe. Toutes les équations mathématiques sont exécutées pour chaque composante R V B & A La couleur résultante en un sommet est : L'émission du matériau au sommet + Interaction entre la composante ambiante de la lumière globale et la composante ambiante du matériau + Interaction entre les composantes diffuses et spéculaires des lumières auxiliaires (i) et les composantes diffuses et spéculaires du matériau Avantages • La commande glColor est plus rapide que glMaterial • Permet de faire varier les composantes couleurs par sommet CR,V,B,A = ∑i (Kd*Ld*(N∙L) Modèle d’ombrage • • • Modèle d’éclairement • définit l’intensité lumineuse en un sommet Modèle d’ombrage • définit les méthodes de calcul et d’interpolation utilisés pour calculer la couleur des pixels d’une surface Exemples de modèles d’éclairement : diffus , spéculaire, etc. Exemples de modèles d’ombrage • Plat : une normale (donc une couleur) par primitive • Gouraud : interpolation linéaire des intensités • Phong : interpolation linéaire des normales Modèle d’ombrage • Pour des raisons d'efficacité, OpenGL ne calcule pas la couleur de chaque pixel d'un polygone : Deux méthode sont implémentées : • Chaque polygone est remplit avec une couleur unie : • Modèle d’ombrage • void glShadeModel (GLenum mode) Spécifie le modèle d’ombrage • « mode » • mode « Flat » 1 normale pour 1 facette (flat) • • 100 facettes Éclairage Blinn-Phong, diffus, etc. sur la facette. GL_SMOOTH (par défaut) • Pour un polygone donné, la couleur de chacun des sommets est calculée, la couleur à l’intérieur du polygone est ensuite interpolée entre les couleurs : algorithme de Gouraud ou encore : 28 facettes GL_FLAT • • • + Ka*La + + Ks*Ls*(N∙H)n)i)R,V,B,A Modèle d’ombrage • • (Ke 1 normale pour 1 sommet • • Éclairage Blinn-Phong, diffus, etc. sur chaque sommet. Interpolation bilinéaire sur la surface du triangle. mode « Smooth » GL_FLAT GL_SMOOTH 35 Modèle d’ombrage Modèle d’ombrage void display(void) { … if ( mode ) // variable manipulée par clavier glShadeModel(GL_SMOOTH); else glShadeModel(GL_FLAT); … glPushMatrix() ; glTranslatef(-0.8F,0.0F,0.0F); glRotatef(50.0F,1.0F,1.0F,1.0F); glutSolidSphere(1.1,faces,faces) ; glPopMatrix() ; Et l’ombrage Phong dans tout ça ! • • 1 normale pour 1 pixel • • glPushMatrix() ; glTranslatef(0.9F,-0.9F,0.0F); glRotatef(-70.0F,1.0F,0.0F,0.0F); glutSolidCone(0.9,2.0,faces,faces) ; glPopMatrix() ; • Normale interpolée le long du triangle. Éclairage Blinn-Phong sur chaque pixel. Nécessite la mise en œuvre d’un pixel shader. glPushMatrix() glTranslatef(0.8F,0.1F,0.0F); glRotatef(-70.0F,1.0F,0.0F,0.0F); glutSolidTorus(0.35,0.8,faces,faces) ; glPopMatrix() ; … } La transparence : Blending • • • Le terme exact est alpha-blending. Cette technique permet de réaliser des effets de transparence Utilisation : • • La transparence : Blending Simulation de transparence / translucidité Rendu non rectangulaire de texture : « billboarding » • • Texture de diffusion : couche R,G,B Texture de transparente : couche alpha Le Blending Pipeline pixel Application Fromatage pixel Le Blending Pipeline sommet Assemblage de sommets Opérations sommets Operations pixel • Assemblage de primtives Opérations primitives Rasterisation pixel Mémoire texture Caractéristiques : • • Combinaison entre source (fragment) et destination (framebuffer) Fonction de combinaison paramétrable par les composantes alpha Rasterisation primitives Operations fragment Framebuffer Display 36 Le Blending Le Blending Fonctionnement : Fragment • Framebuffer : t Framebuffer : t-1 • • • Equation Blending Blended Pixel Fragment (src) Les facteurs d’opacité • Facteurs source : (Asr, Asg, Asb, Asa) • Facteurs destination : (Adr, Adg, Adb, Ada) Valeurs source (fragment) : (Sr , Sg , Sb , Sa) Valeurs destination (framebuffer) : (Dr , Dg , Db , Da) Valeurs finales après mélange : • Dr = Asr * Sr + Adr * Dr • Dg = Asg * Sg + Adg * Dg • Db = Asb * Sb + Adb * Db • Da = Asa * Sa + Ada * Da Framebuffer Pixel (dst) dst src (Asr*Sr+Adr*Dr, Asg*Sg+Adg*Dg , Asb*Sb+Adb*Db, Asa*Sa+Ada*Da) Le Blending Le Blending Valeurs possibles de « src » et « dst » : • void glBlendFunc (GLenum src, GLenum dst) Fonction de contrôle du mélange • Spécifie les paramètres définissant le blending. • Ils déterminent comment la couleur du fragment en cours (source) sera combinée avec celle déjà présente en mémoire (destination). Constante Facteur concerné Valeur du facteur de blending GL_ZERO source ou destination (0, 0, 0, 0) GL_ONE source ou destination (1, 1, 1, 1) GL_DST_COLOR source GL_ONE_MINUS_DST_COLOR • « src » ou « dst » : • facteurs d’opacité attribués à la source ou à la destination • différente combinaisons en fonction de l'effet recherché (Dr, Dg, Db, Da) destination GL_SRC_COLOR source GL_ONE_MINUS_SRC_COLOR (Sr, Sg, Sb, Sa) (1, 1, 1, 1) - (Dr, Dg, Db, Da) destination (1, 1, 1, 1) - (Sr, Sg, Sb, Sa) GL_SRC_ALPHA source ou destination (Asr, Asg, Asb, Asa) GL_ONE_MINUS_SRC_ALPHA source ou destination (1, 1, 1, 1) - (Asr, Asg, Asb, Asa) GL_DST_ALPHA source ou destination (Adr, Adg, Adb, Ada) GL_ONE_MINUS_DST_ALPHA source destination (1, 1, 1, 1) - (Adr, Adg, Adb, Ada) GL_SRC_ALPHA_SATURATE source (f, f, f, 1) avec f = min(Asx, 1 - Adx) Le Blending Le Blending • (GL_ONE, GL_ZERO) (GL_SRC_ALPHA, GL_ONE) (GL_ONE, GL_ONE) (GL_ONE, GL_ONE_MINUS_DST_ALPHA) Activation/Désactivation du Blending • glEnable / glDisable (GL_BLEND) (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 37 Le Blending Void Draw{ … glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); …. Le Blending glBegin(GL_QUADS); glColor4f(0.8,0.2,0.2,0.7); glVertex3f(-1, 1, 1); glVertex3f(-1,-1, 1); glVertex3f( 1,-1, 1); glVertex3f( 1, 1, 1); glColor4f(0.2,0.8,0.2,0.5); glVertex3f(-1, 1, 1.5); glVertex3f(-1,-1, 1.5); glVertex3f( 1,-1, 1.5); glVertex3f( 1, 1, 1.5); GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA glColor4f(0.2,0.2,0.8,0.3); glVertex3f(-1, 1, 2); glVertex3f(-1,-1, 2); glVertex3f( 1,-1, 2); glVertex3f( 1, 1, 2); glEnd; … } GL_DST_COLOR, GL_SRC_COLOR GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_COLOR Le Blending GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA GL_DST_COLOR, GL_SRC_ALPHA GL_ZERO, GL_ZERO Le Blending Blending avec des primitives en mouvement • • Contrôle de l'équation de mélange void glBlendEquation(GLenum equation) « equation » • GL_FUNC_ADD : • GL_FUNC_SUBTRACT : • GL_FUC_REVERSE_SUBTRACT : • GL_MIN : • GL_MAX : Dx Dx Dx Dx Dx • OpenGL calcul toujours la distance entre les yeux de l'utilisateur et la primitives à afficher. • si vous restituez une primitive opaque (A) devant une primitive transparente (T) alors OpenGL ne dessinera que la primitive Opaque du fait qu'elle cache la transparante. Z(A) < Z(T) : utiliser le Z-Buffer = Asx * Sx + Adx * Dx = Asx * Sx - Adx * Dx = - Asx * Sx + Adx * Dx = min(Sx, Dx) = max(Sx, Dx) • si la primitive transparente est situé devant celle opaque alors il ne faut pas que le tampon de profondeur supprime la primitive opaque car elle est visible à travers la transparente : il faudra désactiver le tampon de profondeur pendant la restitution de la primitive opaque . Z(T) < Z(A) : mélange entre intensités de T et de A • La démarche à suivre est la suivante • • commencer à dessiner toute les surfaces opaques pour le dessin des objets transparents, il faut activer le tampon de profondeur en lecture seule. Le Blending • Commande pour le contrôle du tampon de profondeur : glDepthMask(mode) • « mode » : • • GL_FALSE : Z-buffer en lecture seulement GL_TRUE : Z-buffer en lecture-écriture Le Blending // Primitives opaques... glDepthMask( GL_FALSE ); //Tampon en lecture seul // Primitives transparente... glDepthMask( GL_TRUE ); //Retour du tampon en mode lecture / écriture 38 Le Blending display() { draw_cube(); //objet opaque glEnable(GL_BLEND); glDepthMask(GL_FALSE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SOURCE_ALPHA); Textures draw_sphere(); //objet transparent glDepthMask(GL_TRUE); glDisable(GL_BLEND); } Textures Textures Texturage : Texture Mapping Utilisation • • • Simuler des matériaux complexes (bois, marbre, ...) • Augmente les détails sans augmenter la complexité géométrique • Possibilité de mieux filtrer les effets de détail • • Matériel efficace pour les polygones texturés Caractéristiques : • • • • Textures • Relief simulé Plaquage sur points, lignes, polygones Textures uni, bi ou tridimensionnelles Apparence directe ou combinée Définitions Une texture peut altérer plusieurs propriétés : • • • • • • couleur (composante diffuse) normale (bump map) géométrie (displacement map) réflexion (environment map) transparence (billboarding) etc. • • • Texture mapping : technique consistant à appliquer une texture sur une surface Texture map : texture apposée sur une surface Texel : élément de base d’une texture, analogue au pixel d’une image 39 Objectif Etapes Coordonnées paramétriques u Espace texture (2D) yo 1 (u,v) y 0 1 v • t xo zo x • s Coordonnées textures Coordonnées objets Coordonnées écran Espace Objet (3D) Transformation texture-surface Etapes de l'utilisation d'une texture: 1. Spécification de la texture 2. Spécification de la technique à utiliser pour appliquer la texture 3. Activer le texture mapping : autorisation du plaquage 4. Dessin de la scène au moyen des paramètres définis en (1) et (2) • Définir les coordonnées de textures pour chaque sommet du polygone sur lequel on veut plaquer la texture • « target » Spécifie l’action à réaliser sur la texture, tests, lecture, etc. • Valeurs : • • • • • • GL_TEXTURE_2D : les pixels sont lu et formatés pour être utilisés GL_PROXY_TEXTURE_2D : les pixels ne sont pas lu, un examen d’uniformité et de compatibilité/ma tériel est réalisé (utile pour des opérations futures) GL_TEXTURE_CUBE_MAP_POSITIVE_X : … … Spécification de la texture 1. void glTexImage2D ( GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid pixels) Textures • « components » • format interne : Il définit la façon dont on va représenter les texels de l’image • Il caractérise ce ce que l’on souhaite utiliser dans l’image de texture • Entier de 1 à 4 indiquant les composantes RGBA utilisées pour la modulation ou le mélange • Cette représentation peut être en mode • Pour afficher une texture, ce paramètre doit être à GL_TEXTURE_2D • « level » • • • Il est utilisé dans le cas de l’utilisation de niveau de détail différent d’une texture appelée Mipmap • • mipmapping technique avec laquelle on peut préciser différentes résolutions Ce paramètre sert à construire une mipmap lorsque l’on dispose de l’image à plusieurs niveaux de résolutions Il doit être à 0, si une seule résolution est utilisée. LOD 3 : 32x32 LOD 2 : 64x64 • R, G, B et A Luminance Ex : 1 -> rouge 2 -> R et A 3 -> R, V et B 4 -> R, V, B et A Valeurs : • • • LOD 1 : 128x128 (x,y) Textures Textures • Transformation écran (projection) Le mapping comprend donc deux étapes : • La texture est dans un premier temps plaquée sur la surface 3D de l’ob jet à couvrir • Le résultat est ensuite projeté sur l’écran par une transformation de pr ojection Le mapping se résume au final en une transformation d’un espace 2D (tex ture) à un espace 2 D (écran). • Pas de calculs géométrique 3D => donc ne passe pas par le pipe géométrique Textures • (xo,yo,zo) Espace écran (2D) • • GL_LUMINANCE (1) GL_LUMINANCE_ALPHA (2) GL_RGB (3) GL_RGBA (4) … LOD 0 :254x254 40 Textures Textures • « format » • • • • « width & height » • définissent la largeur et la hauteur de la matrice de l’image. • Ils doivent être de la forme 2n (+ 2 pour une bordure) • • Format externe de l’image de texture Il définit la façon de décrire les pixels (format). Valeurs : • • • • n doit être un entier • • • • « type » • « border » • Il définit la taille de la bordure. • Elle peut soit être nulle, soit être de taille un. • Il décrit le type de données rangées dans la matrice image. « Valeurs » • • • • • • • • GL_UNSIGNED_BYTE GL_BYTE, GL_BITMAP GL_UNSIGNED_SHORT GL_SHORT GL_UNSIGNED_INT GL_INTGL_FLOAT. « pixels » • Textures GL_RED GL_GREEN GL_ALPHA GL_RGBA GL_BGRA_EXT GL_LUMINANCE_ALPHA. … C’est le pointeur sur la matrice de données de l’image Textures Textures Mono et Tri-dimentionnelle glTextImage1D(~) && glTextImage3D(~) • Définition de textures 1D & 3D • Les texture à une dimension (1D) sont des textures 2D avec une hauteur de 1. • • • • Les texture 1D sont utilisées pour dessiner des bandes Les textures 3D sont surtout utilisé dans le domaine médical pour modéliser le résultat d'un IRM et av oir une suite de coupe de texture 2D (billboarding) Les textures 3D requièrent énormément de mémoire Pratiquement le paramétrage que glTextImage2D(~) • Autres fonctions de gestion des texures void glGenTextures (GLsizei n, GLuint *names) • Alloue et retourne « n » objets textures (identifiants) non encore utilisé pour les objets de texture dans le tableau « names » • Textures void glBindTexture(GLenum target, GLuint name) • « target » : GL_TEXTURE_2D, GL_TEXTURE_3D, GL_PROXY_TEXTURE_2D, etc. 1. la première fois qu'il est appelé avec une valeur names non nulle, un nouvel Objet-Texture est crée, et le nom names lui est attribué. void glDeleteTextures (GLsizei n, GLuint *names) Libère les « n » objets textures précisés dans le tableau « names » Textures /* Stockage des identifiants des textures */ int texture[1]; //la taille du tableau nombre de textures 2. Si elle appelée avec une valeur « name » déjà liée à une objet-Texture, cet objet devient actif • Indique la texture courante « name » présente sur le canal « target » • Toutes les instructions concernant les textures 2D (association d’une image, modification des paramètres, placage, coordonnées de texture,...) s’adresseront alors à « name » /* Structure de l'image : height, width, et data */ struct Image { unsigned long sizeX; unsigned long sizeY; char *data; }; 3. Si elle appelée avec la valeur zéro, OpenGL arrête d'utiliser des objets-textures et retourne à la texture par défaut, qui elle n'a pas de nom. typedef struct Image Image; 41 Textures Textures // Chargement de l’image et conversion en texture void LoadGLTextures() { // Chargement de la texutre Image *image1; image1 = (Image *) malloc(sizeof(Image)); ImageLoad("texture.bmp", image1); … // Création de la texture glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); … // chargeur d'image BMP, JPG, etc. int ImageLoad(char *filename, Image *image) { FILE *file; unsigned long size; // Taille de l'image en Byte … file = fopen(filename, "rb"); … fread(&image->sizeX, 4, 1, file); fread(&image->sizeY, 4, 1, file) size = image->sizeX * image->sizeY * 3; … image->data = (char *) malloc(size); fread(image->data, size, 1, file); … return 1; } // texture 2d, niveau de détail 0, 3 composantes (red, green, blue), //taille suivant x, taille suivant y, // bordure 0, données couleurs de type rgb, données de type unsigned byte, //les données. glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_R GB, GL_UNSIGNED_BYTE, image1->data); } Textures Spécification de la technique à utiliser pour appliquer la texture (paramétrage) • Gestion des bords • Filtrage (grossissement, reduction) • Interpolation • Etc. 2. Textures void glTexParameter{if}[v](GLenum target, GLenum pname, TYPE param) • • • Cette fonction spécifie la méthode à utiliser pour plaquer la texture courante. Permet de plaquer les textures de différentes manières suivant la fonction de transfert choisie entre l’image destination d’une texture et son image source Paramètres • « target » : canal concerné : GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEX TURE_3D, etc. • « pname » : paramètre à modifier • « param » : valeur attribuées à « pname » Textures Textures Filtrage • Gérer la différence d'échantillonnage texture(espace 3D)/ecran (espace 2D) • Après transformations les texels correspondent rarement avec les pixels. • A un pixel peut correspondre : • 1 Texel = plusieurs pixels (agrandissement) • • Réduction effet pavé. 1 Pixel = plusieurs texel (réduction) • perte d’information. P0(x,y,z) V0(x’,y’) Agrandissement V1(x’,y’) P1(x,y,z) Texture : texels Écran : pixels 42 Textures Textures • « pname » • GL_TEXTURE_MAG_FILTER • Sans filtrage0 • Solution théorique • Lorsque la surface à remplir est plus petite que l’image de texture (réduction) « param » • GL_NEAREST (Point sampling) • Coût élevé Avec filtrage Solution OpenGL • • Lorsque la surface à remplir est plus grande que l’image de texture (agrandissement) GL_TEXTURE_MIN_FILTER • Projection du pixel sur la texture & intégration de l'aire • • • • choisit le texel le plus près du centre du pixel GL_LINEAR (Bilinéaire) • • Un filtrage simple et surtout rapide fait une moyenne (pondérée) des 4 texel les plus près permet de «lisser» la perte d’information. GL_LINEAR GL_NEAREST Textures // Chargement de l’image et conversion en texture void LoadGLTextures() { // Chargement de la texutre Image *image1; image1 = (Image *) malloc(sizeof(Image)); ImageLoad("texture.bmp", image1); … // Création de la texture glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); … // Paramétrage du grossissement glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Paramétrage de la réduction glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); • D’autres techniques existent pour le filtrage : GL_TEXTURE_MIN_FILTER • Mimapping : niveaux de détail (LOD) • Trilinéaire : interpolation inter-LOD • anisotropique : prise en compte des effets d’angle (32 texels) // texture 2d, niveau de détail 0, 3 composantes (red, green, blue), //taille suivant x, taille suivant y, // bordure 0, données couleurs de type rgb, données de type unsigned byte, //les données. glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYT E, image1->data); } Textures Textures Mimapping : niveaux de détail (LOD) • Textures à différentes résolutions • Utilisées pour accélérer et améliorer le filtrage • Principe : 1. 2. Stocker l’image de texture à différents niveaux de résolution : l’image même, l’image de tailles divisées par 4, l’image de tailles divis ées par 16, et ainsi de suite jusqu’à ce que l’image soit de la dimension d’un pixel Pour déterminer les valeurs d’intensités pour un pixel, on peut : • • • • • • choisir l’image dans la mipmap dont les dimensions en pixels sont les plus proches de celles de la surface à remplir (GL_LINEAR_MIPMAP_N EAREST || GL_NEAREST_MIPMAP_NEAREST ) interpoler entre les deux images dans la mipmap dont les dimensions en pixels sont les plus proches de celles de la surface à remplir (GL_LI NEAR_MIPMAP_LINEAR || GL_NEAREST_MIPMAP_LINEAR ) et enfin choisir le texel le plus proche (GL_NEAREST_MIPMAP_NEAREST || GL_NEAREST_MIPMAP_LINEAR ), ou interpoler entre les 4 plus proches (GL_LINEAR_MIPMAP_NEAREST || GL_LINEAR_MIPMAP_LINEAR ), dans les images choisies de la mipmap GL_NEAREST_MIPMAP_LINEAR : interpolation des 4 points les plus proches du mipmap le plus proche GL_LINEAR_MIPMAP_LINEAR : interpolation des 4 points les plus proches dans l’interpolation des deux mipmaps les plus proche Images Résolution 2^(n-2 ) Possibilité d’utiliser la fonction glTexImage2D pour construire une mipmap en utilisant diff érentes valeurs du paramètre Level (mode manuel) void gluBuild2DMipmaps( GLenum target, /* action à réaliser sur la texture GL_TEXTURE_2D */ GLint internalFormat, /* format interne */ GLsizei w, GLsizei h, /* dimensions de l’image */ GLenum format, /* format de l’image */ GLenum type, /* type des donnees */ const GLvoid *texels); /* tableau de donnees */ • Fonction de la libraire glu qui construit une mipmap directement à partir de l’image initiale et qui, de plus, redimensionne automatiquement l’image si celle-ci n’a pas des dimensions puissances de 2 (mode automatique) Filtre Images Résolution 2^(n-1 ) 43 Textures Textures //paramètres de filtrage glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); ... // Définition manuelle d’un jeu de mipmaps glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, glTexImage2D(GL_TEXTURE_2D, 2, GL_RGB, glTexImage2D(GL_TEXTURE_2D, 3, GL_RGB, glTexImage2D(GL_TEXTURE_2D, 4, GL_RGB, glTexImage2D(GL_TEXTURE_2D, 5, GL_RGB, glTexImage2D(GL_TEXTURE_2D, 6, GL_RGB, ... 64, 64, 0, GL_RGB, GL_UNSIGNED_BYTE, texture0); 32, 32, 0, GL_RGB, GL_UNSIGNED_BYTE, texture1); 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, texture2); 8, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, texture3); 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, texture4); 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, texture5); 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, texture6); sans MIP-mapping Ou alors … glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR); //Génération automatique de mipmaps gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, 128, 128, GL_RGB, GL_UNSIGNED_BYTE, texture0); … avec MIP-mapping Textures Filtrage anisotropique • • Textures • Gestion des bords (pavtage) • La projection d'un pixel dans l'espace de la texture: • est assimilée à un carré (isotrope) • n'est pas un carré (anisotrope) ≠ méthodes de filtrage anisotrope Gestion des coordonnées textures en dehors de l’interval [0,1] • • • • • glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAniso); /* maxAniso >= 1.0f */ • • • OpenGL peut soit répéter soit clamper la texture « pname » = GL_TEXTURE_WRAP_{S T} « param » • GL_CLAMP : s = (s<0 ? 0 : (s > 1 ? 1 : s)) GL_REPEAT : répétition GL_MIRRORED_REPEAT 1 Mecanisme général qui définit le degré maximum d'anisotropie Degré d'anisotropie définit par objet texture Indépendant des fonctions de minification & magnification 0 1 Textures // Chargement de l’image et conversion en texture void LoadGLTextures() { // Chargement de la texutre Image *image1; image1 = (Image *) malloc(sizeof(Image)); ImageLoad("texture.bmp", image1); … // Création de la texture glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); … // Paramétrage du grossissement glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Paramétrage de la réduction glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Paramétrage des bords glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); Textures 3. Activer glEnable / glDisable (TYPE param) • Activation/Désactivation d’un canal « param » de texturing particulier • « param » • • • • //Specification de la texture glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->data); le texture mapping : autorisation du plaquage • • GL_TEXTURE_1D GL_TEXTURE_2D GL_TEXTURE_RECTANGLE GL_TEXTURE_3D GL_TEXTURE_CUBE Etc. } 44 Textures Textures // Chargement de l’image et conversion en texture void LoadGLTextures() { // Chargement de la texutre Image *image1; image1 = (Image *) malloc(sizeof(Image)); ImageLoad("texture.bmp", image1); … // Création de la texture glGenTextures(1, &texture[0]); glBindTexture(GL_TEXTURE_2D, texture[0]); … // Paramétrage du grossissement glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Paramétrage de la réduction glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 4.Définition • • • • // Paramétrage des bords glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); des coordonnées textures (texture mapping) Consiste à associer à chaque point affiché un texel (donne au point sa couleur) L’association se fait simplement en indiquant (ou en calculant) les coordonnées (s, t) du texel voulu sur la surface concernée En OpenGL, l’association se fait seulement aux sommets Lors du remplissage des polygones, chaque pixel est associé à un texel par interpolation des coordonnées de textures des sommets (calcul incrémental des coordonnées de texture lors de la rasterization) //Specification de la texture glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image1->data); // activation du texture glEnable(GL_TEXTURE_2D); } Modèles d’ombrage Interpolation suivant les arrêtes • y y2 y y2 S3 S gauche S 2 1 y2 y3 y2 y3 y3 Modèles d’ombrage • y y1 y y1 S3 S gauche S 2 1 y1 y3 y1 y3 ( x3 , y3 ), (s3 , t3 ) y Interpolation horizontale xg x S S droite1 x x d g x x S gauche g x x g d ( x3 , y3 ), (s3 , t3 ) y S gauche S droite y2 ( x2 , y2 ), (s2 , t2 ) ( x1 , y1 ), (s1 , t1 ) Textures • ( x2 , y2 ), (s2 , t2 ) xg x xd ( x1 , y1 ), (s1 , t1 ) Textures 1er méthode • Spécifier explicitement les coordonnées de textures pour chaque sommet void glTexCoord{1234}{sifd}[v] (TYPE[*] coords) • « coords » • prend les coordonnées de texture soit sous forme de valeurs, soit sous forme de tableau 45 Textures Textures glBegin(GL_POLYGON); glTexCoord2f(0,0); glVertex3f(V0); glTexCoord2f(1,0); glVertex3f(V1); glTexCoord2f(1,1); glVertex3f(V2) ; glTexCoord2f(0,1); glVertex3f(V3); glEnd( ); Textures glBegin(GL_POLYGON); glTexCoord2f(0.5,0.2); glVertex3f(V0); glTexCoord2f(1,0.3); glVertex3f(V1); glTexCoord2f(0.8,0.8); glVertex3f(V2); glTexCoord2f(0.5,1); glVertex3f(V3); glEnd( ); Textures Textures Texture i glTexCoord2f(…); glVertex3f(…); glTexCoord2f(…); glVertex3f(…); glTexCoord2f(…); glVertex3f(…); glTexCoord2f(…); glVertezx3f(…); Textures For (int i = 0; i < F_Max; i++) { glBegin(GL_POLYGON); glTexCoord2fv(V[i].t1); glVertex3fv(V[i].p1); glTexCoord2f(V[i].t2); glVertex3fv(V[i].p2); glTexCoord2fv(V[i].t3); glVertex3fv(V[i].p3); glTexCoord2fv(V[i].t4); glVertex3fv(V[i].p4); glEnd( ); } V[i].n1 V[i].p1 V[i].n4 V[i].p4 V[i].n2 V[i].p2 V[i].n3 V[i].p3 46 Textures Textures • 2ème méthode de génération de coordonnées de textures • Générées automatiquement les coordonnées : • Calculer automatiquement ces coordonnées par • Calculer automatiquement ces coordonnées par • • projection linéaire (plan mapping) projection sphérique (environment mapping) void glTexGen{ifd}[v](GLenum coord, GLenum pname, TYPE[*] param) • Fonction permettant de générer et d’appliquer automatiquement les coordonnées textures : • dispenser le concepteur de spécifier les coordonnées de texture des objets complexes • • effets de réflexions : environment mapping effets de contours : cartoon shading Textures • Textures « coord » • • • spécifie la direction d'application de la fonction Valeurs : • • GL_S GL_T Pour appliquer une texture de type bois, moquette, etc. GL_OBJECT_LINEAR • permet d’obtenir un plan de référence en coordonnées objet • • « pname » • • Définition du repère texture Valeurs : • • • • GL_OBJECT_LINEAR • GL_TEXTURE_GEN_MODE : permet d’utiliser des paramètres prédéfinis (voir « param ») GL_OBJECT_PLANE : permet de spécifier manuellement le repère local « OBJECT » dans « param » GL_EYE_PLANE : permet de spécifier manuellement le repère « EYE » dans « param » « param » • • Pour obtenir des lignes de contour dynamiques pour objet en mouvement GL_EYE_LINEAR • permet obtenir un plan de référence en coordonnées de l'oeil • Méthodes d’application de la texture (pour : GL_TEXTURE_GEN_MODE) Valeurs: • GL_OBJECT_LINEAR : • GL_EYE_LINEAR : • GL_SPHERE_MAP : • • • GL_EYE_LINEAR • interpolation linaire dans l’espace de l’objet (plane mapping) interpolation linaire dans l’espace de la caméra (plane mapping) placage d’une texture par projection sphérique la texture est fixe par rapport à l'objet la texture est appliqué en fonction de l'écran et non de l'objet Pour obtenir un effet de texture réfléchie GL_SPHERE_MAP • Permet de plaquer une texture fish-eye sur (texture d'environnement) l’objet par mapping sphérique • (reflet de l’environnement sur l’objet : environment mapping) GL_SPHERE_MAP Textures Activation de la génération automatique de texture (pour S & T) glEnable(GL_TEXTURE_GEN_S) glEnable(GL_TEXTURE_GEN_T) • • Après activation, les glTexCoord ne sont plus interprétés par OpenGL (les c oordonnées de texture seront automatiquement calculées en chacun des s ommets) Ne pas oublier de désactiver après le tracé par glDisable(GL_TEXTURE_GEN_S) glDisable(GL_TEXTURE_GEN_T) Textures glGenTextures(1, &tex_id ); glBindTexture(GL_TEXTURE_2D, tex_id); glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP) ; glEnable(GL_TEXTURE_GEN_S); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP) ; glEnable(GL_TEXTURE_GEN_T ); glEnable(GL_TEXTURE_2D); /* tracé de la géométrique*/ … glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); 47 Textures • • Comme pour les objets et la projection (GL_MODELVIEW & GL_PROJECTION ), on peut appliquer des matrices de transformations sur les textures : Pile de matrices texture Il faut se mettre dans le mode correspondant : glMatrixMode(GL_TEXTURE) • Toutes les instructions de matrices (glRotate, glTranslate, glPushMatrix,...) s’adresseront à l a pile de matrice de texture. • Toutes les coordonnées (s, t) subissent la matrice de texture courante (l’identité par défaut) • Ex : Textures glMatrixMode(GL_TEXTURE) ; glPushMatrix() ; glRotatef(45,0,0,1) ; draw_example1_quad() ; glPopMatrix() ; glMatrixMode(GL_MODELVIEW) ; glMatrixMode(GL_TEXTURE); glTranslatef(.......); ............ glMatrixMode(GL_MODELVIEW); 48 Textures • Textures Plane mapping dans le repère objet • double ps [4] = { 0 . 5 , 0 . 5 , 0 . 0 , 0 . 2 } ; double pt [4]={ −1 .0 ,1 .0 ,0 .0 ,0 .0 } ; glTexGendv (GL_S,GL_OBJECT_PLANE, ps ) ; glTexGendv (GL_T,GL_OBJECT_PLANE, pt ) ; Chaque glVertex dont les coordonnées sont (x, y, z,w) (dans le repè re local courant) est affecté avec la coordonnée de texture s : s = p1 . x + p2 . y + p3 . z + p4 . W • les coefficients ps = (p1, p2, p3, p4) sont spécifiés par : On peut interpréter ps et pt comme un changement de repère inverse par rapport au repère local glTexGenfv(GL_S,GL_OBJECT_PLANE,<float ps[4]>) • idem pour la coordonnée T avec GL_T Textures static p[4]={1.0, 0.0, 0.0, 0.0); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_OBJECT_PLANE, p); Textures • s = ps1x + ps2y + ps3z + ps4w s = p1 . x + p2 . y + p3 . z + p4 . W GL_S : object_linear GL_T : 1.0, 0.0, 0.0, 0.0 Plane mapping dans le repère eye • GL_S : object_linear GL_S : eye_linear GL_T : 1.0, 1.0, 1.0, 0.0 GL_T : 1.0, 0.0, 0.0, 0.0 • • Identique à plane mapping dans le repère objet, mais : (x, y, z ,w) sont les coordonnées du sommet dans le repère de l’oeil ( GL_EYE_LINEAR) ps est à interpréter dans le repère courant lors de l’appel à glT exGendv(GL_S,GL_EYE_PLANE,ps); idem pour la coordonnée T avec GL_T 49 Textures glBindTexture (GL_TEXTURE_2D, tex_id ) ; glTexGeni (GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR ); glEnable (GL_TEXTURE_GEN_S) ; glTexGeni (GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR ); glEnable (GL_TEXTURE_GEN_T) ; double ps [ 4 ] = { 1 , 0 , 0 . 0 , 0 } ; double pt [ 4 ] = { 0 . 0 , 1 . 0 , 0 . 0 , 0 . 0 } ; glTexGendv (GL_S,GL_EYE_PLANE, ps ) ; glTexGendv (GL_T,GL_EYE_PLANE, pt ) ; • • Textures • Environment mapping • Le calcul au sommet dépend principalement de l’angle entre la nor male N et le vecteur de vue V Observateur N V Texture d’environnement GL_EYE_LINEAR remplace GL_OBJECT_LINEAR GL_EYE_PLANE remplace GL_OBJECT_PLANE Surface réfléchissante Textures • Approche Blinn/Newell Textures • Approche Spherical Mapping Textures glGenTextures(1, &tex_id ); glBindTexture(GL_TEXTURE_2D, tex_id); glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP) ; glEnable(GL_TEXTURE_GEN_S); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP) ; glEnable(GL_TEXTURE_GEN_T ); glEnable(GL_TEXTURE_2D); /* tracé de la géométrique*/ … glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); 50 Textures Textures Cartes cubiques (Cube mapping) • Extension des textures d’environnement Calcul de réflexion basé sur le cube (et non une «approximation» d e sphère) Un "cube map" est composé de six textures carrées de même taille , représentant un cube centré à l’origine Chaque texture du cube correspond à une direction : • • • • • +X, -X, +Y, -Y, +Z, -Z Textures Textures … glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0,GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, face_px ); Nouveaux paramètres de destination pour la fonction • glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0,GL_RGB, w, h,0, GL_RGB, GL_UNSIGNED_BYTE, face_nx ); glTexImage2D(~) En fonction de la cibles : • GL_TEXTURE_CUBE_MAP_POSITIVE_X • GL_TEXTURE_CUBE_MAP_NEGATIVE_X • GL_TEXTURE_CUBE_MAP_POSITIVE_Y • GL_TEXTURE_CUBE_MAP_NEGATIVE_Y • GL_TEXTURE_CUBE_MAP_POSITIVE_Z • GL_TEXTURE_CUBE_MAP_NEGATIVE_Z • /* idem pour les 4 autres directions */ glEnable(GL_TEXTURE_CUBE_MAP); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLEXION_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLEXION_MAP); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLEXION_MAP); glEnable(GL_TEX_GEN_S); glEnable(GL_TEX_GEN_T); glEnable(GL_TEX_GEN_R); Nouveaux modes de génération automatique des coordonnées de texture pour la fon ction (vecteurs de paramètres) glTexGeni(~) • • • /* tracé de la géométrie */ glDisable(GL_TEXTURE_CUBE_MAP); glDisable(GL_TEX_GEN_S); glDisable(GL_TEX_GEN_T); glDisable(GL_TEX_GEN_R); GL_NORMALE_MAP : (s,t,r) = normale du sommet GL_REFLEXION_MAP : (s,t,r) = vecteur de visée réfléchi par rapport à la normale … Textures void init(){ … GLfloat t1[] = {2.5,2.5,2.5},t2[] = {-2.5,2.5,2.5}, t3[] = {-2.5,2.5,-2.5},t4[] = {2.5,2.5,-2.5} …; GLfloat b1[] = {2.5,-2.5,2.5},b2[] = {-2.5,-2.5,2.5}, b3[] = {-2.5,-2.5,-2.5},b4[] = {2.5,-2.5,-2.5} …; glGenTextures(GL_TEXTURE_CUBE_MAP_POSITIVE_X, &myNames[0]); glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X,myNames[0]); glTexParameteri(GL_TEXTURE_CUBE_MAP_POSITIVE_X,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_POSITIVE_X,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_POSITIVE_X,GL_TEXTURE_WRAP_S,GL_CLAMP); glTexParameteri(GL_TEXTURE_CUBE_MAP_POSITIVE_X,GL_TEXTURE_WRAP_T,GL_CLAMP); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, texture->Type, texture->Width, texture->Height, 0, texture->Type, GL_UNSIGNED_BYTE, im agData); Textures glBegin(GL_POLYGON); //Top face glNormal3f(0.0,1.0,0.0); glVertex3fv(t1); glVertex3fv(t2); glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X,myNam es[0]); glVertex3fv(t3); glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,myNam es[1]); glVertex3fv(t4); glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Z,myNam es[2]); glEnd(); glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_X,myNam es[3]); glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,myNam es[4]); glBegin(GL_POLYGON); glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,myNam es[5]); //side face 1 void display(){ … glPushMatrix(); glEnable(GL_TEXTURE_CUBE_MAP); glGenTextures(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, &myNames[1]); glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,myNam es[1]); glTexParameteri(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,GL_ TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,GL_ TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,GL_ TEXTURE_WRAP_S,GL_CLAMP); glTexParameteri(GL_TEXTURE_CUBE_MAP_POSITIVE_Y,GL_ TEXTURE_WRAP_T,GL_CLAMP); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, texture->Type, texture->Width, texture->Height, 0, texture->Type, GL_UNSIGNED_BYTE, im agData); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP); // idem pour les 4 autres faces … … } glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); glDisable(GL_TEXTURE_CUBE_MAP); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); glPopMatrix(); … } glNormal3f(1.0,0.0,0.0); glVertex3fv(t1); glVertex3fv(t2); glVertex3fv(b2); glVertex3fv(b1); glEnd(); glBegin(GL_POLYGON); //side face 2 glNormal3f(0.0,0.0,1.0); glVertex3fv(t4); glVertex3fv(t1); glVertex3fv(b1); glVertex3fv(b4); glEnd(); … 51 Textures Textures • • Comme pour les objets la projection (GL_MODELVIEW & GL_PROJECTION ), on peut appliq uer des matrices de transformations sur les textures : Pile de matrices texture Il faut se mettre dans le mode correspondant : glMatrixMode(GL_TEXTURE) • Toutes les instructions de matrices (glRotate, glTranslate, glPushMatrix,...) s’adresseront à l a pile de matrice de texture. • Toutes les coordonnées (s, t) subissent la matrice de texture courante (l’identité par défaut) • Ex : glMatrixMode(GL_TEXTURE); glTranslatef(.......); ............ glMatrixMode(GL_MODELVIEW); Textures glMatrixMode(GL_TEXTURE) ; glPushMatrix() ; glRotatef(45,0,0,1) ; draw_example1_quad() ; glPopMatrix() ; glMatrixMode(GL_MODELVIEW) ; 52