Placage de texture (2/2)
Par Xavier Michelon


 
 
Code source :

/**************/ /* Texture2.c */ /**************/ #include <stdio.h> #include <stdlib.h> #include <GL/glut.h> #include <tiffio.h> #include <string.h> #include <math.h> #define PI 3.14159265 /* declaration des variables */ float distance=2.5; /* distance de l'observateur a l'origine */ int anglex=30,angley=20,xprec,yprec; /* stockage des déplacements de souris */ GLbitfield masqueClear; /* masque pour l'utilisation de glClear() */ GLfloat couleurAP[]={0.8,0.8,0.8,1.0}; /* couleur de fond */ int IdTex[2]; /* tableau d'Id pour les 2 textures */ float decalage=0; /* décalage de la texture procedurale pour l'animation */ /* Parametres de lumière */ GLfloat L0pos[]={ 0.0,2.0,-1.0}; GLfloat L0dif[]={ 1.0,0.6,0.6}; GLfloat L1pos[]={ 2.0,2.0,2.0}; GLfloat L1dif[]={ 0.0,0.5,1.0}; GLfloat Mspec[]={0.5,0.5,0.5}; GLfloat Mshiny=50; /* déclaration des indicateurs booleens */ unsigned char b_gauche=0; /* le bouton gauche de la souris est il presse ? */ unsigned char b_droit=0; /* le bouton gauche de la souris est il presse ? */ unsigned char prof=1; /* Tampon de profondeur */ unsigned char brouillard=0; /* brouillard */ unsigned char eclairage=1; /* eclairage */ unsigned char separe=1; /* séparation de la composante spéculaire pour l'éclairage des textures */ /* prototypes des fonctions */ void init(); void affichage(); void clavier(unsigned char key,int x,int y); void souris(int button, int state,int x,int y); void mouvSouris(int x,int y); void redim(int w,int h); void inactif(); void chargeTextureTiff(char *fichier,int numtex); void chargeTextureProc(int numtex); int fonctionTexture(int x,int y); /**********************************/ /* int main(int argc,char **argv) */ /**********************************/ /* fonction principale */ /**********************************/ int main(int argc,char **argv) { /* initialisation de glut */ glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE); glutInitWindowSize(400,400); glutCreateWindow(argv[0]); /* Chargement des textures */ glGenTextures(2,IdTex); chargeTextureTiff("texture.tif",IdTex[0]); chargeTextureProc(IdTex[1]); /* initialisation d'OpenGL */ init(); /* mise en place des fonctions de rappel glut */ glutDisplayFunc(affichage); glutKeyboardFunc(clavier); glutMouseFunc(souris); glutMotionFunc(mouvSouris); glutReshapeFunc(redim); glutIdleFunc(inactif); /* Boucle principale */ glutMainLoop(); return 0; } /***************************/ /* void init() */ /***************************/ /* Initialisation d'OpenGL */ /***************************/ void init() { /* Parametres de base */ glClearColor(couleurAP[0],couleurAP[1],couleurAP[2],couleurAP[3]); glColor3f(1.0,1.0,1.0); glShadeModel(GL_SMOOTH); /* Parametres de perspective */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0,1,0.1,16.0); glMatrixMode(GL_MODELVIEW); /* Paramètres d'eclaraiage */ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER,GL_TRUE); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glLightfv(GL_LIGHT0,GL_DIFFUSE,L0dif); glLightfv(GL_LIGHT0,GL_SPECULAR,L0dif); glLightfv(GL_LIGHT1,GL_DIFFUSE,L1dif); glLightfv(GL_LIGHT1,GL_SPECULAR,L1dif); if (eclairage) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); if (separe) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR); else glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR); /* Paramétres du matériau */ glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,Mspec); glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,Mshiny); /* Mise en place des textures */ glEnable(GL_TEXTURE_2D); /* mise en place du tampon de profondeur */ if (prof) { masqueClear=GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; glEnable(GL_DEPTH_TEST); } else { masqueClear=GL_COLOR_BUFFER_BIT; glDisable(GL_DEPTH_TEST); } /* Mise en place du brouillard */ glFogi(GL_FOG_MODE,GL_EXP); glFogfv(GL_FOG_COLOR,couleurAP); glFogf(GL_FOG_START,0); glFogf(GL_FOG_END,15); glFogf(GL_FOG_DENSITY,0.35); if (brouillard) glEnable(GL_FOG); else glDisable(GL_FOG); } /***************************************/ /* void affichage() */ /***************************************/ /* fonction de rappel pour l'affichage */ /***************************************/ void affichage() { glClear(masqueClear); /* Positionnement de l'observateur (ou de l'objet) */ glLoadIdentity(); gluLookAt(0.0,0.0,distance,0.0,0.0,0.0,0.0,1.0,0.0); glRotatef(angley,1.0,0.0,0.0); glRotatef(anglex,0.0,1.0,0.0); /* Description de l'obet */ glBindTexture(GL_TEXTURE_2D,IdTex[0]); glBegin(GL_POLYGON); glNormal3f(0.0,0.0,1.0); glTexCoord2f(0.0,1.0); glVertex3f(-0.5, 0.5, 0.5); glTexCoord2f(0.0,0.0); glVertex3f(-0.5,-0.5, 0.5); glTexCoord2f(1.0,0.0); glVertex3f( 0.5,-0.5, 0.5); glTexCoord2f(1.0,1.0); glVertex3f( 0.5, 0.5, 0.5); glEnd(); glBindTexture(GL_TEXTURE_2D,IdTex[1]); glBegin(GL_POLYGON); glNormal3f(1.0,0.0,0.0); glTexCoord2f(0.0,1.0); glVertex3f( 0.5, 0.5, 0.5); glTexCoord2f(0.0,0.0); glVertex3f( 0.5,-0.5, 0.5); glTexCoord2f(1.0,0.0); glVertex3f( 0.5,-0.5,-0.5); glTexCoord2f(1.0,1.0); glVertex3f( 0.5, 0.5,-0.5); glEnd(); glBindTexture(GL_TEXTURE_2D,IdTex[0]); glBegin(GL_POLYGON); glNormal3f(0.0,0.0,-1.0); glTexCoord2f(0.0,1.0); glVertex3f( 0.5, 0.5,-0.5); glTexCoord2f(0.0,0.0); glVertex3f( 0.5,-0.5,-0.5); glTexCoord2f(1.0,0.0); glVertex3f(-0.5,-0.5,-0.5); glTexCoord2f(1.0,1.0); glVertex3f(-0.5, 0.5,-0.5); glEnd(); glBindTexture(GL_TEXTURE_2D,IdTex[1]); glBegin(GL_POLYGON); glNormal3f(-1.0,0.0,0.0); glTexCoord2f(0.0,1.0); glVertex3f(-0.5, 0.5,-0.5); glTexCoord2f(0.0,0.0); glVertex3f(-0.5,-0.5,-0.5); glTexCoord2f(1.0,0.0); glVertex3f(-0.5,-0.5, 0.5); glTexCoord2f(1.0,1.0); glVertex3f(-0.5, 0.5, 0.5); glEnd(); glBindTexture(GL_TEXTURE_2D,IdTex[0]); glBegin(GL_POLYGON); glNormal3f(0.0,1.0,0.0); glTexCoord2f(0.0,1.0); glVertex3f(-0.5, 0.5,-0.5); glTexCoord2f(0.0,0.0); glVertex3f(-0.5, 0.5, 0.5); glTexCoord2f(1.0,0.0); glVertex3f( 0.5, 0.5, 0.5); glTexCoord2f(1.0,1.0); glVertex3f( 0.5, 0.5,-0.5); glEnd(); glBindTexture(GL_TEXTURE_2D,IdTex[1]); glBegin(GL_POLYGON); glNormal3f(0.0,-1.0,0.0); glTexCoord2f(0.0,0.0); glVertex3f(-0.5,-0.5,-0.5); glTexCoord2f(0.0,1.0); glVertex3f(-0.5,-0.5, 0.5); glTexCoord2f(1.0,1.0); glVertex3f( 0.5,-0.5, 0.5); glTexCoord2f(1.0,0.0); glVertex3f( 0.5,-0.5,-0.5); glEnd(); /* echange de tampon (double buffering)*/ glutSwapBuffers(); } /**************************************************/ /* void clavier(unsigned char touche,int x,int y) */ /**************************************************/ /* fonction de rappel clavier */ /**************************************************/ void clavier(unsigned char touche,int x,int y) { switch (touche) { case 'p': /* bascule tampon de profondeur */ prof=1-prof; if (prof) { masqueClear=GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT; glEnable(GL_DEPTH_TEST); } else { masqueClear=GL_COLOR_BUFFER_BIT; glDisable(GL_DEPTH_TEST); } glutPostRedisplay(); break; case 'b': /* bascule brouillard */ brouillard=1-brouillard; if (brouillard) glEnable(GL_FOG); else glDisable(GL_FOG); glutPostRedisplay(); break; case 'e' : /* bascule eclairage */ eclairage=1-eclairage; if (eclairage) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); glutPostRedisplay(); break; case 's' : /* bascule séparation eclairage speculaire */ separe=1-separe; if (separe) glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SEPARATE_SPECULAR_COLOR); else glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL,GL_SINGLE_COLOR); glutPostRedisplay(); break; case 27: /* touche escape pour quitter */ exit(0); default : } } /***********************************************************/ /* void souris(int bouton, int etat,int x,int y) */ /***********************************************************/ /* fonction de rappel pour l'appui sur un bouton de souris */ /***********************************************************/ void souris(int bouton, int etat,int x,int y) { if (bouton == GLUT_LEFT_BUTTON && etat == GLUT_DOWN) { b_gauche = 1; xprec = x; yprec=y; } if (bouton == GLUT_LEFT_BUTTON && etat == GLUT_UP) b_gauche=0; if (bouton == GLUT_RIGHT_BUTTON && etat == GLUT_DOWN) { b_droit = 1; yprec=y; } if (bouton == GLUT_RIGHT_BUTTON && etat == GLUT_UP) b_droit=0; } /***************************************************/ /* void mouvSouris(int x,int y) */ /***************************************************/ /* fonction de rappel pour les mouvement de souris */ /***************************************************/ void mouvSouris(int x,int y) { /* si le bouton gauche est presse */ if (b_gauche) { anglex=anglex+(x-xprec); angley=angley+(y-yprec); glutPostRedisplay(); xprec=x; yprec=y; } /* si le bouton gauche est presse */ if (b_droit) { distance+=((float)(y-yprec))/10.0; if (distance<1.0) distance=1.0; if (distance>15.0) distance=15.0; glutPostRedisplay(); yprec=y; } } /****************************************************************/ /* void redim(int l,int h) */ /****************************************************************/ /* fonction de rappel pour les redimensionnements de la fenetre */ /****************************************************************/ void redim(int l,int h) { if (l<h) glViewport(0,(h-l)/2,l,l); else glViewport((l-h)/2,0,h,h); } /****************************************************/ /* void inactif */ /****************************************************/ /* fonction de rappel pour pour l'inactivité (idle) */ /****************************************************/ void inactif() { /* increment du décalage */ decalage+=0.1; if (decalage>2*PI) decalage-=2*PI; /* rechargement de la texture */ chargeTextureProc(IdTex[1]); glutPostRedisplay(); } /****************************************************/ /* void chargeTextureTiff(char *fichier,int numtex) */ /****************************************************/ /* chargement de l'image tif 'fichier' et placement */ /* dans la texture de numero 'numtex' */ /****************************************************/ void chargeTextureTiff(char *fichier,int numtex) { unsigned char image[256][256][3]; uint32 l, h; int i,j; size_t npixels; uint32* raster; /* chargement de l'image TIF */ TIFF* tif = TIFFOpen(fichier, "r"); if (tif) { TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &l); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); npixels = l * h; raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32)); if (raster != NULL) { /* lecture de l'image */ if (TIFFReadRGBAImage(tif, l, h, raster, 1)) { /* transfert de l'image vers le tableau 'image' */ for (i=0;i<256;i++) for (j=0;j<256;j++) { image[i][j][0]=((unsigned char *)raster)[i*256*4+j*4+0]; image[i][j][1]=((unsigned char *)raster)[i*256*4+j*4+1]; image[i][j][2]=((unsigned char *)raster)[i*256*4+j*4+2]; } } else { printf("erreur de chargement du fichier %s\n",fichier); exit(0); } _TIFFfree(raster); } TIFFClose(tif); /* paramétrage de la texture */ glBindTexture(GL_TEXTURE_2D,numtex); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,256,256,0, GL_RGB,GL_UNSIGNED_BYTE,image); } } /**************************************/ /* void chargeTextureProc(int numtex) */ /**************************************/ /* Création de la texture procedurale */ /* de numero 'numtex' */ /**************************************/ void chargeTextureProc(int numtex) { unsigned char image[256][256][3]; int i,j; int a; /* calcule de l'image */ for (i=0;i<256;i++) for (j=0;j<256;j++) { a=fonctionTexture(i,j); image[i][j][0]=a; image[i][j][1]=128; image[i][j][2]=128; } /* Paramètrage de la texture */ glBindTexture(GL_TEXTURE_2D,numtex); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,256,256,0, GL_RGB,GL_UNSIGNED_BYTE,image); } /*****************************************************/ /* int fonctionTexture(int x,int y) */ /*****************************************************/ /* Calcule et renvoie la valeur de la fonction */ /* utilisee pour la texture procedurale au point x,y */ /*****************************************************/ int fonctionTexture(int x,int y) { float dx=(128.0-(float)x)/255.0*40.0; float dy=(128.0-(float)y)/255.0*40.0; float a=cos(sqrt(dx*dx+dy*dy)+decalage); return (int)((a+1.0)/2.0*255); }