Solutions des exercices |
||
Mini-langage
pour OpenGL,
fonctions basiques pour Auxiliary library Caméras, implantation en VRML et en OpenGL Mise en route en VRML et en OpenGL Utilisation des primitives graphiques
Dernière modification |
Push Push T(1.5,0,-1.5) C Pop Push T(-1.5,0,-1.5) R(30,0,1,0) T(0,0,-0.5) C Pop Push T(-1.5,0,1.5) Z(1,1,2) C Pop Push T(1.5,0,1.5) R(45,0,1,0) C Pop Pop Push R(r1,0,1,0) T(1.5,0,0) Push Z(3,1,1) C Pop T(1.5,0,0) R(r2,0,1,0) T(1.5,0,0) Push Z(3,0.8,0.8) C Pop T(1.8,0,0) R(r3,1,0,0) Push Z(0.6,1.2,1.8) C Pop T(0.8,0,0) Push T(0,0,-0.2-d) Push Z(1.0,1.2,0.4) C Pop Pop Push T(0,0,0.2+d) Push Z(1.0,1.2,0.4) C Pop Pop Pop
#VRML V1.0 ascii Separator { Rotation { rotation 0 1 0 0.7854 } Translation { translation 1.5 0 0 } Cube { width 3 height 1 depth 1 } Translation { translation 1.5 0 0 } Rotation { rotation 0 1 0 0.5236 } Translation { translation 1.5 0 0 } Cube { width 3 height 0.8 depth 0.8 } Translation { translation 1.8 0 0 } Rotation { rotation 1 0 0 1.0472 } Cube { width 0.6 height 1.2 depth 1.8 } Translation { translation 0.8 0 0 } Separator { Translation { translation 0 0 -0.4 } Cube { width 1.0 height 1.2 depth 0.4 } } Separator { Translation { translation 0 0 0.4 } Cube { width 1.0 height 1.2 depth 0.4 } } }
L = Ip Kd cos(q) L = Ip Kd (.) #include <stdio.h> #include <math.h> typedef struct coord_3D { float x ; float y ; float z ; } coord_3D ; typedef struct couleur { float r ; float v ; float b ; } couleur ; typedef struct direction_3D { float dx ; float dy ; float dz ; } direction_3D ; typedef struct pointLight { coord_3D pos ; couleur coul ; float energie ; } pointLight ; typedef struct materiau { couleur diffusion ; couleur reflexion ; couleur transmission ; couleur emission ; } materiau ; typedef struct energie { float er ; float ev ; float eb ; } energie ; float distance(coord_3D *p1, coord_3D *p2) { double x = p1->x - p2->x ; double y = p1->y - p2->y ; double z = p1->z - p2->z ; double d2 = x*x + y*y + z*z ; return((float) pow(d2,0.5)) ; } void calculVecteurNorme(coord_3D *pi, coord_3D *pf, direction_3D *n) { double x = pf->x - pi->x ; double y = pf->y - pi->y ; double z = pf->z - pi->z ; double d2 = x*x + y*y + z*z ; d2 = pow(d2,0.5) ; n->dx =(float) (x / d2) ; n->dy =(float) (y / d2) ; n->dz =(float) (z / d2) ; } float produitScalaire(direction_3D *d1, direction_3D *d2) { return(d1->dx*d2->dx + d1->dy*d2->dy + d1->dz*d2->dz) ; } /* En entree les coordonnees du point p et la pointlight l. En sortie l'energie recue*/ void calculEnergieRecue(coord_3D *p, pointLight *l, energie *e) { float d = distance(p,&l->pos) ; float atten = 1.0F / d / d ; e->er = atten * l->energie * l->coul.r ; e->ev = atten * l->energie * l->coul.v ; e->eb = atten * l->energie * l->coul.b ; } /* En entree les coordonnees du point p, la normale n a la surface au point p, le materiau m de la surface, la pointlight l. En sortie l'energie diffusee*/ void calculEnergieDiffusee(coord_3D *p, direction_3D *n, materiau *m, pointLight *l, energie *e) { energie recu ; calculEnergieRecue(p,l,&recu) ; direction_3D li ; calculVecteurNorme(p,&l->pos,&li) ; float scal = produitScalaire(&li,n) ; if ( scal < 0.0F ) scal = 0.0F ; e->er = recu.er * scal * m->diffusion.r ; e->ev = recu.ev * scal * m->diffusion.v ; e->eb = recu.eb * scal * m->diffusion.b ; } void main(void) { coord_3D p = { 1.0F,2.0F,0.0F } ; direction_3D n = { 0.0F,0.0F,1.0F } ; pointLight l = { {-1.0F,2.0F,4.0F}, {1.0F,0.5F,0.5F}, 5.0F } ; materiau m = { {0.5F,0.5F,1.0F}, {0.0F,0.0F,0.0F}, {0.0F,0.0F,0.0F}, {0.0F,0.0F,0.0F} } ; energie e ; energie ed ; calculEnergieRecue(&p,&l,&e) ; printf("Energie recue : %f %f %f\n", e.er,e.ev,e.eb) ; calculEnergieDiffusee(&p,&n,&m,&l,&ed) ; printf("Energie diffusee : %f %f %f\n", ed.er,ed.ev,ed.eb) ; } Fichier source: TD-Diffusion.cpp
#include <stdio.h> #include <math.h> typedef struct coord_3D { float x ; float y ; float z ; } coord_3D ; typedef struct direction_3D { float dx ; float dy ; float dz ; } direction_3D ; typedef struct rayon { coord_3D pos ; direction_3D dir ; } rayon ; /* En entree le rayon r teste. En sortie le nombre d'intersection(s) */ int intersectionSphere(rayon *r) { float a = r->dir.dx*r->dir.dx + r->dir.dy*r->dir.dy + r->dir.dz*r->dir.dz ; float b = 2*(r->dir.dx*r->pos.x + r->dir.dy*r->pos.y + r->dir.dz*r->pos.z) ; float c = r->pos.x*r->pos.x + r->pos.y*r->pos.y + r->pos.z*r->pos.z - 1 ; float delta = b*b - 4*a*c ; if ( delta > 0 ) return(2) ; if ( delta == 0 ) return(1) ; return(0) ; } int posIntersectionSphere(rayon *r, coord_3D *p) { float a = r->dir.dx*r->dir.dx + r->dir.dy*r->dir.dy + r->dir.dz*r->dir.dz ; float b = 2*(r->dir.dx*r->pos.x + r->dir.dy*r->pos.y + r->dir.dz*r->pos.z) ; float c = r->pos.x*r->pos.x + r->pos.y*r->pos.y + r->pos.z*r->pos.z - 1 ; float delta = b*b - 4*a*c ; if ( delta > 0 ) { float rcn =(float) pow(delta,0.5) ; float d = (-b-rcn)/2/a ; if ( d > 0 ) { p->x = r->pos.x + d * r->dir.dx ; p->y = r->pos.y + d * r->dir.dy ; p->z = r->pos.z + d * r->dir.dz ; return(1) ; } else { float d = (-b+rcn)/2/a ; if ( d > 0 ) { p->x = r->pos.x + d * r->dir.dx ; p->y = r->pos.y + d * r->dir.dy ; p->z = r->pos.z + d * r->dir.dz ; return(1) ; } } return(0) ; } if ( delta == 0 ) { float d = -b/2/a ; p->x = r->pos.x + d * r->dir.dx ; p->y = r->pos.y + d * r->dir.dy ; p->z = r->pos.z + d * r->dir.dz ; return(1) ; } return(0) ; } float produitScalaire(direction_3D *d1, direction_3D *d2) { return(d1->dx*d2->dx + d1->dy*d2->dy + d1->dz*d2->dz) ; } void calculReflexion(rayon *r, float d, rayon *ref) { ref->pos.x = r->pos.x + d * r->dir.dx ; ref->pos.y = r->pos.y + d * r->dir.dy ; ref->pos.z = r->pos.z + d * r->dir.dz ; direction_3D n = { ref->pos.x, ref->pos.y, ref->pos.z } ; direction_3D i = { -r->dir.dx, -r->dir.dy, -r->dir.dz } ; float scal = produitScalaire(&n,&i) ; ref->dir.dx = 2 * n.dx * scal - i.dx ; ref->dir.dy = 2 * n.dy * scal - i.dy ; ref->dir.dz = 2 * n.dz * scal - i.dz ; } /* En entree le rayon r teste. En sortie un booleen indiquant l'existence d'un rayon reflechi, le rayon reflechi ref */ int rayonReflechiSphere(rayon *r, rayon *ref) { float a = r->dir.dx*r->dir.dx + r->dir.dy*r->dir.dy + r->dir.dz*r->dir.dz ; float b = 2*(r->dir.dx*r->pos.x + r->dir.dy*r->pos.y + r->dir.dz*r->pos.z) ; float c = r->pos.x*r->pos.x + r->pos.y*r->pos.y + r->pos.z*r->pos.z - 1 ; float delta = b*b - 4*a*c ; a *= 2 ; if ( delta > 0 ) { float rcn =(float) pow(delta,0.5) ; float d = (-b-rcn)/a ; if ( d > 0 ) { calculReflexion(r,d,ref) ; return(1) ; } else { float d = (-b+rcn)/2 ; if ( d > 0 ) { calculReflexion(r,d,ref) ; return(1) ; } } return(0) ; } if ( delta == 0 ) { float d = -b/a ; calculReflexion(r,d,ref) ; return(1) ; } return(0) ; } void main(void) { /* rayon r = { {3.0F,-0.2F,-0.3F}, {-0.95F,0.22F,0.22F} } ;*/ /* rayon r = { {3.0F,0.7071067811F, 0.7071067811F}, {-1.0F,0.0F,0.0F} } ;*/ /* rayon r = { {3.0F,0.7071067811F,0.0F}, {-1.0F,0.0F,0.0F} } ;*/ rayon r = { {3.0F,0.0F,0.7071067811F}, {-1.0F,0.0F,0.0F} } ; printf("Rayon initial : %f %f %f\n", r.pos.x,r.pos.y,r.pos.z) ; printf(" %f %f %f\n", r.dir.dx,r.dir.dy,r.dir.dz) ; int n = intersectionSphere(&r) ; printf("Nombre intersections : %d\n",n) ; coord_3D p ; int inter = posIntersectionSphere(&r,&p) ; if ( inter ) { printf("Pos intersection : %f %f %f\n", p.x,p.y,p.z) ; } else { printf("Pas d'intersection\n") ; } rayon ref ; inter = rayonReflechiSphere(&r,&ref) ; if ( inter ) { printf("Rayon reflechi : %f %f %f\n", ref.pos.x,ref.pos.y,ref.pos.z) ; printf(" %f %f %f\n", ref.dir.dx, ref.dir.dy, ref.dir.dz) ; } else { printf("Pas de reflexion\n") ; } } Fichier source: TD-Reflexion.cpp
#include <stdio.h> #include <stdlib.h> #include <math.h> typedef struct coord_3D { float x ; float y ; float z ; } coord_3D ; typedef struct polygone { int n ; coord_3D *c ; } polygone ; void pixel(float x,float y,float z) { printf("%f %f %f\n",x,y,z) ; } double power(double v,int p) { return(( !v && !p ) ? 1.: pow(v,(double) p)) ; } /* En entree le polygone p, le nombre de points n */ void bezier(polygone *p,int n) { int i,j ; float t,mt ; float *cn,x,y,z,fac ; cn =(float *) calloc(p->n,sizeof(float)); cn[0] = 1 ; cn[1] =(float) (p->n-1) ; for ( i = 2 ; i < p->n ; i++ ) cn[i] = cn[i-1] * (p->n - i) / i ; for ( i = 0 ; i < n ; i++ ) { t =(float) i/(n-1) ; mt = 1-t ; x = y = z = 0.0F ; for ( j = 0 ; j < p->n ; j++ ) { fac = cn[j]*(float) power(t,j)* (float) power(mt,p->n-1-j); x += fac * p->c[j].x ; y += fac * p->c[j].y ; z += fac * p->c[j].z ; } pixel(x,y,z) ; } free(cn) ; } void main(void) { coord_3D c[8] = { {-6.0F,-6.0F, 3.0F}, {-6.0F,-1.0F, 1.0F}, {-5.0F, 2.0F,-1.0F}, {-1.0F, 3.0F, 1.0F}, { 2.0F, 1.0F, 4.0F}, { 4.0F, 2.0F, 2.0F}, { 5.0F, 5.0F,-2.0F}, { 6.0F, 6.0F,-4.0F} } ; polygone p = { 8,c } ; bezier(&p,50) ; } Fichier source: TD-Bezier.cpp static GLfloat pts[7][3] = { {3,2,-1},{-4,5,-4}, {-5,4,3},{-1,-3,-2}, {4,-1,0}}; void traceBezierGL(void) { glMap1f(GL_MAP1_VERTEX_3, 0.0,1.0,3,5,&pts[0][0]); glEnable(GL_MAP1_VERTEX_3); glColor3f(0.0,1.0,1.0); glBegin(GL_POINTS); for ( int i = 0 ; i <= 100 ; i++ ) glEvalCoord1f((GLfloat) i/100.0F); glEnd(); } Fichier source complet: TD-Bezier-GL.cpp
float p = 0.55 ; float pts1[4][3] = { {1.0F,0.0F,0.0F}, {1.0F,p,0.0F}, {p,1.0F,0.0F}, {0.0F,1.0F,0.0F} } ; void traceQuartCercleBezierGL(float r) { glPushMatrix() ; glScalef(r,r,r) ; glMap1f(GL_MAP1_VERTEX_3, 0.0,1.0,3,4,&pts1[0][0]); glEnable(GL_MAP1_VERTEX_3); glColor3f(0.0,1.0,1.0); glBegin(GL_POINTS); for ( int i = 0 ; i <= n ; i++ ) glEvalCoord1f((GLfloat) i/100.0F); glEnd(); glPopMatrix() ; } void traceCercleBezierGL(float r) { glPushMatrix() ; traceQuartCercleBezierGL(r) ; glRotatef(90.0F,0.0F,0.0F,1.0F) ; traceQuartCercleBezierGL(r) ; glRotatef(90.0F,0.0F,0.0F,1.0F) ; traceQuartCercleBezierGL(r) ; glRotatef(90.0F,0.0F,0.0F,1.0F) ; traceQuartCercleBezierGL(r) ; glPopMatrix() ; } Fichier source complet: TD-Bezier-GL-Cercle.cpp
float p = 0.55F ; float pts1[16][3] = { {1.0F,0.0F,1.0F}, {1.0F,p,1.0F}, {p,1.0F,1.0F}, {0.0F,1.0F,1.0F}, {1.0F,0.0F,0.3F}, {1.0F,p,0.3F}, {p,1.0F,0.3F}, {0.0F,1.0F,0.3F}, {1.0F,0.0F,-0.3F}, {1.0F,p,-0.3F}, {p,1.0F,-0.3F}, {0.0F,1.0F,-0.3F}, {1.0F,0.0F,-1.0F}, {1.0F,p,-1.0F}, {p,1.0F,-1.0F}, {0.0F,1.0F,-1.0F} } ; void traceQuartTuyauBezierGL(float r, float h) { glPushMatrix() ; glScalef(r,r,h/2) ; glMap2f(GL_MAP2_VERTEX_3,0.0F,1.0F, 3,4, 0.0F,1.0F, 12,4, (float *) pts1); glEnable(GL_MAP2_VERTEX_3); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glMapGrid2f(np1,0.0,1.0,np2,0.0,1.0); if ( ff ) glEvalMesh2(GL_LINE,0,np1,0,np2); else glEvalMesh2(GL_FILL,0,np1,0,np2); glPopMatrix() ; } void traceTuyauBezierGL(float r,float h) { glPushMatrix() ; traceQuartTuyauBezierGL(r,h) ; glRotatef(90.0F,0.0F,0.0F,1.0F) ; traceQuartTuyauBezierGL(r,h) ; glRotatef(90.0F,0.0F,0.0F,1.0F) ; traceQuartTuyauBezierGL(r,h) ; glRotatef(90.0F,0.0F,0.0F,1.0F) ; traceQuartTuyauBezierGL(r,h) ; glPopMatrix() ; } Fichier source complet: TD-Bezier-GL-Tuyau.cpp
Fichier source complet: TD-Bezier-GL-Tuyau2.cpp
float p = 0.55F ; float pts1[10][2] = { {0.0F,-5.0F}, {5.0F,-5.0}, {4.5F,-4.0F}, {2.0F,-2.0F}, {1.5F,0.0F}, {0.2F,1.0F}, {0.2F,2.0F}, {1.5F,4.0F}, {1.5F,5.0F}, {0.5F,5.0F} } ; void points(float *pts) { glDisable(GL_LIGHTING) ; glPointSize(5.0); glColor3f(0.0,1.0,1.0); glBegin(GL_POINTS); for ( int i = 0 ; i < 40 ; i++ ) glVertex3fv(&pts[i*3]); glEnd(); glEnable(GL_LIGHTING) ; } void traceQuartVaseBezierGL(void) { glPushMatrix() ; float pts[10][4][3] ; for ( int i = 0 ; i < 10 ; i++ ) { pts[i][0][0] = pts1[i][0] ; pts[i][0][1] = pts1[i][1] ; pts[i][0][2] = 0.0F ; pts[i][1][0] = pts1[i][0] ; pts[i][1][1] = pts1[i][1] ; pts[i][1][2] = p*pts1[i][0] ; pts[i][2][0] = p*pts1[i][0] ; pts[i][2][1] = pts1[i][1] ; pts[i][2][2] = pts1[i][0] ; pts[i][3][0] = 0.0F ; pts[i][3][1] = pts1[i][1] ; pts[i][3][2] = pts1[i][0] ; } glMap2f(GL_MAP2_VERTEX_3, 0.0F,1.0F, 3,4, 0.0F,1.0F, 12,10, (float *) pts); glEnable(GL_MAP2_VERTEX_3); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glMapGrid2f(np1,0.0,1.0,np2,0.0,1.0); if ( ff ) glEvalMesh2(GL_LINE,0,np1,0,np2); else glEvalMesh2(GL_FILL,0,np1,0,np2); glPopMatrix() ; } void traceVaseBezierGL(void) { glPushMatrix() ; traceQuartVaseBezierGL() ; glRotatef(90.0F,0.0F,1.0F,0.0F) ; traceQuartVaseBezierGL() ; glRotatef(90.0F,0.0F,1.0F,0.0F) ; traceQuartVaseBezierGL() ; glRotatef(90.0F,0.0F,1.0F,0.0F) ; traceQuartVaseBezierGL() ; glPopMatrix() ; } Fichier source complet: TD-Bezier-GL-Revolution.cpp
|