00001
00028 #include "GLvis_.h"
00029
00030
00031 struct vertex_
00032 {
00033 float x;
00034 float y;
00035 float z;
00036 float nx;
00037 float ny;
00038 float nz;
00039 char nb;
00040 };
00041
00042
00043 struct image_GL_
00044 {
00045 char *terrain;
00046 char nom[80];
00047 float rapport;
00048 Fort_int lfmt[9];
00049 };
00050
00051
00052
00056 unsigned char afficheRepere = TRUE;
00060 unsigned char faceArriere=TRUE;
00064 unsigned char areteTransv=FALSE;
00068 unsigned char afficheNormales=FALSE;
00072 unsigned char afficheLampes=TRUE;
00076 unsigned char modePlein=TRUE;
00080 int repere=0,terrain=0,normales=0,lampes=0;
00084 int nbSubdiv=NB_SUBDIV_INIT;
00088 int nbSubdiv_max;
00092 float echelleVert=ECHELLE_VERT_INIT;
00096 char b_gauche=0,b_droit=0;
00100 int theta=-30,phi=300;
00104 int xprec,yprec;
00108 float distance=DISTANCE_INIT;
00112 int time_flag_level=0;
00116 int nb_terrains;
00120 image_GL * terrains_GL=NULL;
00124 int terrain_courant=0;
00125
00129 GLfloat L0pos[]={0.0,2.0,1.0},L0dif[]={0.3,0.3,0.8},L1pos[]={2.0,2.0,2.0},L1dif[]={0.5,0.5,0.5},Mspec[]={0.5,0.5,0.5},Mshiny=50;
00130
00131 extern void imerror ( int code, char * format, ...);
00132
00150 void visualisation(char ** noms_images,int nb_images,char * texture2D,int texture_flag,int time_flag,int repere_flag,int fil_de_fer_flag,int nbSubdivmax,int nb_voulu,float marge,int argc,char ** argv)
00151 {
00152 int i;
00153 clock_t t0=0,t1=0;
00154
00155 struct nf_fmt gfmt;
00156
00157
00158
00159
00160 if(texture_flag)
00161 nb_terrains=strlen(texture2D);
00162
00163
00164 nb_terrains=0;
00165
00166
00167 if (time_flag)
00168 t0 = clock();
00169 time_flag_level=time_flag;
00170
00171 for (i=0;i<9;i++)
00172 (gfmt.lfmt)[i]=0;
00173 for (i=0;i<3;i++)
00174 (gfmt.offsets)[i]=0;
00175 gfmt.maille=0;
00176 gfmt.bias=0;
00177 gfmt.scale=1;
00178
00179 afficheRepere=!repere_flag;
00180 modePlein=!fil_de_fer_flag;
00181 if (nbSubdivmax)
00182 nbSubdiv_max=nbSubdivmax;
00183
00184
00185 glutInit(&argc,argv);
00186 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
00187 glutInitWindowSize(800,600);
00188 glutCreateWindow(noms_images[terrain_courant]);
00189
00190
00191
00192 initGL();
00193
00194 for (i=0;i<nb_images;i++)
00195 {
00196 fprintf(stderr,"chargement de %s...",noms_images[i]);
00197 chargeImage(noms_images[i],&nb_terrains,&gfmt,nb_voulu,marge,max(0,time_flag -1));
00198 fprintf(stderr,"[OK]\n");
00199 }
00200
00201
00202 creeRepere();
00203 creeLampes();
00204 creeTerrain(max(0,time_flag-1));
00205
00206 if (time_flag)
00207 {
00208 t1=clock()-t0;
00209 printf("visualisation: temps mis: %f secondes\n",t1/(float)CLOCKS_PER_SEC);
00210 }
00211
00212 glutMainLoop();
00213 }
00214
00225 void chargeImage(char *nom,int * num_plans,struct nf_fmt * gfmt,int nb_voulu,float marge,int time_flag)
00226 {
00227 struct image * img;
00228
00229 img=image_(nom,"e","",gfmt);
00230 if ((gfmt->lfmt)[I_NDIMZ]==1)
00231
00232 chargeSurface2D(img,nom,num_plans,gfmt->lfmt,time_flag);
00233 else
00234
00235 chargeFamilleSurfaces(img,nom,num_plans,nb_voulu,marge,gfmt->lfmt,time_flag);
00236
00237 fermnf_(&img);
00238 }
00239
00253 void chargeSurface2D(struct image * img,char * nom,int *num_plans,Fort_int lfmt2D[9],int time_flag)
00254 {
00255 int i;
00256 int buff_size=buffer_size(lfmt2D,lfmt2D[I_DIMY]);
00257 char * buffer=i_malloc(buff_size);
00258 clock_t t0=0,t1=0;
00259 Fort_int tmp_lfmt[9];
00260
00261
00262 if (time_flag)
00263 t0 = clock();
00264
00265 lecflt_(&img,&(lfmt2D[I_DIMY]),buffer);
00266
00267 for (i=0;i<9;i++)
00268 tmp_lfmt[i]=lfmt2D[i];
00269 tmp_lfmt[I_NDIMX]=nbSubdiv_max;
00270 tmp_lfmt[I_NDIMY]=nbSubdiv_max;
00271 tmp_lfmt[I_NDIMZ]=1;
00272 tmp_lfmt[I_NDIMV]=1;
00273 tmp_lfmt[I_DIMX]=nbSubdiv_max;
00274 tmp_lfmt[I_DIMY]=tmp_lfmt[I_NDIMY]*tmp_lfmt[I_NDIMZ];
00275 tmp_lfmt[I_BSIZE]=4;
00276
00277
00278 terrains_GL=(image_GL *)realloc(terrains_GL,((*num_plans)+1)*sizeof(image_GL));
00279
00280 strcpy(terrains_GL[*num_plans].nom,nom);
00281
00282 for (i=0;i<9;i++)
00283 terrains_GL[*num_plans].lfmt[i]=tmp_lfmt[i];
00284
00285 terrains_GL[*num_plans].terrain=resize_image(buffer,lfmt2D,tmp_lfmt,0,0,max(0,time_flag-1));
00286 terrains_GL[*num_plans].rapport=(float)(lfmt2D)[I_NDIMX]/(float)(lfmt2D)[I_NDIMY];
00287 (*num_plans)++;
00288
00289 if (time_flag)
00290 {
00291 t1=clock()-t0;
00292 printf("chargeSurface2D: temps mis: %f secondes\n",t1/(float)CLOCKS_PER_SEC);
00293 }
00294 }
00295
00311 void chargeFamilleSurfaces(struct image * img,char * nom,int * num_plans,int nb_voulu,float marge,Fort_int lfmt_in[9],int time_flag)
00312 {
00313 clock_t t0=0,t1=0;
00314 struct nf_fmt gfmt_in,gfmt_out;
00315 Fort_int tmp_lfmt[9];
00316
00317 char ** buff_famille;
00318 int i,j,nb_isosurfs,nv_zero=0;
00319
00320 char tmp_nom[80];
00321
00322
00323 if (time_flag)
00324 t0 = clock();
00325
00326
00327 for (i=0;i<9;i++)
00328 gfmt_in.lfmt[i]=lfmt_in[i];
00329 for (i=0;i<3;i++)
00330 gfmt_in.offsets[i]=0;
00331 gfmt_in.maille=0;
00332 gfmt_in.bias=0;
00333 gfmt_in.scale=0;
00334
00335
00336 for (i=0;i<9;i++)
00337 tmp_lfmt[i]=lfmt_in[i];
00338 tmp_lfmt[I_NDIMX]=nbSubdiv_max;
00339 tmp_lfmt[I_NDIMY]=nbSubdiv_max;
00340 tmp_lfmt[I_NDIMZ]=1;
00341 tmp_lfmt[I_NDIMV]=1;
00342 tmp_lfmt[I_DIMX]=nbSubdiv_max;
00343 tmp_lfmt[I_DIMY]=tmp_lfmt[I_NDIMY]*tmp_lfmt[I_NDIMZ];
00344 tmp_lfmt[I_BSIZE]=4;
00345
00346
00347
00348 buff_famille=separation(img,gfmt_in,&gfmt_out,marge,nb_voulu,&nv_zero,max(time_flag-1,0));
00349
00350
00351
00352 nb_isosurfs=gfmt_out.lfmt[I_NDIMZ];
00353
00354 terrains_GL=(image_GL *)realloc(terrains_GL,((*num_plans)+nb_isosurfs)*sizeof(image_GL));
00355
00356 for (i=0;i<nb_isosurfs;i++)
00357 {
00358 sprintf(tmp_nom,"%s.iso%d",nom,i-nv_zero);
00359 strcpy(terrains_GL[*num_plans+i].nom,tmp_nom);
00360 for (j=0;j<9;j++)
00361 terrains_GL[*num_plans+i].lfmt[j]=tmp_lfmt[j];
00362 terrains_GL[*num_plans+i].terrain=resize_image(buff_famille[i],lfmt_in,tmp_lfmt,0,0,max(0,time_flag-1));
00363 terrains_GL[*num_plans+i].rapport=(float)(lfmt_in)[I_NDIMX]/(float)(lfmt_in)[I_NDIMY];
00364 }
00365 (*num_plans)+=i;
00366
00367
00368 for (i=0;i<nb_isosurfs;i++)
00369 i_Free(&(buff_famille[i]));
00370 free(buff_famille);
00371 buff_famille=NULL;
00372
00373 if (time_flag)
00374 {
00375 t1=clock()-t0;
00376 printf("chargeFamilleSurfaces: temps mis: %f secondes\n",t1/(float)CLOCKS_PER_SEC);
00377 }
00378 }
00379
00389 void initGL()
00390 {
00391
00392 glClearColor(0.8,0.8,0.8,1.0);
00393
00394 glEnable(GL_DEPTH_TEST);
00395
00396
00397 if (modePlein)
00398 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
00399 else
00400 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
00401
00402
00403 glCullFace(GL_BACK);
00404 if (faceArriere)
00405 glDisable(GL_CULL_FACE);
00406 else
00407 glEnable(GL_CULL_FACE);
00408
00409
00410 glMatrixMode(GL_PROJECTION);
00411 glLoadIdentity();
00412 gluPerspective(45.0,1.0,0.1,20.0);
00413 glMatrixMode(GL_MODELVIEW);
00414
00415
00416 glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE);
00417 glEnable(GL_LIGHTING);
00418 glEnable(GL_LIGHT0);
00419 glEnable(GL_LIGHT1);
00420 glLightfv(GL_LIGHT0,GL_DIFFUSE,L0dif);
00421 glLightfv(GL_LIGHT0,GL_SPECULAR,L0dif);
00422 glLightfv(GL_LIGHT1,GL_DIFFUSE,L1dif);
00423 glLightfv(GL_LIGHT1,GL_SPECULAR,L1dif);
00424
00425
00426 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Mspec);
00427 glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,Mshiny);
00428
00429
00430 glutDisplayFunc(affichage);
00431 glutKeyboardFunc(clavier);
00432 glutMouseFunc(souris);
00433 glutMotionFunc(mouvement);
00434 glutReshapeFunc(redim);
00435 }
00436
00444 void affichage()
00445 {
00446 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00447 glLoadIdentity();
00448 gluLookAt(0.0,0.0,distance,0.0,0.0,0.0,0.0,1.0,0.0);
00449 glRotatef(phi,1.0,0.0,0.0);
00450 glRotatef(theta,0.0,0.0,1.0);
00451 glLightfv(GL_LIGHT0,GL_POSITION,L0pos);
00452 glLightfv(GL_LIGHT1,GL_POSITION,L1pos);
00453 if (afficheLampes)
00454 glCallList(lampes);
00455 glCallList(terrain);
00456 if (afficheNormales)
00457 glCallList(normales);
00458 if (afficheRepere)
00459 glCallList(repere);
00460 glutSwapBuffers();
00461 }
00462
00472 void clavier(unsigned char touche,int x,int y)
00473 {
00474 switch (touche) {
00475 case 3:
00476 case 4:
00477 case 'q':
00478 case 27:
00479 exit(0);
00480 case '+':
00481 if (nbSubdiv!=nbSubdiv_max)
00482 {
00483 nbSubdiv++;
00484 creeTerrain(time_flag_level);
00485 glutPostRedisplay();
00486 }
00487 break;
00488 case '-':
00489 if (nbSubdiv!=1)
00490 {
00491 nbSubdiv--;
00492 creeTerrain(time_flag_level);
00493 glutPostRedisplay();
00494 }
00495 break;
00496 case 'p':
00497 echelleVert+=0.02;
00498 if (echelleVert>ECHELLE_VERT_MAX)
00499 echelleVert=ECHELLE_VERT_MAX;
00500 creeTerrain(time_flag_level);
00501 glutPostRedisplay();
00502 break;
00503 case 'o':
00504 echelleVert-=0.02;
00505 if (echelleVert<-ECHELLE_VERT_MAX)
00506 echelleVert=-ECHELLE_VERT_MAX;
00507 creeTerrain(time_flag_level);
00508 glutPostRedisplay();
00509 break;
00510 case 'f':
00511 modePlein=1-modePlein;
00512 if (modePlein)
00513 glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
00514 else
00515 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
00516 glutPostRedisplay();
00517 break;
00518 case 'n':
00519 afficheNormales=1-afficheNormales;
00520 glutPostRedisplay();
00521 break;
00522
00523 case 'r':
00524 afficheRepere=1-afficheRepere;
00525 glutPostRedisplay();
00526 break;
00527 case 'l' :
00528 afficheLampes=1-afficheLampes;
00529 glutPostRedisplay();
00530 break;
00531 case 'c':
00532 faceArriere=1-faceArriere;
00533 if (faceArriere)
00534 glDisable(GL_CULL_FACE);
00535 else
00536 glEnable(GL_CULL_FACE);
00537 glutPostRedisplay();
00538 break;
00539 case 't':
00540 areteTransv=1-areteTransv;
00541 creeTerrain(time_flag_level);
00542 glutPostRedisplay();
00543 break;
00544 case '>':
00545 terrain_courant=(terrain_courant+1)%nb_terrains;
00546 creeTerrain(time_flag_level);
00547 glutSetWindowTitle(terrains_GL[terrain_courant].nom);
00548 glutSetIconTitle(terrains_GL[terrain_courant].nom);
00549 glutPostRedisplay();
00550 break;
00551 case '<':
00552 terrain_courant=(terrain_courant+nb_terrains-1)%nb_terrains;
00553 creeTerrain(time_flag_level);
00554 glutSetWindowTitle(terrains_GL[terrain_courant].nom);
00555 glutSetIconTitle(terrains_GL[terrain_courant].nom);
00556 glutPostRedisplay();
00557 break;
00558 default:
00559
00560 fprintf(stderr,"appui de %i,position:(%i,%i)\n",(int)touche,x,y);
00561 break;
00562 }
00563 }
00564
00575 void souris(int bouton,int etat,int x,int y)
00576 {
00577 if (bouton == GLUT_LEFT_BUTTON && etat == GLUT_DOWN) {
00578 b_gauche = 1;
00579 xprec = x;
00580 yprec=y;
00581 }
00582 if (bouton == GLUT_LEFT_BUTTON && etat == GLUT_UP)
00583 b_gauche=0;
00584
00585 if (bouton == GLUT_RIGHT_BUTTON && etat == GLUT_DOWN) {
00586 b_droit = 1;
00587 yprec=y;
00588 }
00589 if (bouton == GLUT_RIGHT_BUTTON && etat == GLUT_UP)
00590 b_droit=0;
00591 }
00592
00603 void mouvement(int x,int y)
00604 {
00605
00606 if (b_gauche) {
00607 theta+=x-xprec;
00608 if (theta>=360)
00609 while (theta>=360)
00610 theta-=360;
00611 phi+=y-yprec;
00612 if (phi<0)
00613 while (phi<0)
00614 phi+=360;
00615 xprec=x;
00616 yprec=y;
00617 glutPostRedisplay();
00618 }
00619
00620
00621 if (b_droit) {
00622 distance+=((float)(y-yprec))/50.0;
00623 if (distance<1.0)
00624 distance=1.0;
00625 if (distance>DISTANCE_MAX)
00626 distance=DISTANCE_MAX;
00627 glutPostRedisplay();
00628 yprec=y;
00629 }
00630 }
00631
00638 void redim(int l,int h)
00639 {
00640 if (l<h)
00641 glViewport(0,(h-l)/2,l,l);
00642 else
00643 glViewport((l-h)/2,0,h,h);
00644 }
00645
00654 void creeRepere()
00655 {
00656 repere=glGenLists(1);
00657 glNewList(repere,GL_COMPILE);
00658 glDisable(GL_LIGHTING);
00659 glLineWidth(2.0);
00660 glBegin(GL_LINES);
00661 glColor3f(1.0,0.0,0.0);
00662 glVertex3f(0.0,0.0,0.0);
00663 glVertex3f(0.3,0.0,0.0);
00664 glColor3f(0.0,1.0,0.0);
00665 glVertex3f(0.0,0.0,0.0);
00666 glVertex3f(0.0,0.3,0.0);
00667 glColor3f(0.0,0.0,1.0);
00668 glVertex3f(0.0,0.0,0.0);
00669 glVertex3f(0.0,0.0,0.3);
00670 glEnd();
00671 glEnable(GL_LIGHTING);
00672 glEndList();
00673 }
00674
00675
00682 void creeLampes()
00683 {
00684 lampes=glGenLists(1);
00685 glNewList(lampes,GL_COMPILE);
00686 glDisable(GL_LIGHTING);
00687 glColor3f(1.0,1.0,1.0);
00688 glPointSize(6.0);
00689 glBegin(GL_POINTS);
00690 glVertex3fv(L0pos);
00691 glVertex3fv(L1pos);
00692 glEnd();
00693 glLineWidth(1.0);
00694 glBegin(GL_LINES);
00695 glVertex3fv(L0pos);
00696 glVertex3f(0.0,0.0,0.0);
00697 glVertex3fv(L1pos);
00698 glVertex3f(0.0,0.0,0.0);
00699 glEnd();
00700 glEnable(GL_LIGHTING);
00701 glEndList();
00702 }
00703
00713 void creeTerrain(int time_flag)
00714 {
00715 float rapport=(terrains_GL[terrain_courant]).rapport;
00716 char * retour=(terrains_GL[terrain_courant]).terrain;
00717 int i,j;
00718 float x_T_pas=2.0/nbSubdiv;
00719 float y_T_pas=(2.0/nbSubdiv)*rapport;
00720 float pas=((float)(terrains_GL[terrain_courant]).lfmt[I_NDIMX]-1.0)/nbSubdiv;
00721
00722 vertex *T;
00723 vertex *P1,*P2,*P3,*P4;
00724 vertex V1,V2,V3;
00725 float incx,incy,incz,norme;
00726 clock_t t0=0,t1=0;
00727 T=(vertex *)malloc((nbSubdiv+1)*(nbSubdiv+1)*sizeof(vertex));
00728
00729
00730 if (time_flag)
00731 t0=clock();
00732
00733
00734 for (i=0;i<=nbSubdiv;i++)
00735 for (j=0;j<=nbSubdiv;j++) {
00736 T[i*(nbSubdiv+1)+j].nx=0.0;
00737 T[i*(nbSubdiv+1)+j].ny=0.0;
00738 T[i*(nbSubdiv+1)+j].nz=0.0;
00739 }
00740
00741 for (i=0;i<=nbSubdiv;i++)
00742 for (j=0;j<=nbSubdiv;j++) {
00743 T[i*(nbSubdiv+1)+j].x=-1.0+i*x_T_pas;
00744 T[i*(nbSubdiv+1)+j].y=(-1.0*rapport+j*y_T_pas);
00745 T[i*(nbSubdiv+1)+j].z=value(retour,(int)((float)j*pas),(int)((float)i*pas),(terrains_GL[terrain_courant]).lfmt)*echelleVert;
00746 }
00747
00748 for (i=0;i<nbSubdiv;i++)
00749 for (j=0;j<nbSubdiv;j++) {
00750 P1=&T[i*(nbSubdiv+1)+j];
00751 P2=&T[(i+1)*(nbSubdiv+1)+j];
00752 P3=&T[(i+1)*(nbSubdiv+1)+j+1];
00753 P4=&T[i*(nbSubdiv+1)+j+1];
00754
00755 V1.x=P2->x-P1->x; V1.y=P2->y-P1->y; V1.z=P2->z-P1->z;
00756 V2.x=P3->x-P1->x; V2.y=P3->y-P1->y; V2.z=P3->z-P1->z;
00757 V3.x=P4->x-P1->x; V3.y=P4->y-P1->y; V3.z=P4->z-P1->z;
00758
00759 incx=V2.y*V1.z-V1.y*V2.z;
00760 incy=V2.z*V1.x-V1.z*V2.x;
00761 incz=V2.x*V1.y-V1.x*V2.y;
00762 norme=sqrt(incx*incx+incy*incy+incz*incz);
00763 incx/=norme; incy/=norme; incz/=norme;
00764 P1->nx-=incx; P1->ny-=incy; P1->nz-=incz;
00765 P2->nx-=incx; P2->ny-=incy; P2->nz-=incz;
00766 P3->nx-=incx; P3->ny-=incy; P3->nz-=incz;
00767
00768
00769 incx=V3.y*V2.z-V2.y*V3.z;
00770 incy=V3.z*V2.x-V2.z*V3.x;
00771 incz=V3.x-V2.y-V2.x*V3.y;
00772 P1->nx-=incx; P1->ny-=incy; P1->nz-=incz;
00773 P3->nx-=incx; P3->ny-=incy; P3->nz-=incz;
00774 P4->nx-=incx; P4->ny-=incy; P4->nz-=incz;
00775 }
00776
00777
00778 for (i=0;i<=nbSubdiv;i++)
00779 for (j=0;j<=nbSubdiv;j++) {
00780 P1=&T[i*(nbSubdiv+1)+j];
00781 norme=sqrt(P1->nx*P1->nx+P1->ny*P1->ny+P1->nz*P1->nz);
00782 P1->nx/=norme;
00783 P1->ny/=norme;
00784 P1->nz/=norme;
00785 }
00786
00787
00788 if (glIsList(terrain))
00789 glDeleteLists(terrain,1);
00790 terrain=glGenLists(1);
00791 glNewList(terrain,GL_COMPILE);
00792 glColor3f(0.0,0.0,0.0);
00793 glLineWidth(1.0);
00794 for (i=0;i<nbSubdiv;i++)
00795 for (j=0;j<nbSubdiv;j++) {
00796 glBegin(GL_TRIANGLES);
00797
00798 glEdgeFlag(TRUE);
00799 drawVertex(i,j,T);
00800 drawVertex(i+1,j,T);
00801 if (!areteTransv)
00802 glEdgeFlag(FALSE);
00803 drawVertex(i+1,j+1,T);
00804
00805
00806 drawVertex(i,j,T);
00807 if (!areteTransv)
00808 glEdgeFlag(TRUE);
00809 drawVertex(i+1,j+1,T);
00810 drawVertex(i,j+1,T);
00811 glEnd();
00812 }
00813 glEndList();
00814
00815
00816 creeNormales(T);
00817
00818
00819 free(T);
00820
00821 if (time_flag)
00822 {
00823 t1=clock()-t0;
00824 fprintf(stderr,"creeTerrain: temps mis: %f secondes\n",t1/(float)CLOCKS_PER_SEC);
00825 }
00826 }
00827
00835 void creeNormales(vertex *T)
00836 {
00837 int i,j;
00838 vertex *P;
00839 if (glIsList(normales))
00840 glDeleteLists(normales,1);
00841 normales=glGenLists(1);
00842 glNewList(normales,GL_COMPILE);
00843 glDisable(GL_LIGHTING);
00844 glLineWidth(1.0);
00845 glColor3f(1.0,1.0,1.0);
00846 glBegin(GL_LINES);
00847 for (i=0;i<=nbSubdiv;i++)
00848 for (j=0;j<=nbSubdiv;j++) {
00849 P=&T[i*(nbSubdiv+1)+j];
00850 glVertex3fv(&P->x);
00851 glVertex3f(P->x+ECHELLE_NORMALES*P->nx,
00852 P->y+ECHELLE_NORMALES*P->ny,
00853 P->z+ECHELLE_NORMALES*P->nz);
00854 }
00855 glEnd();
00856 glEnable(GL_LIGHTING);
00857 glEndList();
00858 }
00859
00867 void drawVertex(int i,int j,vertex *T)
00868 {
00869 glNormal3fv(&(T[i*(nbSubdiv+1)+j].nx));
00870 glVertex3fv(&(T[i*(nbSubdiv+1)+j].x));
00871 }