#include #include #include #include // ou suivant la config systeme /* Compilation sous UNIX dans le repertoire de travail 1) Creez un fichier "Makefile" avec le texte ci-dessous ------------------------------------------------------- XLIBS = -L/usr/X11/lib -L/usr/X11R6/lib -lX11 -lXext -lpthread GLLIBS = -L/usr/X11R6/lib -lglut -lGL -lGLU Image2D : Image2D.o gcc -o Image2D Image2D.o $(GLLIBS) $(XLIBS) -lm (remplacez par le caractere tabulation) 2) Compilez avec la commande ---------------------------- make Image2D 3) Executez avec la commande ---------------------------- ./Image2D */ /* Ce programme contient 3 parties : I- Definition d'une image et procedures associees ---------------------------------------------- II- Vos fonctions ------------- III- Gestion des evenements sous GLUT -------------------------------- //===================================== /* I- Definition d'un type image 2D */ //===================================== /* La structure de donnees ci-dessous permet pour une image I de : - lire et allouer l'espace nécessaire pour une image RGB (.ppm) ou en niveau de gris (.pgm) - preciser sa nature avec I->rgb qui vaut 1 si c'est une image RGB, 0 si en niveau de gris - connaitre ses dimensions avec I->larg et I->haut - acceder a un pixel avec l'expression I->pix[i][j] - acceder à la suite de pixels I->dat pour les transferts entre la mémoire centrale et la carte graphique */ typedef struct image { int larg, haut, rgb; GLubyte *dat; GLubyte **pix; } *Image; /* lecture d'une image PPM (rgb) ou PGM (niveaux de gris) */ #define MAXLIGNE 256 Image LireImage(char *nom) { int i, nbOctets; GLubyte *P; Image I; FILE *f; char s[MAXLIGNE]; int maxgrey; /* Ouverture du fichier */ f = fopen(nom, "r"); if (f == NULL) exit(0); /* confirmation du codage PPM ou PGM */ fgets(s, MAXLIGNE, f); if (s[0] != 'P' || ((s[1] != '6') && (s[1] != '5'))) { printf("erreur de format\n") ; exit(0); } I = (Image) malloc(sizeof(struct image)); if (s[1] == '6') { I->rgb=1; nbOctets=3;} else { I->rgb=0; nbOctets=1;} /* Lecture larg haut et allocation de l'image */ do fgets(s, MAXLIGNE, f) ; while (s[0] == '#') ; sscanf (s, "%d %d", &I->larg, &I->haut) ; P = I->dat = (GLubyte*) malloc(sizeof(GLubyte)*nbOctets*I->larg*I->haut); I->pix = (GLubyte**) malloc(sizeof(GLubyte*)*I->haut); for (i=0 ; ihaut ; i++) { I->pix[i] = P; P = P+nbOctets*I->larg; } /* Saut des commentaires et lecture de maxgrey */ do fgets(s, MAXLIGNE, f); while (s[0] == '#') ; /* Lecture de la matrice image */ fread(I->dat,sizeof(GLubyte)*nbOctets*I->larg*I->haut,1,f); fclose(f); return I; } // Creer une image en niveau de gris et l'initialiseer avec une couleur Image allouerImageGris(int l, int h, int couleur) { int i, j; GLubyte *P; Image I; I = (Image) malloc(sizeof(struct image)); I->rgb=0; I->larg = l ; I->haut = h ; P = I->dat = (GLubyte*) malloc(sizeof(GLubyte)*I->larg*I->haut); I->pix = (GLubyte**) malloc(sizeof(GLubyte*)*I->haut); for (i=0 ; ihaut ; i++) { I->pix[i] = P; P = P+I->larg; } // initialisation avec une couleur de fond for (i=0 ; ihaut ; i++) for (j=0 ; jlarg ; j++) I->pix[i][j] = couleur ; return I; } /* restitution de l'espace memoire occupe par une image */ void restituerImage(Image I) { free(I->pix); free(I->dat); free(I); I=NULL; } //============================== // II- Ajouter vos fonctions ici //============================== //========================================== // III- Interruptions et affichage avec GLUT //========================================== // taille de la fenetre d'affichage int hautWind=750, largWind=1000; Image I; // Exemple de trace d'une primitive void tracerTruc(void) { glBegin(GL_POLYGON) ; glVertex2i(20,20) ; glVertex2i(70,50) ; glVertex2i(20,100) ; glEnd() ; } // Scene constituee d'une image et d'un triangle rouge void afficherImage() { glClear(GL_COLOR_BUFFER_BIT) ; glRasterPos2i(0,0); // positionnement de l'origine pour glDrawPixels if (I->rgb) glDrawPixels(I->larg, I->haut ,GL_RGB , GL_UNSIGNED_BYTE, I->dat); else glDrawPixels(I->larg, I->haut ,GL_LUMINANCE , GL_UNSIGNED_BYTE, I->dat); glColor3f(1., 0, 0) ; tracerTruc(); glutSwapBuffers(); } void priseDeVue(int l, int h) { float coef; hautWind = h; largWind = l; glViewport(0,0,l,h); // zone d'affichage dans la fenêtre glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0, l, 0, h); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void souris(int bouton, int state, int x, int y) { /* L'origine de la souris est fixee en haut a gauche contrairement a notre image (en bas a gauche). Pour retrouver un repère direct, apliquer : y = hautWind - y - 1 ; */ y = hautWind - y - 1 ; printf("click en (%d, %d)\n", x, y); // A vous ... // glutPostRedisplay(); // si l'evenement doit modifier l'affichage } void fleches(int key, int x, int y) { switch (key ) { case GLUT_KEY_UP : // ajouter une action ici // glutPostRedisplay(); break; case GLUT_KEY_DOWN : // glutPostRedisplay(); break; case GLUT_KEY_LEFT : // glutPostRedisplay(); break; case GLUT_KEY_RIGHT : // glutPostRedisplay(); break; } } void menu1(int value) { int i,j; switch (value) { case 0: /* quit */ exit(0); break; // glutPostRedisplay(); } } void menu2(int value) { switch (value) { case 0: printf("coucou !\n"); break ; case 1: printf("Bonjour !\n"); break ; } } void clavier(unsigned char touche, int x, int y) { /* L'origine de la souris est fixee en haut a gauche contrairement a notre image (en bas a gauche) */ switch (touche) { case 27 : /* escape */ exit(0); } } void initGraphic() { /* la taille des paquets d'octets pour otpimiser les transfers vers la carte graphique doit etre un diviseur de la taille d'une ligne de l'image */ glPixelStorei(GL_UNPACK_ALIGNMENT,1); /* moins efficace mais sur ! */ glClearColor(0.0, 0.0, 0.0, 1.0); glShadeModel(GL_FLAT) ; } int main(int argc, char** argv) { int sousMenu; /* Exemple de lecture et affichage d'une image */ // I = LireImage("terre.ppm"); // I = LireImage("lena.pgm"); /* Exemple de creation d'une image gris moyen pour affichage */ I = allouerImageGris(500,500, 128) ; //image grise /* initialisation de la fenetre */ glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (largWind, hautWind); glutInitWindowPosition (20, 20); glutCreateWindow ("Image2D"); initGraphic(); /* INITIALISATION DE LA BOUCLE D'EVENEMENTS */ glutDisplayFunc(afficherImage); glutReshapeFunc(priseDeVue); glutKeyboardFunc(clavier); glutMouseFunc(souris); glutSpecialFunc(fleches); sousMenu = glutCreateMenu(menu2); glutAddMenuEntry("coucou !", 0); glutAddMenuEntry("bonjour !", 1); glutCreateMenu(menu1); glutAddSubMenu("coucou ?", sousMenu); glutAddMenuEntry("quit", 0); glutAttachMenu(GLUT_LEFT_BUTTON); glutMainLoop(); return 0; }