/* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Juin 2001 */ /* Illustration de la reflexion speculaire */ #include #include #include #include #include #include #include "ModuleCouleurs.h" #include "ModuleDessinArc.h" #include "ModuleReshape.h" #include "ModuleManipulateur.h" #include "ModuleMenus.h" #include "ModuleFont.h" #include "ModuleFleche.h" #include "ModuleMatriceVecteur.h" static vecteur pl = { -0.4F,1.4F,1.1F,1.0F } ; static vecteur pi = { 0.4F,0.0F,0.6F } ; static vecteur n ; static vecteur l ; static vecteur r ; static float scal; static float fact = 2.0F; static int f1 ; static int f2 ; static float degres ; static float shininess = 40.0F; void myinit(void) { glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE) ; glDepthFunc(GL_LESS); glEnable(GL_ALPHA_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); glLightfv(GL_LIGHT0,GL_AMBIENT,couleurNoir()); glLightfv(GL_LIGHT0,GL_SPECULAR,couleurNoir()); glLightfv(GL_LIGHT1,GL_AMBIENT,couleurNoir()); glLightfv(GL_LIGHT1,GL_SPECULAR,couleurJaune()); glLightfv(GL_LIGHT2,GL_SPECULAR,couleurNoir()); glLightfv(GL_LIGHT2,GL_AMBIENT,couleurNoir()); float l2[4] = { 0.0F,1.0F,0.0F,0.0F }; glLightfv(GL_LIGHT2,GL_POSITION,l2); } void axes() { glPushMatrix() ; glColor4fv(couleurJaune()) ; glBegin(GL_LINES) ; glVertex3f(0.0F,0.0F,0.0F) ; glVertex3f(0.25F,0.0F,0.0F) ; glEnd() ; placeFontCursor(0.3F,0.05F,0.05F); simpleBitmapOutput(1,1,"x"); glColor4fv(couleurCyan()) ; glBegin(GL_LINES) ; glVertex3f(0.0F,0.0F,0.0F) ; glVertex3f(0.0F,0.25F,0.0F) ; glEnd() ; placeFontCursor(0.05F,0.3F,0.05F); simpleBitmapOutput(1,1,"y"); glColor4fv(couleurMagenta()) ; glBegin(GL_LINES) ; glVertex3f(0.0F,0.0F,0.0F) ; glVertex3f(0.0F,0.0F,0.25F) ; glEnd() ; placeFontCursor(0.05F,0.05F,0.3F); simpleBitmapOutput(1,1,"z"); glPopMatrix() ; } void solidHemisphere(double r,int n1,int n2) { vecteur **p =(vecteur **) calloc(n1,sizeof(vecteur *)); int i; for ( i = 0 ; i < n1 ; i++ ) p[i] =(vecteur *) calloc(n2,sizeof(vecteur)); for ( i = 0 ; i < n1 ; i++ ) { double a1 = i * 3.14159 / 2.0 / (n1-1); double csa1 = cos(a1); double sna1 = sin(a1); for ( int j = 0 ; j < n2 ; j++ ) { double a2 = j * 3.14159 * 2.0 / (n2-1); double csa2 = cos(a2); double sna2 = sin(a2); p[i][j][0] = csa2*csa1; p[i][j][2] = sna2*csa1; p[i][j][1] = sna1; } } glBegin(GL_QUADS); for ( i = 0 ; i < n1-1 ; i++ ) { for ( int j = 0 ; j < n2 ; j++ ) { glNormal3f(p[i+1][j][0],p[i+1][j][1],p[i+1][j][2]); glVertex3f(r*p[i+1][j][0],r*p[i+1][j][1],r*p[i+1][j][2]); glNormal3f(p[i+1][(j+1)%n2][0],p[i+1][(j+1)%n2][1],p[i+1][(j+1)%n2][2]); glVertex3f(r*p[i+1][(j+1)%n2][0],r*p[i+1][(j+1)%n2][1],r*p[i+1][(j+1)%n2][2]); glNormal3f(p[i][(j+1)%n2][0],p[i][(j+1)%n2][1],p[i][(j+1)%n2][2]); glVertex3f(r*p[i][(j+1)%n2][0],r*p[i][(j+1)%n2][1],r*p[i][(j+1)%n2][2]); glNormal3f(p[i][j][0],p[i][j][1],p[i][j][2]); glVertex3f(r*p[i][j][0],r*p[i][j][1],r*p[i][j][2]); } } glEnd(); for ( i = 0 ; i < n1 ; i++ ) free(p[i]); free(p); } void solidBaseHemisphere(double r,int n2) { vecteur *p =(vecteur *) calloc(n2,sizeof(vecteur)); int j; for ( j = 0 ; j < n2 ; j++ ) { double a2 = j * 3.14159 * 2.0 / (n2-1); double csa2 = cos(a2); double sna2 = sin(a2); p[j][0] = r*csa2; p[j][2] = r*sna2; p[j][1] = 0.0F; } glBegin(GL_POLYGON); glNormal3f(0.0F,-1.0F,0.0F); for ( j = 0 ; j < n2 ; j++ ) { glVertex3f(p[j][0],p[j][1],p[j][2]); } glEnd(); free(p); } static int estEgal(float a,float b) { return(fabs(a-b) < 0.00001) ; } void coneOriente(float dx,float dy,float dz,float cr,float cl) { glPushMatrix(); double d = pow((double) (dx*dx+dy*dy+dz*dz),0.5); glPushMatrix(); dx /= d; dy /= d; dz /= d; if ( estEgal(dz,-1.0F) ) glRotatef(180.0F,1.0F,0.0F,0.0F); else if ( !estEgal(dz,1.0F) ) { double a = acos(dz) * 180 / 3.14159; glRotatef(a,-dy,dx,0); } glPushMatrix(); glutSolidCone(cl,cr,36,20); glPopMatrix(); glPopMatrix(); glPopMatrix(); } void display(void) { glClearColor(0.7F,0.7F,0.6F,0.0F); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); manipulateurSouris(); manipulateurClavier(); glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurBlanc()); glLightfv(GL_LIGHT1,GL_DIFFUSE,couleurNoir()); glLightfv(GL_LIGHT2,GL_DIFFUSE,couleurBlanc()); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHT2); glTranslatef(0.0F,-0.65F,0.0F); float lreel[4] = { pl[0],pl[1],pl[2],1.0F }; glLightfv(GL_LIGHT1,GL_POSITION,lreel); { glPushMatrix(); glTranslatef(-0.4F,0.8F,-1.4F); axes(); glPopMatrix(); } glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,shininess); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,couleurNoir()); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,couleurNoir()); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurJaune()); { glPushMatrix(); glTranslatef(pl[0],pl[1],pl[2]); glutSolidSphere(0.06F,20,20); glPopMatrix(); } pi[1] = sqrt(1.0F-pi[0]*pi[0]-pi[2]*pi[2]); n[0] = pi[0]; n[1] = pi[1]; n[2] = pi[2]; normalise(n); l[0] = pl[0]-pi[0]; l[1] = pl[1]-pi[1]; l[2] = pl[2]-pi[2]; normalise(l); scal = produitScalaire(l,n); if ( scal > 0.0F ) { degres = atan2(1.0F/shininess*50,fact)*180.0F/3.14159F; r[0] = 2.0F*n[0]*scal-l[0]; r[1] = 2.0F*n[1]*scal-l[1]; r[2] = 2.0F*n[2]*scal-l[2]; } vecteur axe = { r[2],0.0F,-r[0] }; vecteur rd = { r[0],r[1],r[2] }; matrice m; toRotation(m,degres,axe[0],axe[1],axe[2]); produitMatriceVecteur(m,rd,rd); glDisable(GL_LIGHTING); glColor3fv(couleurVert()); vecteur pint; positionIntermediaire(rd,r,n,0.75F,pint); traceAngle(rd,r,n,20,0.75F,1); glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurBleu()); { glPushMatrix(); glDisable(GL_LIGHTING); glTranslatef(pi[0],pi[1],pi[2]); glColor3fv(couleurVert()); glBegin(GL_LINES); glVertex3f(0.0F,0.0F,0.0F); glVertex3f(rd[0]*2,rd[1]*2,rd[2]*2); glEnd(); glEnable(GL_LIGHTING); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurBleu()); glutSolidSphere(0.04F,20,20); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurJaune()); flecheEnVolume(pl[0]-pi[0],pl[1]-pi[1],pl[2]-pi[2],0.03F,0.1F,0.01F); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurRouge()); flecheEnVolume(l[0],l[1],l[2],0.03F,0.1F,0.012F); if ( scal > 0.0F ) { glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurVert()); flecheEnVolume(r[0],r[1],r[2],0.03F,0.1F,0.012F); } glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurMagenta()); flecheEnVolume(pi[0],pi[1],pi[2],0.03F,0.1F,0.01F); glPopMatrix(); } glDisable(GL_CULL_FACE); glEnable(GL_CULL_FACE); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurNoir()); glLightfv(GL_LIGHT1,GL_DIFFUSE,couleurBlanc()); glDisable(GL_LIGHT2); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,couleurJaune()); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurRougeFonce()); solidHemisphere(1.0,120,120); solidBaseHemisphere(1.0,120); glDisable(GL_CULL_FACE); glEnable(GL_LIGHT2); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,couleurNoir()); glLightfv(GL_LIGHT1,GL_DIFFUSE,couleurNoir()); glLightfv(GL_LIGHT0,GL_DIFFUSE,couleurBlanc()); glDisable(GL_LIGHTING); glColor3fv(couleurVert()); placeFontCursor(pint[0],pint[1],pint[2]) ; deplacementCursor(10,0,0) ; simpleBitmapOutput(1,SYMBOL,"q") ; deplacementCursor(20,0,0) ; simpleBitmapOutput(1,REGULAR8x13," = %6.2f",degres) ; glColor3fv(couleurJaune()); placeFontCursor(pl[0],pl[1],pl[2]) ; setAlignement(CENTER); deplacementCursor(0,-40,0) ; simpleBitmapOutput(1,REGULAR8x13,"LUMIERE") ; deplacementCursor(0,-20,0) ; simpleBitmapOutput(1,REGULAR8x13,"PONCTUELLE") ; glColor3fv(couleurMagenta()); placeFontCursor(2*pi[0],2*pi[1],2*pi[2]) ; deplacementCursor(15,5,0) ; simpleBitmapOutput(1,REGULAR8x13,"N") ; deplacementCursor(15,0,0) ; simpleBitmapOutput(1,DESSIN,"TF") ; glColor3fv(couleurRouge()); placeFontCursor(pi[0]+l[0],pi[1]+l[1],pi[2]+l[2]) ; deplacementCursor(5,-15,0) ; simpleBitmapOutput(1,REGULAR8x13,"L") ; deplacementCursor(5,-20,0) ; simpleBitmapOutput(1,DESSIN,"TF") ; glColor3fv(couleurVert()); placeFontCursor(pi[0]+r[0],pi[1]+r[1],pi[2]+r[2]) ; deplacementCursor(5,-15,0) ; simpleBitmapOutput(1,REGULAR8x13,"R") ; deplacementCursor(5,-20,0) ; simpleBitmapOutput(1,DESSIN,"TF") ; setAlignement(LEFT); glEnable(GL_LIGHTING); if ( scal > 0.0F ) { glPushMatrix(); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,couleurVert(0.5F)); glTranslatef(pi[0]+fact*r[0],pi[1]+fact*r[1],pi[2]+fact*r[2]); coneOriente(-r[0]*fact,-r[1]*fact,-r[2]*fact,fact,1.0F/shininess*50); glPopMatrix(); } glDisable(GL_LIGHTING); glPopMatrix(); glFlush(); glutPostWindowRedisplay(f2); glutSwapBuffers(); } void key2(unsigned char key,int x,int y) { switch ( key ) { case 45 : shininess *= 1.02F; glutPostWindowRedisplay(f1); break; case 43 : shininess /= 1.02F; glutPostWindowRedisplay(f1); break; case 'a' : pl[0] += 0.02F; glutPostWindowRedisplay(f1); break; case 'A' : pl[0] -= 0.02F; glutPostWindowRedisplay(f1); break; case 'q' : pl[1] += 0.02F; glutPostWindowRedisplay(f1); break; case 'Q' : pl[1] -= 0.02F; glutPostWindowRedisplay(f1); break; case 'w' : pl[2] += 0.02F; glutPostWindowRedisplay(f1); break; case 'W' : pl[2] -= 0.02F; glutPostWindowRedisplay(f1); break; case '4' : { float px = pi[0] - 0.02F; if ( px*px+pi[2]*pi[2] < 1.0F ) pi[0] = px ; glutPostWindowRedisplay(f1); } break; case '6' : { float px = pi[0] + 0.02F; if ( px*px+pi[2]*pi[2] < 1.0F ) pi[0] = px ; glutPostWindowRedisplay(f1); } break; case '2' : { float pz = pi[2] - 0.02F; if ( pz*pz+pi[0]*pi[0] < 1.0F ) pi[2] = pz ; glutPostWindowRedisplay(f1); } break; case '8' : { float pz = pi[2] + 0.02F; if ( pz*pz+pi[0]*pi[0] < 1.0F ) pi[2] = pz ; 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 display2(void) { glClearColor(0.0F,0.0F,0.0F,1.0F) ; glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glPushMatrix(); float pos = 1.0F; glColor4fv(couleurJaune()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"LUMIERE : %6.3f %6.3f %6.3f",pl[0],pl[1],pl[2]) ; pos += 1.0F; glColor4fv(couleurBleu()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"INTERSECTION : %6.3f %6.3f %6.3f",pi[0],pi[1],pi[2]) ; pos += 1.0F; glColor4fv(couleurMagenta()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"NORMALE : %6.3f %6.3f %6.3f",n[0],n[1],n[2]) ; pos += 1.0F; glColor4fv(couleurRouge()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"L : %6.3f %6.3f %6.3f",l[0],l[1],l[2]) ; pos += 1.0F; glColor4fv(couleurVert()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"REFLEXION : %6.3f %6.3f %6.3f",r[0],r[1],r[2]) ; pos += 1.0F; glColor4fv(couleurVert()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"THETA : %7.3f",degres) ; pos += 1.0F; glColor4fv(couleurVert()); placeFontCursor(5.0F,-pos*20.0F,0.0F) ; simpleBitmapOutput(1,REGULAR8x13,"SHININESS : %7.3f",shininess) ; glPopMatrix(); glFlush(); glutSwapBuffers(); } void special(int key,int x,int y) { if ( specialManipulateur(key,x,y) ) { glutPostWindowRedisplay(f1); } } 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(); } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH); glutInitWindowPosition(10,10); glutInitWindowSize(400,270); f1 = glutCreateWindow("La reflexion speculaire"); myinit(); creationMenuBasique(); setParametresOrthoBasique(-1.1F,1.1F,-1.1F,1.1F,-50.0,50.0); setManipulateurDistance(1.0F); setManipulateurClavierAngle(15.0F,-50.0F,0.0F) ; glutReshapeFunc(reshapeOrthoBasique); glutKeyboardFunc(key); glutSpecialFunc(specialBasique); glutMotionFunc(motionBasique); glutMouseFunc(sourisBasique); glutDisplayFunc(display); glutInitWindowSize(370,150); glutInitWindowPosition(60,360); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); f2 = glutCreateWindow("Valeurs"); creationMenuBasique(); glutDisplayFunc(display2); glutReshapeFunc(reshape2); glutKeyboardFunc(key2); glutSpecialFunc(special); glutMainLoop(); return(0); } /* ************************************************** */