// Alpha - Blending et Test alpha // Prog3D // Fabrice Aubert #include #include #include #include #include "trackball.h" #include #include using namespace std; static void erreur(const string &mesg) { cout << "Erreur dans alpha.cpp :" << endl; cout << mesg << endl; exit(1); } // VARIABLES GLOBALES (anim) GLfloat ANGLE=0.0; GLint id_tex1,id_tex2; GLuint id_image; // affectation d'une image à un identifiant de texture GLint initTexture(const char *nom) { GLubyte *image; GLuint result; GLint longueur,largeur,format,bpp,depth; ILenum il_erreur; bool ok=ilLoadImage(nom); if (!ok) { cout << "impossible de lire " << nom << endl; erreur("initTexture"); } longueur=ilGetInteger(IL_IMAGE_WIDTH); largeur=ilGetInteger(IL_IMAGE_HEIGHT); format=ilGetInteger(IL_IMAGE_FORMAT); bpp=ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL); cout << "lecture image " << nom << " : " << longueur << "," << largeur << "," << bpp << endl; image=new GLubyte[longueur*largeur*bpp]; // Attention : memory leak ! ilCopyPixels(0,0,0,longueur,largeur,1,IL_RGB,IL_UNSIGNED_BYTE,image); il_erreur=ilGetError(); if (il_erreur!=IL_NO_ERROR) { // cout << iluErrorString(il_erreur); erreur("Chargement texture"); } // affectation identifiant glGenTextures(1,&result); // génération d'un identifiant par OpenGL glBindTexture(GL_TEXTURE_2D,result); // la texture courante 2D correspond à glPixelStorei(GL_UNPACK_ALIGNMENT,1); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,longueur,largeur,0,GL_RGB,GL_UNSIGNED_BYTE,image); 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); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); return result; } // Pour définir une lumiere blanche void initSource(GLint light) { GLfloat ambient[4]={1.0,1.0,1.0,1.0}; GLfloat diffuse[4]={1.0,1.0,1.0,1.0}; GLfloat speculaire[4]={1.0,1.0,1.0,1.0}; glLightfv(light,GL_AMBIENT,ambient); glLightfv(light,GL_DIFFUSE,diffuse); glLightfv(light,GL_SPECULAR,speculaire); } void sourceLocale(GLint light) { GLfloat position[4]={0,0,1,0}; // la lumiere est une source directionnelle glLightfv(light,GL_POSITION,position); } // ********************************************************** // TRACE DE LA SCENE void tracerCarre(float taille) { glPushMatrix(); glNormal3f(0,0,1); // pour le calcul d'éclairement glScalef(taille,taille,taille); glBegin(GL_POLYGON); glTexCoord2f(0,0); glVertex3f(-1,-1,0); glTexCoord2f(1,0); glVertex3f(1,-1,0); glTexCoord2f(1,1); glVertex3f(1,1,0); glTexCoord2f(0,1); glVertex3f(-1,1,0); glEnd(); glPopMatrix(); } void tracerPlanOeuvre(GLint idtex) { glPushMatrix(); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,idtex); glTranslatef(0,0,-5); glRotatef(30,0,1,0); glScalef(6,4,1); tracerCarre(1.0); glDisable(GL_TEXTURE_2D); glPopMatrix(); } void tracerPlanPortrait(GLint idtex) { glPushMatrix(); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D,idtex); glTranslatef(2,0.5,0); glRotatef(-30,0,1,0); glScalef(2,2,1); tracerCarre(1.0); glDisable(GL_TEXTURE_2D); glPopMatrix(); } // ************************************************************** void tracerExo1() { glEnable(GL_BLEND); // GL_ONE / GL_ONE :: Prend la couleur de la dest, celle de la source, mixe. Le fait pour chaque canal. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // carre vert en z=-5 glPushMatrix(); glTranslatef(1,1,-5); glColor4f(0,1,0, 0.6); tracerCarre(3.0); glPopMatrix(); // fin carre vert // carre rouge en z=-10 glPushMatrix(); glTranslatef(-2,-2,-10); glColor4f(1,0,0,0.6); // alpha = 1=>100% opaque tracerCarre(3.0); glPopMatrix(); // fin carre rouge glDisable(GL_BLEND); } void tracerExo2(float angle) { glPushMatrix(); glPushMatrix(); glRotatef(angle,1,0.5,0.2); glColor4f(0.2,0.9,0.3,0.45); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //tracerCarre(2.0); glutSolidTorus(1,3,10,10); glDisable(GL_BLEND); glPopMatrix(); glColor4f(0.0,0.0,0.0,1.0); tracerPlanPortrait(id_tex2); tracerPlanOeuvre(id_tex1); glPopMatrix(); } // ******************************************************* // Callback de display void myDisplay(void) { glClearColor(0,0,0,0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glTranslatef(0,0,-10); // éloignement tbMatrix(); // trackball //tracerExo1(); glAlphaFunc(GL_EQUAL, 1.0); tracerExo2(ANGLE); glDepthMask(GL_FALSE); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_LESS, 1.0); tracerExo2(ANGLE); glDepthFunc(GL_LESS); glDepthMask(GL_TRUE); glPopMatrix(); glutSwapBuffers(); } // Callback de redimensionnement de fenetre void myReshape(int width, int height) { glViewport(0, 0, (GLint) width, (GLint) height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45,(GLfloat)width/(GLfloat)height,1.0,30.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); tbReshape(width,height); } // Callback IDLE void myIdle(void) { // mettre à jour les paramètres évolutifs à travers // le temps ... tbIdle(); ANGLE+=0.4; glutPostRedisplay(); } // Callback de la souris void myMouse(int button, int status, int x, int y) { tbMouse(button,status,x,y); } void myMotion(int x,int y) { tbMotion(x,y); } // CallBack clavier void myKey(unsigned char c,int x,int y) { switch (c) { case 27: exit(0); break; // sortie violente si appui sur "Echap" // case ' ': default: break; } } void myInit() { ilInit(); id_image=ilGenImage(); ilBindImage(id_image); ilEnable(IL_ORIGIN_SET); ilOriginFunc(IL_ORIGIN_LOWER_LEFT); glEnable(GL_DEPTH_TEST); id_tex1=initTexture("../data/age_mur.jpg"); id_tex2=initTexture("../data/claudel.jpg"); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); tbInit(GLUT_LEFT_BUTTON); // ACTIVATION ECLAIREMENT glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); sourceLocale(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE); } int main(int argc, char **argv) { glutInit(&argc,argv); glutInitWindowSize(512,512); glutInitDisplayMode(GLUT_ALPHA | GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STENCIL); glutCreateWindow("Prog3D - Alpha"); glutReshapeFunc(myReshape); glutDisplayFunc(myDisplay); glutMouseFunc(myMouse); glutMotionFunc(myMotion); glutKeyboardFunc(myKey); glutIdleFunc(myIdle); myInit(); glutMainLoop(); return 0; }