/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Decembre 2001 */ /* Schema pour un calcul d'illumination */ /* de Phong */ #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleFont.h" #include "ModuleManipulateur.h" #include "ModuleMatriceVecteur.h" #include "ModuleMenus.h" #include "ModuleFleche.h" #include "ModuleReshape.h" typedef float couleur[4]; struct facette3 { vecteur pa; vecteur na; vecteur pb; vecteur nb; vecteur pc; vecteur nc; } ; static float px1; static float pz1; static float px2; static float pz2; static float px; static float pz; static float h1; static float h2; static vecteur n1; static vecteur n2; static vecteur n; static int f1; static int f2; static int disc = 0; static int fleches = 0; static float posx = 0.5F; static float posy = 0.0F; static int mode = 0; static facette3 f = { { 0.05F,0.8F,0.0F }, { 0.660303F,0.063246F,0.748331F }, { -0.55F,-0.2F,0.0F }, { -0.1F,0.547722F,0.774597F }, { 0.85F,-0.75F,0.0F } , { -0.593296F,-0.089442F,0.8F } }; static GLfloat l_pos[] = { -1.5F,0.0F,1.0F,0.0F }; void myinit(void) { glLightfv(GL_LIGHT0,GL_POSITION,l_pos); glEnable(GL_LIGHT0); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); glClearColor(0.7F,0.7F,0.8F,1.0F) ; glDepthFunc(GL_LESS); } int intersection(vecteur pi,vecteur pf,vecteur ni,vecteur nf,float y,float *x,float *z,vecteur nn,float *h) { if ( ( y > pi[1] ) || ( y < pf[1] ) ) return(0); float fact = (y-pf[1])/(pi[1]-pf[1]); *h = 1.0F-fact; *x = pf[0] + fact*(pi[0]-pf[0]); *z = pf[2] + fact*(pi[2]-pf[2]); nn[0] = nf[0] + fact*(ni[0]-nf[0]); nn[1] = nf[1] + fact*(ni[1]-nf[1]); nn[2] = nf[2] + fact*(ni[2]-nf[2]); normalise(nn); return(1); } void evaluationIntersections(void) { if ( intersection(f.pa,f.pb,f.na,f.nb,posy,&px1,&pz1,n1,&h1) ) { if ( !intersection(f.pa,f.pc,f.na,f.nc,posy,&px2,&pz2,n2,&h2) ) intersection(f.pb,f.pc,f.nb,f.nc,posy,&px2,&pz2,n2,&h2); } else { intersection(f.pa,f.pc,f.na,f.nc,posy,&px2,&pz2,n2,&h2); intersection(f.pb,f.pc,f.nb,f.nc,posy,&px1,&pz1,n1,&h1); } px = px1 + posx*(px2-px1); pz = pz1 + posx*(pz2-pz1); n[0] = n1[0] + posx*(n2[0]-n1[0]); n[1] = n1[1] + posx*(n2[1]-n1[1]); n[2] = n1[2] + posx*(n2[2]-n1[2]); normalise(n); } void copie(vecteur a,vecteur b) { a[0] = b[0]; a[1] = b[1]; a[2] = b[2]; a[3] = b[3]; } void positionIntermediaire(vecteur a,vecteur b,vecteur i) { i[0] = (a[0]+b[0])/2.0F; i[1] = (a[1]+b[1])/2.0F; i[2] = (a[2]+b[2])/2.0F; } void normaleIntermediaire(vecteur a,vecteur b,vecteur i) { i[0] = (a[0]+b[0]); i[1] = (a[1]+b[1]); i[2] = (a[2]+b[2]); normalise(i); } void dessineFacetteTriangulairePhong(facette3 *f,vecteur l_pos,int disc) { if ( disc == 0 ) { float facta = produitScalaire(f->na,l_pos); float factb = produitScalaire(f->nb,l_pos); float factc = produitScalaire(f->nc,l_pos); if ( fleches ) { glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurGrisMoyen()); glPushMatrix(); glTranslatef(f->pa[0],f->pa[1],f->pa[2]); flecheEnVolume(f->na[0]/3.0F,f->na[1]/3.0F,f->na[2]/3.0F,0.01F,0.06F,0.004F); glPopMatrix(); glPushMatrix(); glTranslatef(f->pb[0],f->pb[1],f->pb[2]); flecheEnVolume(f->nb[0]/3.0F,f->nb[1]/3.0F,f->nb[2]/3.0F,0.01F,0.06F,0.004F); glPopMatrix(); glPushMatrix(); glTranslatef(f->pc[0],f->pc[1],f->pc[2]); flecheEnVolume(f->nc[0]/3.0F,f->nc[1]/3.0F,f->nc[2]/3.0F,0.01F,0.06F,0.004F); glPopMatrix(); glDisable(GL_LIGHTING); } glBegin(GL_POLYGON); glColor3f(facta,facta,facta); glVertex3fv(f->pa); glColor3f(factb,factb,factb); glVertex3fv(f->pb); glColor3f(factc,factc,factc); glVertex3fv(f->pc); glEnd();} else { facette3 f1; facette3 f2; facette3 f3; facette3 f4; vecteur pab; vecteur nab; vecteur pac; vecteur nac; vecteur pbc; vecteur nbc; positionIntermediaire(f->pa,f->pb,pab); positionIntermediaire(f->pa,f->pc,pac); positionIntermediaire(f->pb,f->pc,pbc); normaleIntermediaire(f->na,f->nb,nab); normaleIntermediaire(f->na,f->nc,nac); normaleIntermediaire(f->nb,f->nc,nbc); copie(f1.pa,f->pa); copie(f1.na,f->na); copie(f1.pb,pab); copie(f1.nb,nab); copie(f1.pc,pac); copie(f1.nc,nac); copie(f2.pa,f->pb); copie(f2.na,f->nb); copie(f2.pb,pab); copie(f2.nb,nab); copie(f2.pc,pbc); copie(f2.nc,nbc); copie(f3.pa,f->pc); copie(f3.na,f->nc); copie(f3.pb,pac); copie(f3.nb,nac); copie(f3.pc,pbc); copie(f3.nc,nbc); copie(f4.pa,pab); copie(f4.na,nab); copie(f4.pb,pac); copie(f4.nb,nac); copie(f4.pc,pbc); copie(f4.nc,nbc); dessineFacetteTriangulairePhong(&f1,l_pos,disc-1); dessineFacetteTriangulairePhong(&f2,l_pos,disc-1); dessineFacetteTriangulairePhong(&f3,l_pos,disc-1); dessineFacetteTriangulairePhong(&f4,l_pos,disc-1); } } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); glColor4fv(couleurGrisClair()); glEnable(GL_DEPTH_TEST); switch (mode) { case 0 : glBegin(GL_POLYGON); glVertex3fv(f.pa); glVertex3fv(f.pb); glVertex3fv(f.pc); glEnd(); break; case 1 : { float facta = produitScalaire(f.na,l_pos); float factb = produitScalaire(f.nb,l_pos); float factc = produitScalaire(f.nc,l_pos); glBegin(GL_POLYGON); glColor3f(facta,facta,facta); glVertex3fv(f.pa); glColor3f(factb,factb,factb); glVertex3fv(f.pb); glColor3f(factc,factc,factc); glVertex3fv(f.pc); glEnd(); } break; case 2 : dessineFacetteTriangulairePhong(&f,l_pos,disc) ; break; } glDisable(GL_DEPTH_TEST); glColor4fv(couleurNoir()); glBegin(GL_LINES); glVertex3f(px1,posy,pz1); glVertex3f(px2,posy,pz2); glEnd(); glBegin(GL_LINE_LOOP); glVertex3fv(f.pa); glVertex3fv(f.pb); glVertex3fv(f.pc); glEnd(); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); if ( posy > f.pb[1] ) { glPushMatrix(); glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurVert()); glTranslatef(f.pa[0],f.pa[1],f.pa[2]); flecheEnVolume(px1-f.pa[0],posy-f.pa[1],pz1-f.pa[2],0.022F,0.1F,0.009F); glPopMatrix(); } else { glPushMatrix(); glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurRouge()); glTranslatef(f.pb[0],f.pb[1],f.pb[2]); flecheEnVolume(px1-f.pb[0],posy-f.pb[1],pz1-f.pb[2],0.022F,0.1F,0.009F); glPopMatrix(); } glPushMatrix(); glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurBleu()); glTranslatef(f.pa[0],f.pa[1],f.pa[2]); flecheEnVolume(px2-f.pa[0],posy-f.pa[1],pz2-f.pa[2],0.022F,0.1F,0.009F); glPopMatrix(); glPushMatrix(); glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurJaune()); glTranslatef(px1,posy,pz1); flecheEnVolume(px-px1,0.0F,pz-pz1,0.022F,0.1F,0.009F); glPopMatrix(); glMaterialfv(GL_FRONT,GL_DIFFUSE,couleurGrisMoyen()); glPushMatrix(); glTranslatef(f.pa[0],f.pa[1],f.pa[2]); flecheEnVolume(f.na[0],f.na[1],f.na[2],0.025F,0.12F,0.009F); glPopMatrix(); glPushMatrix(); glTranslatef(f.pb[0],f.pb[1],f.pb[2]); flecheEnVolume(f.nb[0],f.nb[1],f.nb[2],0.025F,0.12F,0.009F); glPopMatrix(); glPushMatrix(); glTranslatef(f.pc[0],f.pc[1],f.pc[2]); flecheEnVolume(f.nc[0],f.nc[1],f.nc[2],0.025F,0.12F,0.009F); glPopMatrix(); float fact1 = produitScalaire(n1,l_pos); float coul1[4] = { fact1,fact1,fact1 }; glMaterialfv(GL_FRONT,GL_DIFFUSE,coul1); glPushMatrix(); glTranslatef(px1,posy,pz1); glutSolidSphere(0.035F,10,10); flecheEnVolume(n1[0],n1[1],n1[2],0.025F,0.12F,0.009F); glPopMatrix(); float fact2 = produitScalaire(n2,l_pos); float coul2[4] = { fact2,fact2,fact2 }; glMaterialfv(GL_FRONT,GL_DIFFUSE,coul2); glPushMatrix(); glTranslatef(px2,posy,pz2); glutSolidSphere(0.035F,10,10); flecheEnVolume(n2[0],n2[1],n2[2],0.025F,0.12F,0.009F); glPopMatrix(); float fact = produitScalaire(n,l_pos); float coul[4] = { fact,fact,fact }; glMaterialfv(GL_FRONT,GL_DIFFUSE,coul); glPushMatrix(); glTranslatef(px,posy,pz); glutSolidSphere(0.035F,10,10); flecheEnVolume(n[0],n[1],n[2],0.025F,0.12F,0.009F); glPopMatrix(); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glColor4fv(couleurBleu()); setAlignement(RIGHT); if ( posy > f.pb[1] ) { placeFontCursor((f.pa[0]+px1)/2.0F-0.05F,(f.pa[1]+posy)/2.0F,(f.pa[2]+pz1)/2.0F) ; simpleBitmapOutput(REGULAR8x13,"PaP1 = h1PaPb") ; deplacementCursor(-2,-5,0) ; simpleBitmapOutput(DESSIN,"TTTTF TTTTF") ; } else { placeFontCursor((f.pb[0]+px1)/2.0F-0.05F,(f.pb[1]+posy)/2.0F,(f.pb[2]+pz1)/2.0F) ; simpleBitmapOutput(REGULAR8x13,"PbP1 = h1PbPc") ; deplacementCursor(-2,-5,0) ; simpleBitmapOutput(DESSIN,"TTTTF TTTTF") ; } setAlignement(LEFT); placeFontCursor((f.pa[0]+px2)/2.0F+0.05F,(f.pa[1]+posy)/2.0F,(f.pa[2]+pz2)/2.0F) ; simpleBitmapOutput(REGULAR8x13,"PaP2 = h2PaPb") ; deplacementCursor(0,-5,0) ; simpleBitmapOutput(DESSIN,"TTTTF TTTTF") ; setAlignement(CENTER); placeFontCursor(px,posy-0.1F,pz) ; simpleBitmapOutput(REGULAR8x13,"P1P = hP1P2") ; deplacementCursor(0,-5,0) ; simpleBitmapOutput(DESSIN,"TTTF TTTTF") ; setAlignement(CENTER); placeFontCursor(f.pa[0]+0.05F,f.pa[1]+0.05F,f.pa[2]+0.05F) ; simpleBitmapOutput(REGULAR8x13,"Pa (Na)") ; deplacementCursor(-1,-5,0) ; simpleBitmapOutput(DESSIN," TTF") ; setAlignement(RIGHT); placeFontCursor(f.pb[0]-0.05F,f.pb[1],f.pb[2]+0.05F) ; simpleBitmapOutput(REGULAR8x13,"Pb (Nb)") ; deplacementCursor(0,-5,0) ; simpleBitmapOutput(DESSIN," TTF ") ; setAlignement(LEFT); placeFontCursor(f.pc[0]+0.05F,f.pc[1],f.pc[2]+0.05F) ; simpleBitmapOutput(REGULAR8x13,"Pc (Nc)") ; deplacementCursor(-3,-5,0) ; simpleBitmapOutput(DESSIN," TTF") ; setAlignement(CENTER); placeFontCursor(px1-0.1F,posy+0.1F,pz1+0.1F) ; simpleBitmapOutput(REGULAR8x13,"P1") ; placeFontCursor(px2+0.1F,posy+0.1F,pz2+0.1F) ; simpleBitmapOutput(REGULAR8x13,"P2") ; placeFontCursor(px+0.1F,posy+0.1F,pz+0.1F) ; simpleBitmapOutput(REGULAR8x13,"P") ; setAlignement(LEFT); glPopMatrix(); glPushMatrix(); placeFontCursor(-1.2F,-0.82F,0.1F) ; if ( posy > f.pb[1] ) { simpleBitmapOutput(REGULAR8x13,"N1 = Na+h1(Nb-Na)") ; } else { simpleBitmapOutput(REGULAR8x13,"N1 = Nb+h1(Nc-Nb)") ; } deplacementCursor(-3,-5,0) ; simpleBitmapOutput(DESSIN,"TTF TTF TTF TTF") ; placeFontCursor(-1.2F,-0.95F,0.1F) ; simpleBitmapOutput(REGULAR8x13,"N2 = Na+h2(Nc-Na)") ; deplacementCursor(-3,-5,0) ; simpleBitmapOutput(DESSIN,"TTF TTF TTF TTF") ; placeFontCursor(0.4F,-0.95F,0.1F) ; simpleBitmapOutput(REGULAR8x13,"N = N1+h(N2-N1)") ; deplacementCursor(-3,-5,0) ; simpleBitmapOutput(DESSIN,"TF TTF TTF TTF") ; glPopMatrix(); glFlush(); glutSwapBuffers(); glutPostWindowRedisplay(f2) ; } void special(int k,int x,int y) { if ( specialManipulateur(k,x,y) ) { glutPostWindowRedisplay(f1); } } void key2(unsigned char key,int x,int y) { switch ( key ) { case '4' : posx -= 0.01F; if ( posx < 0.0F ) posx = 0.0F; evaluationIntersections(); glutPostWindowRedisplay(f1) ; break ; case '6' : posx += 0.01F; if ( posx > 1.0F ) posx = 1.0F; evaluationIntersections(); glutPostWindowRedisplay(f1) ; break ; case 'd' : disc++ ; glutPostWindowRedisplay(f1) ; break ; case 'D' : disc-- ; if ( disc < 0 ) disc = 0; glutPostWindowRedisplay(f1) ; break ; case 43 : posy += 0.01F; if ( posy > f.pa[1] ) posy = f.pa[1]; evaluationIntersections(); glutPostWindowRedisplay(f1) ; break ; case 45 : posy -= 0.01F; if ( posy < f.pc[1] ) posy = f.pc[1]; evaluationIntersections(); glutPostWindowRedisplay(f1) ; break ; case ' ' : fleches = (fleches+1)%2 ; glutPostWindowRedisplay(f1) ; break ; case 0x0D : mode = (mode+1)%3 ; glutPostWindowRedisplay(f1) ; break ; case 0x1B : exit(0); break ; } } void key(unsigned char key,int x,int y) { if ( keyManipulateur(key,x,y) ) glutPostWindowRedisplay(f1); else key2(key,x,y); } void reshape2(int w,int h) { glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0,w,-h,0,-1.0,1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void display2() { glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glClearColor(0.0F,0.0F,0.0F,1.0F) ; glPushAttrib(GL_LIGHTING); glDisable(GL_LIGHTING); glPushMatrix(); glColor4fv(couleurBlanc()); float pos = 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"PA : %6.3f %6.3f %6.3f",f.pa[0],f.pa[1],f.pa[2]) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"PB : %6.3f %6.3f %6.3f",f.pb[0],f.pb[1],f.pb[2]) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"PC : %6.3f %6.3f %6.3f",f.pc[0],f.pc[1],f.pc[2]) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"NA : %6.3f %6.3f %6.3f",f.na[0],f.na[1],f.na[2]) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"NB : %6.3f %6.3f %6.3f",f.nb[0],f.nb[1],f.nb[2]) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"NC : %6.3f %6.3f %6.3f",f.nc[0],f.nc[1],f.nc[2]) ; glColor4fv(couleurBlanc()); pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"h1 : %6.3f",h1) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"P1 : %6.3f %6.3f %6.3f",px1,posy,pz1) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"h2 : %6.3f",h2) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"P2 : %6.3f %6.3f %6.3f",px2,posy,pz2) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"h : %6.3f",posx) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"P : %6.3f %6.3f %6.3f",px,posy,pz) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"N1 : %6.3f %6.3f %6.3f",n1[0],n1[1],n1[2]) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"N2 : %6.3f %6.3f %6.3f",n2[0],n2[1],n2[2]) ; pos += 1.0F; placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(REGULAR8x13,"N : %6.3f %6.3f %6.3f",n[0],n[1],n[2]) ; glPopMatrix(); glPopAttrib(); glutSwapBuffers(); } int main(int argc,char **argv) { glutInit(&argc,argv); normalise(l_pos); evaluationIntersections(); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(450,300); glutInitWindowPosition(10,50); f1 = glutCreateWindow("Schema Phong"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-1.0,1.0,-1.0,1.0,-5.0,5.0); setManipulateurDistance(1.0F); glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(special); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutDisplayFunc(display); glutInitWindowSize(260,310); glutInitWindowPosition(480,45); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); f2 = glutCreateWindow("Valeurs"); creationMenuBasique(); glutDisplayFunc(display2); glutReshapeFunc(reshape2); glutKeyboardFunc(key2); glutSpecialFunc(special); glutMainLoop(); return(0); }