/* Placage d'une texture sur un rectangle */ /* ou sur un cylindre */ /* */ /* Auteur: Nicolas JANEY */ /* nicolas.janey@univ-fcomte.fr */ /* Fevrier 2019 */ #include #include #include #include #include #include /* Variables et constantes globales */ static const float blanc[] = { 1.2F,1.2F,1.2F,1.0F }; static int affichage = 1; static int question = 0; static int texture = 1; ////////////////////////////////////////////////// #include "PNG/ChargePngFile.h" static unsigned int textureID = 0; /* Fonction d'initialisation des parametres */ /* OpenGL ne changeant pas au cours de la vie */ /* du programme */ static void init(void) { glClearColor(0.25F,0.25F,0.25F,1.0F); glLightfv(GL_LIGHT0,GL_DIFFUSE,blanc); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_NORMALIZE); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1); glGenTextures(1,&textureID); glBindTexture(GL_TEXTURE_2D,textureID); glPixelStorei(GL_UNPACK_ALIGNMENT,1); { int rx; int ry; unsigned char *img = chargeImagePng("Emojis.png",&rx,&ry); if ( img ) { glTexImage2D(GL_TEXTURE_2D,0,3,rx,ry,0,GL_RGB,GL_UNSIGNED_BYTE,img); free(img); printf("Texture chargée %d\n",textureID); } else { glDeleteTextures(1,&textureID); textureID = 0; printf("Texture non chargée\n"); } } glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); } /* Dessin d'un rectangel */ static void rectangle(float largeur,float hauteur) { largeur /= 2.0F; hauteur /= 2.0F; glPushMatrix(); glBegin(GL_QUADS); glNormal3f(0.0F,0.0F,1.0F); glTexCoord2f(0.0F,0.0F); glVertex3f(-largeur,-hauteur,0.0F); glTexCoord2f(1.0F,0.0F); glVertex3f(largeur,-hauteur,0.0F); glTexCoord2f(1.0F,1.0F); glVertex3f(largeur,hauteur,0.0F); glTexCoord2f(0.0F,1.0F); glVertex3f(-largeur,hauteur,0.0F); glEnd(); glPopMatrix(); } /* Dessin d'un cylindre */ #ifndef M_PI #define M_PI 3.14159 #endif static void mySolidCylinder(double hauteur,double rayon,int ns) { glPushMatrix(); hauteur /= 2.0F; glBegin(GL_QUAD_STRIP); for ( int i = 0 ; i <= ns ; i++ ) { float rp =(float) i/ns; float a = 2.0*M_PI*rp; float cs = cos(a); float sn = -sin(a); glNormal3f(cs,0.0F,sn); float x = rayon*cs; float z = rayon*sn; glTexCoord2f(rp,1.0F); glVertex3f(x,hauteur,z); glTexCoord2f(rp,0.0F); glVertex3f(x,-hauteur,z); } glEnd(); glPopMatrix(); } /* Scene dessinee : rectangle */ static void sceneRectangle() { glPushMatrix(); rectangle(7.5F,5.0F); glPopMatrix(); } /* Scene dessinee : cylindre */ static void sceneCylindre() { glPushMatrix(); mySolidCylinder(5.0,2.5,72); glPopMatrix(); } static double px = 0.0; static double py = 0.0; static double pz = 10.0; /* Fonction executee lors d'un rafraichissement */ /* de la fenetre de dessin */ static void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); const GLfloat light0_position[] = { 0.0,0.0,10.0,1.0 }; glPolygonMode(GL_FRONT_AND_BACK,(affichage) ? GL_FILL : GL_LINE); if ( texture ) glEnable(GL_TEXTURE_2D); else glDisable(GL_TEXTURE_2D); glPushMatrix(); glLightfv(GL_LIGHT0,GL_POSITION,light0_position); gluLookAt(px,py,pz,0.0,0.0,0.0,0.0,1.0,0.0); switch (question) { case 0 : sceneRectangle(); break; case 1 : sceneCylindre(); break; } glPopMatrix(); glFlush(); glutSwapBuffers(); int error = glGetError(); if ( error != GL_NO_ERROR ) printf("Erreur OpenGL: %d\n",error); } /* Desallocation de la texture */ static void clean(void) { if ( textureID != 0 ) glDeleteTextures(1,&textureID); } ////////////////////////////////////////////////// /* Fonction executee lors d'un changement */ /* de la taille de la fenetre OpenGL */ /* -> Ajustement de la camera de visualisation */ static void reshape(int tx,int ty) { glViewport(0,0,tx,ty); glMatrixMode(GL_PROJECTION); glLoadIdentity(); double ratio =(double) tx/ty; if ( ratio >= 1.0 ) gluPerspective(50.0,ratio,0.01,200.0); else gluPerspective(50.0/ratio,ratio,0.01,200.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* Fonction executee lors de la frappe */ /* d'une touche speciale du clavier */ static void special(int key,int x,int y) { switch ( key ) { case GLUT_KEY_UP : py += 0.1; glutPostRedisplay(); break; case GLUT_KEY_DOWN : py -= 0.1; glutPostRedisplay(); break; case GLUT_KEY_LEFT : px -= 0.1; glutPostRedisplay(); break; case GLUT_KEY_RIGHT : px += 0.1; glutPostRedisplay(); break; case GLUT_KEY_PAGE_UP : pz -= 0.1; glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN : pz += 0.1; glutPostRedisplay(); break; case GLUT_KEY_F1 : px = 0.0; py = 0.0; pz = 10.0; glutPostRedisplay(); break; } } /* Fonction executee lors de la frappe */ /* d'une touche du clavier */ static void keyboard(unsigned char key,int x,int y) { switch ( key ) { case 'a' : affichage = (affichage+1)%2; glutPostRedisplay(); break; case 0x0D : question = (question+1)%2; glutPostRedisplay(); break; case 0x20 : texture = (texture+1)%2; glutPostRedisplay(); break; case 0x1B : exit(0); break; } } /* Fonction principale */ int main(int argc,char **argv) { atexit(clean); glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE); glutInitWindowSize(480,360); glutInitWindowPosition(50,50); glutCreateWindow("Plaçage d'une texture"); init(); glutKeyboardFunc(keyboard); glutSpecialFunc(special); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMainLoop(); return(0); }