techniques de points de contrôle en opengl : formes de bézier
TRANSCRIPT
Techniques de points de contrôle en OpenGL :
formes de Bézier
2
Courbes de Bézier
Prend en compte les courbes et les surfaces de Bézier, celles de Hermite, toutespline ou surface polynomiale ou polynomiale rationnelle de n’importe quel degré,les B-splines, les B-splines rationnelles non uniformes (NURBS).
Définition de la courbe
Il s’agit d’abord de construire un tableau des coordonnées des points de contrôlede la courbe.
GLfloat points_de_controle[4][3] = { {-4.0, -4.0, 1.0}, {-2.0, -1.0, 0.0}, {0.0, 0.0, -1.0}, {4.0, 4.0, 1.0}};
On peut alors définir une courbe de Bézier comme suit :
void glMap1{fd}(GLenum Mode, TYPE u1, TYPE u2, GLint n, GLint m, const TYPE *P);
Mode de représentationdes points de contrôle
Plage de la variable u
# de coordonnées d’un point
# de points de contrôle
Pointe vers la 1ière
coordonnée du 1er
point de contrôle :&points_de_controle[0][0]
3
Mode de représentation des points de contrôle :
- GL_MAP1_VERTEX_3 : coordonnées des sommets x, y, z - GL_MAP1_VERTEX_4 : coordonnées des sommets x, y, z, w - GL_MAP1_INDEX : index couleur - GL_MAP1_COLOR_4 : R, V, B, A - GL_MAP1_NORMAL : coordonnées de la normale - GL_MAP1_TEXTURE_COORD_1 : coordonnées de texture s - GL_MAP1_TEXTURE_COORD_2 : coordonnées de texture s, t - GL_MAP1_TEXTURE_COORD_3 : coordonnées de texture s, t, r - GL_MAP1_TEXTURE_COORD_4 : coordonnées de texture s, t, r, q.
On peut alors évaluer la courbe de Bézier en un sommet :
void glEvalCoord1{fd}(TYPE u);void glEvalCoord1{fd}(TYPE * u);
Note : Cela n’utilise pas les coordonnées des valeurs actives des couleurs,des index couleurs, des vecteurs normaux et des textures.
Afin de pouvoir activer ce mode et permettre l’évaluation de points sur la courbe,on utilise la primitive glEnable() comme par exemple :
glEnable(GL_MAP1_VERTEX_3);
4
On peut aussi évaluer la courbe de Bézier en des points espacés régulièrement :
Au lieu de faire appel à glEvalCoord1() avec n’importe quelle valeur de u,on définit d’abord une grille de points sur la courbe :
void glMapGrid1{fd}(GLint n, TYPE u1, TYPE u2);
Une grille de n points sur la courbe également espacés entreu1 et u2 est définie.
puis, on évalue des points de cette grille pour affichage de la courbe :
void glEvalMesh1(GLenum mode, GLint p1, GLint p2);
GL_POINTou
GL_LINE
0 p1, p2 n
Cela est équivalent à :
glBegin(GL_POINTS); // ou glBegin(GL_LINE_STRIP);for (i = p1; i <= p2; i++) glEvalCoord1(u1 + i * (u2 – u1) / n);
glEnd();
5
Exemple :
GLfloat points_de_controle[4][3] = { {-4.0, -4.0, 1.0}, {-2.0, -1.0, 0.0}, {0.0, 0.0, -1.0}, {4.0, 4.0, 1.0}};
void Initialisation(void){
glClearColor(0.0, 0.0, 0.0, 0.0);
/* Permet de fixer les 3 composantes réelles de la couleur d'affichage. Elle demeure inchangée tant que ses attributs ne sont pas modifiés. */
glShadeModel(GL_FLAT);
glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);glMatrixMode(GL_MODELVIEW);
glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &points_de_controle[0][0]);glEnable(GL_MAP1_VERTEX_3);
}
Affichage d’une courbe de Bézier de degré 3.
6
void affichage( void ){
glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0);
// Affichage de la courbe de Bézier.
glBegin(GL_LINE_STRIP);for (int i = 0; i <= 30; i++) glEvalCoord1f((GLfloat) i / 30.0);
glEnd();
// Affichage des points de contrôle sous forme de points.
glPointSize(5.0);glColor3f(1.0, 1.0, 0.0);glBegin(GL_POINTS);
for(i = 0; i < 4; i++) glVertex3fv(&points_de_controle[i][0]);glEnd();
glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(1.0, 0.0, 0.0, -10.0, -10.0, 0.0, 0.0, 1.0, 0.0);glFlush();
}
7
Surfaces de BézierDéfinition de la surface
Il s’agit d’abord de construire un tableau des coordonnées des points de contrôlede la surface.
GLfloat points_de_controle[4][4][3] = {{ {-1.5, -1.5, 4.0}, {-0.5, -1.5, 2.0}, {0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}},{ {-1.5, -0.5, 1.0}, {-0.5, -0.5, 3.0}, {0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}},{ {-1.5, 0.5, 4.0}, {-0.5, 0.5, 0.0}, {0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}},{ {-1.5, 1.5, -2.0}, {-0.5, 1.5, -2.0}, {0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}},
};
8
Surfaces de Bézier
On peut alors définir une surface de Bézier comme suit :
void glMap2{fd}( GLenum Mode, TYPE u1, TYPE u2, GLint n, GLint m,TYPE v1, TYPE v2, GLint h, GLint k, TYPE * P);
Mode de représentation des points de contrôle(idem au tableau précédent sauf que MAP1est remplacé par MAP2.
Plage de la variable v
# de coordonnéesd’un point
# de points de contrôledans les directions u et v
Pointe vers la 1ière
coordonnée du 1er
point de contrôle :&points_de_controle[0][0]
Plage de la variable u
# de coordonnéessur une ligne
Afin de pouvoir activer ce mode et permettre l’évaluation de points sur la surface,on utilise la primitive glEnable() comme par exemple :
glEnable(GL_MAP2_VERTEX_3);
9
Surfaces de Bézier
On peut alors évaluer la surface de Bézier en un sommet :
void glEvalCoord2{fd}(TYPE u, TYPE v);void glEvalCoord2{fd}v(TYPE * valeurs);
On peut aussi évaluer la surface de Bézier en des points espacés régulièrement :
void glMapGrid2{fd}(GLint nu, TYPE u1, TYPE u2, GLint nv, TYPE v1, TYPE v2);
Une grille de nu x nv points sur la surface également espacés entreu1 et u2 et entre v1 et v2 resp. est définie.
puis, on évalue des points de cette grille pour affichage de la surface :
void glEvalMesh2(GLenum mode, GLint i1, GLint i2 , GLint j1, GLint j2);
GL_POINTou
GL_LINEou
GL_FILL
0 i1, i2 nu
0 j1, j2 nv
10
Surfaces de BézierCela est équivalent à :
glBegin(GL_POINTS); for (i = i1; i <= i2; i++) for (j = j1; j <= j2; j++)
glEvalCoord2( u1 + i *(u2 – u1) / nu, v1 + j *(v2 – v1) / nv);glEnd();
oufor (i = i1; i <= i2; i++){
glBegin(GL_LINES); for (j = j1; j <= j2; j++)
glEvalCoord2( u1 + i *(u2 – u1) / nu, v1 + j *(v2 – v1) / nv);glEnd();
}for (j = j1; j <= j2; j++){
glBegin(GL_LINES); for (i = i1; i <= i2; i++)
glEvalCoord2( u1 + i *(u2 – u1) / nu, v1 + j *(v2 – v1) / nv);glEnd();
}
11
Surfaces de Bézierou
for (i = i1; i < i2; i++){
glBegin(GL_QUAD_STRIP); for (j = j1; j <= j2; j++){ glEvalCoord2( u1 + i *(u2 – u1) / nu, v1 + j *(v2 – v1) / nv); glEvalCoord2( u1 + (i+1) *(u2 – u1) / nu, v1 + j *(v2 – v1) / nv);}
glEnd();}
12
Exemple : Affichage d’une surface de Bézier de degré 3 x 3 en fil de fer.
void Initialisation(void){
glClearColor(0.0, 0.0, 0.0, 0.0);glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);glMatrixMode(GL_MODELVIEW);
glMap2f(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,&points_de_controle[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);}
GLfloat points_de_controle[4][4][3] = {{ {-1.5, -1.5, 4.0}, {-0.5, -1.5, 2.0}, {0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}},{ {-1.5, -0.5, 1.0}, {-0.5, -0.5, 3.0}, {0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}},{ {-1.5, 0.5, 4.0}, {-0.5, 0.5, 0.0}, {0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}},{ {-1.5, 1.5, -2.0}, {-0.5, 1.5, -2.0}, {0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}},
};
13
void affichage( void ){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glColor3f(1.0, 0.0, 0.0);glRotatef(85.0, 1.0, 1.0, 1.0);
// Affichage d'un réseau de courbes de Bézier sur la surface.
for (GLint j = 0; j <= 8; j++){
glBegin(GL_LINE_STRIP);for (GLint i = 0; i <= 30; i++)
glEvalCoord2f((GLfloat) i / 30.0, (GLfloat) j / 8.0);glEnd();glBegin(GL_LINE_STRIP);
for (i = 0; i <= 30; i++)glEvalCoord2f((GLfloat) j / 8.0, (GLfloat) i / 30.0);
glEnd();};
14
// Affichage des points de contrôle sous forme de points.
glPointSize(5.0);glColor3f(1.0, 1.0, 0.0);glBegin(GL_POINTS);
for(GLint i = 0; i < 4; i++)for (int j = 0; j < 4; j++)
glVertex3fv(&points_de_controle[i][j][0]);glEnd();
glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(1.0, 0.0, 0.0, -10.0, -10.0, 0.0, 0.0, 1.0, 0.0);glFlush();
}
15
Exemple : Affichage d’une surface de Bézier de degré 3 x 3 en considérantdes points espacés régulièrement à l’aide de polygones pleins.
void Initialisation(void){
glClearColor(0.0, 0.0, 0.0, 0.0);glColor3f(1.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-5.0, 5.0, -5.0, 5.0, -5.0, 5.0);glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glMap2f(GL_MAP2_VERTEX_3, 0.0, 1.0, 3, 4, 0.0, 1.0, 12, 4,&points_de_controle[0][0][0]);
glEnable(GL_MAP2_VERTEX_3);glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
}
16
void affichage( void ){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);glRotatef(85.0, 1.0, 1.0, 1.0);
glEvalMesh2(GL_FILL, 0, 20, 0, 20);
glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(1.0, 0.0, 0.0, -10.0, -10.0, 0.0, 0.0, 1.0, 0.0);
glFlush();}