#include "fumee.h" #include "vector.h" #include #include Fumee::Fumee(double x0, double y0, double z0, double intervale_emision ) { pos[0]=x0; pos[1]=y0; pos[2]=z0; this->intervale_emision=intervale_emision; temps_ecoule=0.0; l_emision=intervale_emision+1.; lastT.start(); } void Fumee::affiche(GLuint * _texture){ drawFumee(_texture[0]); drawChemine(_texture[1]); } void Fumee::drawFumee(GLuint &_texture) { if(liste_Boufees.empty()) return; std::deque::iterator i; i = liste_Boufees.begin(); glDepthMask(GL_FALSE); glBindTexture(GL_TEXTURE_2D, _texture); while (i != liste_Boufees.end()) { i->affiche(); i++; } glDepthMask(GL_TRUE); } void Fumee::drawChemine(GLuint &_texture) { glDepthMask(GL_FALSE); glBindTexture(GL_TEXTURE_2D, _texture); glEnable(GL_TEXTURE_2D); // Comme on ne veut pas que ce quadrilatère soit affecté // par la lumière, on désactive l’éclairage juste avant // de l’afficher, et on le réactivera juste après. Vous // n’aurez donc pas besoin de spécifier la normale du // quadrilatère glDisable(GL_LIGHTING); // On veut pouvoir voir les deux côtés du quadrilatère glDisable(GL_CULL_FACE); // On active le blending pour que la couleur de la texture // se mélange à la couleur du reste de la scène dans des // proportions données par la valeur alpha de chaque texel // de la texture glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); // On récupère le positionnement de la camera float matrice [16]; glGetFloatv( GL_MODELVIEW_MATRIX, matrice ); Vector Haut, Droite; double taille=3.0; Droite.x = matrice[0] * taille ; Droite.y = matrice[4] * taille ; Droite.z = matrice[8] * taille ; Haut.x = matrice[1] * taille; Haut.y = matrice[5] * taille ; Haut.z = matrice[9] * taille ; Vector A, B, C, D; // On calcule la position des 4 sommets du quadrilatère A.x = pos[0] + Haut.x - Droite.x; A.y = pos[1] + Haut.y - Droite.y; A.z = pos[2] + Haut.z - Droite.z; B.x = pos[0] + Haut.x + Droite.x; B.y = pos[1] + Haut.y + Droite.y; B.z = pos[2] + Haut.z + Droite.z; C.x = pos[0] - Haut.x + Droite.x; C.y = pos[1] - Haut.y + Droite.y; C.z = pos[2] - Haut.z + Droite.z; D.x = pos[0] - Haut.x - Droite.x; D.y = pos[1] - Haut.y - Droite.y; D.z = pos[2] - Haut.z - Droite.z; // // // // Affichage du quadrilatère texturé avec la texture RGBA // Draw a 2D face with texture // Affichage du billboard glBegin(GL_QUADS); glColor4d(1.,1.,1., .7); glTexCoord2f(0.0, 0.0); glVertex3f(D.x,D.y,D.z); glTexCoord2f(1.0, 0.0); glVertex3f(C.x,C.y,C.z); glTexCoord2f(1.0, 1.0); glVertex3f(B.x,B.y,B.z); glTexCoord2f(0.0, 1.0 ); glVertex3f(A.x,A.y,A.z); glEnd(); // On désactive le blending glDisable(GL_BLEND); // On reactive l’utilisation de la lumière glEnable(GL_LIGHTING); // Pour ne voir qu’un seul côté des polygones // (affichage plus rapide) glEnable(GL_CULL_FACE); glDisable(GL_TEXTURE_2D); glDepthMask(GL_TRUE); } void Fumee::anime(QTime currenT){ temps_ecoule = lastT.msecsTo(currenT)/1. ; anime(temps_ecoule); lastT=currenT; } void Fumee::anime(double& temps){ ajoutBouffee(temps); supBouffee(); computePos(temps); } void Fumee::ajoutBouffee(double& temps){ l_emision += temps; if(intervale_emision <= l_emision){ for(uint i=0; i <= 5; i++){ Bouffee pff(pos[0] + .5, pos[1]+2.50, pos[2], intervale_emision); liste_Boufees.push_back(pff); } l_emision=0.0; } } void Fumee::supBouffee(){ if(liste_Boufees.empty()) return; std::deque::iterator i; i = liste_Boufees.begin(); while( i != liste_Boufees.end() ) { if( i->getVie() <= 0.0 ) liste_Boufees.erase(i--); i++; } } void Fumee::computePos(double& temps){ if(liste_Boufees.empty() ) return; std::deque::iterator i; i = liste_Boufees.begin(); while( i++ != liste_Boufees.end() ) { i->anime(temps); } }