Opengl 4
Opengl 4
Introduction à OpenGL
Partie I: Rudiments d'OpenGL
1. OGL : Open Graphic Language
2. références
3. Pipeline OpenGL
4. Conventions de l'API
5. Matrices homogènes
6. Buffers OpenGL
Johan Montagnat 7. Primitives géométriques
I3S, CNRS 8. Couleurs et matériaux
9. Sources lumineuses
johan@[Link]
10. Interaction entre OpenGL et X windows
Introduction a OpenGL 2 SI2 - cours de synthèse d'images, 2006
Philosophie GL
Organisation de librairies
• Notion de contexte
À chaque fenêtre graphique 3D est associé un contexte OpenGL • Les principales librairies
GL: API de base
Un seul contexte actif à un instant donné
GLU (GL Utility): API haut niveau (primitive graphiques complexes, position de
Toutes les commandes GL ont lieu dans le contexte actif
la caméra, projections, ...)
• Architecture en pipeline GLX: interface avec X windows (sous UNIX)
Deux types de primitives: GLUT (GL Utility Toolkit): API haut niveau (initialisation, boucle d'évènements
- Géométriques (points, lignes...) X windows, ...)
Application
- Pixels (images, textures...) • Organisation
Traitement des primitives en série (pipeline) jusqu'à l'étape de rasterization X GLUT
(discrétisation et écriture dans le buffer d'affichage) GLX GLU GL
Windows
• Superposition de buffers comme autant de couches transparentes Système d'exploitation Driver graphique
Le buffer d'affichage (framebuffer), généralement sur 24 ou 32 bits
Matériel Carte graphique
Mais aussi le Z-buffer, stencil-buffer, double buffer...
- Autant de bits par pixel! Introduction a OpenGL 8 SI2 - cours de synthèse d'images, 2006
10. Références
Références électroniques
• Le site officiel
[Link]
• Mesa3D
[Link]
• SGI
[Link]
[Link]
[Link]
• Tutorial et exemples
[Link]
Conventions de nommage
Changer l'état courant
• Les types • OpenGL fonctionne comme une machine à états
Il n'y a ni types, ni structures définies en OpenGL. Les seuls types manipulés sont
Les commandes ne sont souvent pas suffisantes par elle même, elles s'exécutent
les types primitifs du C ou des tableaux de type primitifs dans un contexte.
• Les constantes Ex: à un sommet est attaché une couleur courant, une normale courante, etc.
GL_... suivi de mots en majuscules séparés par des _ Le changement d'état se fait à travers de très nombreuses fontions de l'API:
GL_PROJECTION, GL_TRIANGLE_FAN gl{Enable,Disable}({GL_LIGHTING, GL_FOG, GL_DEPTH_TEST...})
Piles de matrices
Piles de matrices
• Toutes les coordonnées (sommet, normales, directions...) sont • Matrices représentées en rangées dominantes
multipliées par des matrices de transformation et de projection. Attention, ce n'est pas la représentation usuelle 0 4 8 12
Translation
Rotation (r, t, -n)
Echelle
(3x3) (l, b, -n)
projection 1 n f
• Translations:glTranslate 1
0
0
1
0
0
x
y
• Projection orthogonale 2
glTranslate{fd}(T x, T y, T z); 0 0 1 z
glOrtho(double l, double r, double b, double t, r-l 0 0 - r+l
0 0 0 1 r-l
double n, double f) 2
0
t-b 0 - t+b
glMatrixMode(GL_MODELVIEW);
// … réalise le rendu des objets
glColor3f(red, green, blue) ou glColor4f(red, green, blue, alpha) • Définition des composantes d'un matériau
Toutes les primitives affichées par la suite prennent la couleur fixée glMaterialfv(GL_FRONT, GL_SPECULAR, tab_4_float) composante spéculaire
• La couleur est composée en fonction des calculs d'éclairage et de glMaterialfv(GL_FRONT, GL_DIFFUSE, tab_4_float) composante diffuse
transparence glMaterialfv(GL_FRONT, GL_AMBIENT, tab_4_float) composante ambiente
• glColor permet de colorer les primitives points ou lignes glMaterialfv(GL_FRONT, GL_EMISSIVE, tab_4_float) composante émissive
glMaterialf(GL_FRONT, GL_SHININESS, float) coefficient de brillance dans [0, ∞[
Introduction a OpenGL 34 SI2 - cours de synthèse d'images, 2006
Atténuation de la lumière
Spots
• Différentes lois d'atténuation de l'intensité • En plus des paramètres précédents...
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, value) atténuation
• Une direction Spot
indépendante de la distance à l'objet (lumière directionnelle à l'infini)
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, value)
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, value) atténuation linéaire en value = 3 float
la distance à l'objet (lumière ponctuelle) soumise aux transformations géométriques
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, value) atténuation Cut-off
quadratique en la distance à l'objet (lumière ponctuelle) • Un angle d'ouverture Direction
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, value)
en degrés
• Position de la lumière soumise à la matrice de transformation
glLightfv(GL_LIGHT0, GL_POSITION, value) • Un coefficient d'atténuation exponentielle à l'intérieur du cône
value = 4 float glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, value)
La valeur par défaut est 0 (pas d'atténuation = bords nets du cône de lumière).
Introduction a OpenGL 40 SI2 - cours de synthèse d'images, 2006
Pipeline OpenGL
2. Interaction entre OpenGL et X windows
• Le paradigme objet est bien adapté à la gestion événementielle et la Les actions utilisateur (clavier, souris...) génèrent des événements
et conditionnent les capacités de rendu. Plusieurs tentatives peuvent être nécessaire pour obtenir un visual supporté par la
carte graphique (si les paramètres transmis ne sont pas supportés, la fonction
• Les capacités du serveur X sont paramétrables mais limitées par la retourne 0).
carte graphique pilotée
Introduction a OpenGL 48 SI2 - cours de synthèse d'images, 2006
// callback de réaffichage
void display() {
// instructions GL...
}
Introduction a OpenGL 52 SI2 - cours de synthèse d'images, 2006
• Fonctionnalités
Manipulations matricielles (→ repose sur glMultMatrix())
Positionnement de la camera (→ glMultMatrix())
Quadriques (→ primitives géométriques)
NURBS (→ primitives géométriques)
Simplification de polygones
Introduction a OpenGL 54 SI2 - cours de synthèse d'images, 2006
Projections
Projections
• Chaque méthode crée une matrice puis appelle glMultMatrix • Projection perspective 3D: spécification intuitive
gluPerspective(double fovy, double aspect, double near, double far)
gluProject() / gluUnproject()
fovy = angle de vue en y (en degrés)
Projection des coordonnées de l'espace objet à l'espace écran et réciproquement
aspect = rapport de l'angle de vue en x sur l'ange en y (généralement 1)
Paramètres = coordonnées + tous les paramètres de transformation (matrices,
near = distance au plan de coupe proche
viewport)
far = distance au plan de coupe éloigné
Les paramètres de la transformation finale écran (viewport), établis par appel à
fovy
glViewport(), peuvent être relu par glGetDoublev(GL_VIEWPORT, Par simple appel à glFrustum(): y
tableau_4_double). x
ymax = - ymin = near * tan(fovy * PI / 360) fovx
Quadriques
Quadriques
• Primitives géométriques de haut niveau
Quadriques = sphère, cylindres et disques • Exécution des primitives GL
Structure commune GLUquadricObj *quad = gluNewQuadric(); Création de facettes quadrilatérales
Orientation par défaut (selon l'axe Y)
gluSphere(quad, radius, slices, stack): sphère (méridiens et parallèles)
• Paramètres de rendu gluCylinder(quad, r1, r2, height, slices, stack): cylindre conique
gluQuadricDrawStyle: GLU_POINT, GLU_LINE, GLU_FILL, GLU_SILHOUETTE
gluDisk(quad, r1, r2, slices, loops): disque dans le plan z=0
primitives utilisées pour le rendu gluPartialDisk(quad, r1, r2, slices, loops, a1, a2): arc de disque
gluQuadricNormals: GLU_NONE, GLU_FLAT, GLU_SMOOTH
utilisation des normales: aucune, une par face, une par sommet • Callback associé
gluQuadricTexture: GL_TRUE, GL_FALSE gluQuadricCallback() : gestion des erreurs
Les polynômes de base sont paramétrés par un ensemble fini de noeuds (suite croissante de réels). Σ
n-1
Σ p
m-1
B (x)B (y) y d d
i=0 j=0 nm i,x j,y
Leur degré peut varier. Introduction a OpenGL 62 SI2 - cours de synthèse d'images, 2006
NURBS
• Comme pour les quadriques: objet NURBS NURBS
GLUnurbsObj *nurbs = gluNewNurbsRenderer();
normales, points de texture... générés par GLU // où #nœuds = n+d, order = d, nœuds est un tableau de n+d points et
property = GLU_{SAMPLING_METHOD, DISPLAY_MODE, …} pour contrôler la • Création d'une surface de manière similaire
discrétisation, l'affichage, ... gluBeginSurface(nurbs);
// autant de fois que désiré
• Création d'une courbe ou d'une surface gluNurbsCurve(nurbs, int #nœudsx, float *nœudsx, int #nœudsy, float
gluNurbsCurve() / gluNurbsSurface() *nœudsy, int offset, float *ctlpoints, int orderx, int ordery
• Destructuion
GL_MAP2_VERTEX{3,4});
gluEndSurface(nurbs);
gluDeleteNurbsRenderer(nurbs); Introduction a OpenGL 64 SI2 - cours de synthèse d'images, 2006
Transformations
• Les tableaux de pixels manipulés peuvent être soumis à une série de Ecriture d'un tableau de pixels
transformations
voir pipeline de glDrawPixels, (GLSPEC p 96) • Ecriture dans le buffer d'affichage
glDrawPixels()
• Exemple: augmenter l'intensité du plan rouge • Ecriture dans la mémoire de texture
glPixelTransferf(GL_RED_SCALE, 2.0); glTexImage[1-3]D()
• Exemple: convolution du tableau avec un filtre • Copie d'une région du buffer d'affichage dans une autre
glConvolutionFilter2D(GL_CONVOLUTION_2D, GLenum outputFormat, int width, glCopyPixels()
int height, GLenum inputFormat, GLenum type, void *data) • Lecture d'une région du buffer d'affichage
inputFormat = format du buffer d'entrée (e.g. GL_RGB) glReadPixels()
outputFormat = format du tableau de pixels généré (e.g. GL_RGBA) cf pipeline des transformations en lecture (GLSPEC p 181), inverse des
width, height = taille de l'image transformations en écriture
type = type du buffer de pixels (e.g. GL_UNSIGNED_BYTE)
• Lecture de tout un buffer
data = image composant le filtre de convolution glReadBuffer()
glConvolutionParameter{if}v(GL_CONVOLUTION_2D,
GL_CONVOLUTION_FILTER_{SCALE, BIAS}, 4_float_values): paramètres à appliquer
au filtre de convolution Introduction a OpenGL 68 SI2 - cours de synthèse d'images, 2006
Coordonnées texture
Paramètres de texture
• OpenGL prévoit un espace de texture à 4 dimensions, normalisées
entre 0 et 1, et désignées par GL_T, GL_S, GL_R, GL_Q
• Couleur de base de la texture
glTextEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, 4_floats)
• Paramètres de texture: glTexParameter Par défaut : (0, 0, 0, 0)
glTexParameteri(GL_TEXTURE_{1,2,3}D, GL_TEXTURE_WRAP_{S,T,R},
GL_{CLAMP, REPEAT}): Troncature ou répétition au bord
glTexParameteri(GL_TEXTURE_{1,2,3}D, GL_TEXTURE_{MIN,MAG}_FILTER, • Mode de composition des pixels de la texture avec la couleur de base
GL_{NEAREST,LINEAR,...}): Filtre de sous- ou sur-échantillonnage et le contenu du buffer d'affichage
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_{REPLACE,
MODULATE, DECAL, BLEND})
• Association des points de texture avec les sommets géométriques GL_REPLACE = ignorer le buffer d'affichage
glTexCoord2f(float x, float y): x et y dans [0,1]
GL_MODULATE = moduler avec la couleur de base
Alternance coordonnée sommet - coordonnée texture:
GL_DECAL, GL_BLEND = moduler avec la couleur de base et le buffer d'affichage
glTexCoord2f(0.0, 0.0)
glVertex3f(0, 0, 0)
glTexCoordef(1.0, 0.0)
glVertex3f(100.0, 0, 0)
Introduction a OpenGL 72 SI2 - cours de synthèse d'images, 2006
placage d'une texture fish-eye sur l'objet (=reflet de l'environnement sur l'objet) Introduction a OpenGL 74 SI2 - cours de synthèse d'images, 2006
Clipping
Brouillard
• Supprimer du pipeline de rendu toutes les primitives à l'extérieur • Modifier la couleur fonction de la distance pour donner une impression
du/des plan(s) de coupe de profondeur (pour le rendu fil de fer ou les effets de brouillard)
glEnable(GL_FOG)
• Pour éviter les aberrations (projection d'objet derrière la caméra, etc), • Choisir pour couleur de brouillard celle du fond
il existe toujours deux plans parallèles à la caméra (near et far) mis glFogfv(GL_FOG_COLOR, 4_floats)
en place avec glFrustum()
• Fonctions de transformation linéaire, exp ou exp^2
• Activation de plans de coupe glFogi(GL_FOG_MODE, GL_{LINEAR, EXP, EXP2})
glEnable(GL_CLIP_PLANEi)
réalisme = tenir compte de la distance de chaque primitive… spécifier le type de test et la valeur seuil de test
- très coûteux en espace mémoire et en temps
• Compromis: utilisation de la composante Alpha de couleur pour • Moduler la couleur en fonction du coefficient Alpha:
simuler la transparence glEnable(GL_BLEND)
Composer les couleurs (R,G,B,A) 2 à 2 La couleur d'un fragment peut être composée avec une couleur de référence:
glBlendColor(float red, float green, float blue, float alpha)
Garder un seul plan des valeurs A pour chaque pixel de l'écran
et le contenu du buffer d'affichage:
ex: pixel (i,j) de couleur (R1,G1,B1,A1) à composer avec (R2,G2,B2,A2):
glBlendEquation() et glBlendFunc()
(R,G,B,A) = (A1*R1+A2*R2, A1*G1+A2*G2, A1*B1+A2*B2, A1*A2)
éclaircissement progressif par superposition
ou bien une autre forme de composition ? Introduction a OpenGL 78 SI2 - cours de synthèse d'images, 2006
Transparence en OpenGL
Anti-crénelage (antialiasing)
• glBlendEquation :
• Affectation d'une composante Alpha dans [0,1] proportionnelle à la
glBlendEquation(GL_FUNC_{ADD,SUBSTRACT,MIN,MAX,REVERSE_SUBSTRACT})
surface de pixel couverte par chaque primitive
GL_FUNC_ADD: Couleur = src * CouleurFragment + dst * CouleurBuffer
... • Activation de l'anti-crénelage
glEnable(GL_{POINT,LINE,POLYGON}_SMOOTH)
• glBlendFunc :
• Contrôle qualité / coût
glBlendFunc(enum src, enum dst)
glHint(GL_{POINT,LINE,POLYGON}_SMOOTH_HINT,
src = GL_{ZERO,ONE,DST_COLOR,ONE_MINUS_DST_COLOR,CONSTANT_COLOR…}
GL_{FASTEST,NICEST,DONT_CARE})
dest = GL_{ZERO,ONE,SRC_COLOR,ONE_MINUS_SRC_COLOR,CONSTANT_COLOR…}
exemple de transparence:
glBlendEquation(GL_FUNC_ADD)
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
• Définition d'une fonction de transfert pour contrôler l'opacité de • Sélection du buffer de rendu
chaque pixel traversé glDrawBuffer(GL_BACK_{LEFT,RIGHT})
5. Optimisation
Double buffers
• Double buffers • Eviter le scintillement en dessinant hors de l'écran puis en
• Listes précompilées rafraîchissant la fenêtre « instantanément »
• Textures hiérarchisées Initialisation: paramètre GLX_DOUBLEBUFFER de glXChooseVisual()
Simplification de triangulations
• Simplification = réduction d'une triangulation (on parle de décimation:
1 sur 10)
Conserver la topologie
Préserver au mieux la géométrie (concentrer les triangles dans les zones de forte
courbure)