IN Synthèse d'Images Rendu - IUT d'Arles

IN Synthèse d'Images Rendu - IUT d'Arles IN Synthèse d'Images Rendu - IUT d'Arles

iut.arles.up.univ.mrs.fr
from iut.arles.up.univ.mrs.fr More from this publisher
10.03.2014 Views

IUT de Provence – Site d’Arles 2012 - 2013 Département d’Informatique LP SIL IN IN – Synthèse d’images TP 4 Animation de feu d'artifice par système de particules Nous allons maintenant utiliser des textures translucides au moyen d’images 32 bits. Chaque pixel de ces images est codé sur un quadruplet RGBA où A est un octet indiquant le niveau d’opacité du pixel : si A = 0 le pixel est complètement transparent ; si A = 255 le pixel est complètement opaque ; entre les deux, le pixel est plus ou moins translucide. On veut représenter un feu d'artifice par un système de particules (voir le chapitre 4 du cours) où chaque particule correspondra à une étincelle. Les étincelles seront affichées au moyen de quadrilatères sur lesquels on plaque la texture RGBA « etincelle.tga ». Récupérez sur ma page web la base de ce TP. Classe Etincelle 1. Ecrire une classe Etincelle pour représenter une étincelle, qui sera affichée au moyen d’un quadrilatère texturé. Une étincelle est caractérisée par sa position (xpos, ypos, zpos : 3 float), sa taille (taille : 1 float, le quadrilatère étant carré), sa couleur (rouge, vert, bleu : 3 float), sa vitesse de déplacement selon x, y et z (vitesse_x, vitesse_y, vitesse_z : 3 float) et le temps qu’il lui reste à « vivre » en secondes (vie : 1 float). Ecrire le constructeur de cette classe, permettant d’initialiser ces données. 2. Ecrire une méthode anime() de la classe Etincelle qui recevra en paramètre le temps écoulé en secondes entre deux affichages : void Etincelle::anime (float temps); Elle permettra de modifier la position de l'étincelle en fonction du temps écoulé et de sa vitesse : nouvelle position = position courante + vitesse * temps On réduira aussi le temps de vie restant de l'étincelle en lui soustrayant le temps écoulé. 3. Ecrire une méthode affiche() de la classe Etincelle, permettant d’afficher l'étincelle au moyen d’un quadrilatère texturé : void Etincelle::affiche(); 1

<strong>IUT</strong> de Provence – Site d’Arles 2012 - 2013<br />

Département d’Informatique<br />

LP SIL <strong>IN</strong><br />

<strong>IN</strong> – Synthèse d’images<br />

TP 4<br />

Animation de feu d'artifice par système de particules<br />

Nous allons maintenant utiliser des textures translucides au moyen d’images 32 bits. Chaque pixel<br />

de ces images est codé sur un quadruplet RGBA où A est un octet indiquant le niveau d’opacité du<br />

pixel : si A = 0 le pixel est complètement transparent ; si A = 255 le pixel est complètement<br />

opaque ; entre les deux, le pixel est plus ou moins translucide.<br />

On veut représenter un feu d'artifice par un système de particules (voir le chapitre 4 du cours) où<br />

chaque particule correspondra à une étincelle. Les étincelles seront affichées au moyen de<br />

quadrilatères sur lesquels on plaque la texture RGBA « etincelle.tga ».<br />

Récupérez sur ma page web la base de ce TP.<br />

Classe Etincelle<br />

1. Ecrire une classe Etincelle pour représenter une étincelle, qui sera affichée au moyen d’un<br />

quadrilatère texturé. Une étincelle est caractérisée par sa position (xpos, ypos, zpos : 3<br />

float), sa taille (taille : 1 float, le quadrilatère étant carré), sa couleur (rouge, vert,<br />

bleu : 3 float), sa vitesse de déplacement selon x, y et z (vitesse_x, vitesse_y,<br />

vitesse_z : 3 float) et le temps qu’il lui reste à « vivre » en secondes (vie : 1 float).<br />

Ecrire le constructeur de cette classe, permettant d’initialiser ces données.<br />

2. Ecrire une méthode anime() de la classe Etincelle qui recevra en paramètre le temps<br />

écoulé en secondes entre deux affichages :<br />

void Etincelle::anime (float temps);<br />

Elle permettra de modifier la position de l'étincelle en fonction du temps écoulé et de sa<br />

vitesse :<br />

nouvelle position = position courante + vitesse * temps<br />

On réduira aussi le temps de vie restant de l'étincelle en lui soustrayant le temps écoulé.<br />

3. Ecrire une méthode affiche() de la classe Etincelle, permettant d’afficher l'étincelle<br />

au moyen d’un quadrilatère texturé :<br />

void Etincelle::affiche();<br />

1


On verra dans la question 8 comment faire pour toujours orienter ce quadrilatère face à<br />

l’observateur, mais vous pouvez pour le moment lui donner une orientation fixe (par exemple<br />

dans un plan z).<br />

A la fin du TP, vous pourrez aussi modifier la transparence de l'étincelle en jouant sur la valeur<br />

alpha grâce à glColor4f().<br />

// Comme on ne veut pas que ce quadrilatère soit affecté<br />

// par la lumière, on désactive l’éclairage juste avant<br />

// de l’afficher, et on le réactivera juste après. Vous<br />

// n’aurez donc pas besoin de spécifier la normale du<br />

// quadrilatère<br />

glDisable(GL_LIGHT<strong>IN</strong>G);<br />

// On veut pouvoir voir les deux côtés du quadrilatère<br />

glDisable(GL_CULL_FACE);<br />

// On colore la texture<br />

glColor4f(rouge, vert, bleu, alpha);<br />

// On active le blending pour que la couleur de la texture<br />

// se mélange à la couleur du reste de la scène dans des<br />

// proportions données par la valeur alpha de chaque texel<br />

// de la texture<br />

glBlendFunc(GL_SRC_ALPHA, GL_ONE_M<strong>IN</strong>US_SRC_ALPHA);<br />

glEnable(GL_BLEND);<br />

// Affichage du quadrilatère texturé avec la texture RGBA<br />

// glBegin(GL_QUADS)<br />

// ...<br />

// glEnd() ;<br />

// On désactive le blending<br />

glDisable(GL_BLEND);<br />

// On reactive l’utilisation de la lumière<br />

glEnable(GL_LIGHT<strong>IN</strong>G);<br />

// Pour ne voir qu’un seul côté des polygones<br />

// (affichage plus rapide)<br />

glEnable(GL_CULL_FACE);<br />

2


Classe Feu<br />

4. Ecrire une classe Feu pour représenter le feu d'artifice constitué d'étincelles. Elle contiendra<br />

les données membres suivantes :<br />

- La position (x,y,z) de l’origine du feu d'artifices, là où il éclate en étincelles.<br />

- Le nombre d'étincelles à générer lors de l'explosion.<br />

- Une liste chaînée d’objets de classe Etincelle. On utilisera la classe list de la STL :<br />

list liste_etincelles;<br />

- Un pointeur sur un objet de classe Texture servant de texture pour les étincelles. Vous<br />

chargerez la texture dans un objet de classe Texture dans le programme principal et<br />

vous passerez son adresse au constructeur de l’objet de classe Feu.<br />

5. Ecrire une méthode explose(float x, float y, float z, float vie_min,<br />

float vie_max) de la classe Feu qui remplira la liste liste_etincelles avec des<br />

objets de type Etincelle dont la position correspondra à celle du feu, avec des durées de<br />

vie comprises aléatoirement entre vie_min et vie_max. On donnera initialement au vecteur<br />

vitesse (vitesse_x, vitesse_y, vitesse_z) de chaque étincelle une direction<br />

aléatoire, afin que les particules partent dans toutes les directions par rapport au centre de<br />

l'explosion.<br />

6. Ecrire une méthode anime() de la classe Feu qui recevra en paramètre le temps écoulé en<br />

secondes entre deux affichages (variable globale dt du programme principal, à passer en<br />

paramètre lors de l’appel de la méthode anime() dans la fonction affiche_scene() du<br />

programme principal) :<br />

void Feu::anime(float temps);<br />

On décomposera cette fonction en deux étapes :<br />

1. Suppression d'étincelles : on parcours la liste d'étincelles à la recherche de celles dont<br />

la durée de vie s’est complètement écoulée (≤ 0). Si c’est le cas, elles seront<br />

supprimées de la liste grâce à la méthode erase() de list :<br />

list::iterator i;<br />

i = liste_etincelles.begin();<br />

while( i != liste_etincelles.end() )<br />

{<br />

if( i->duree_de_vie


7. Ecrire une méthode affiche() de la classe Feu qui affichera l’ensemble des étincelles de<br />

la liste :<br />

void Feu::affiche();<br />

8. Les étincelles apparaissent comme plates si on regarde de côté les quadrilatères qui les<br />

forment. Une solution est d’utiliser le principe de « billboarding », qui consiste à toujours<br />

orienter le quadrilatère face à l’observateur.<br />

Pour afficher en billboarding un quadrilatère de dimensions (largeur x hauteur) et centré<br />

autour de (xpos, ypos, zpos), on peut procéder comme suit :<br />

// On récupère le positionnement de la camera<br />

float matrice [16];<br />

glGetFloatv( GL_MODELVIEW_MATRIX, matrice );<br />

Vector Haut, Droite;<br />

Droite.x = matrice[0] * (largeur / 2.0f);<br />

Droite.y = matrice[4] * (largeur / 2.0f);<br />

Droite.z = matrice[8] * (largeur / 2.0f);<br />

Haut.x = matrice[1] * (hauteur / 2.0f);<br />

Haut.y = matrice[5] * (hauteur / 2.0f);<br />

Haut.z = matrice[9] * (hauteur / 2.0f);<br />

Vector A, B, C, D;<br />

// On calcule la position des 4 sommets du quadrilatère<br />

A.x = xpos + Haut.x - Droite.x;<br />

A.y = ypos + Haut.y - Droite.y;<br />

A.z = zpos + Haut.z - Droite.z;<br />

B.x = xpos + Haut.x + Droite.x;<br />

B.y = ypos + Haut.y + Droite.y;<br />

B.z = zpos + Haut.z + Droite.z;<br />

C.x = xpos - Haut.x + Droite.x;<br />

C.y = ypos - Haut.y + Droite.y;<br />

C.z = zpos - Haut.z + Droite.z;<br />

D.x = xpos - Haut.x - Droite.x;<br />

D.y = ypos - Haut.y - Droite.y;<br />

D.z = zpos - Haut.z - Droite.z;<br />

// Affichage du billboard<br />

glBegin(GL_QUADS);<br />

glVertex3f(D.x,D.y,D.z);<br />

glVertex3f(C.x,C.y,C.z);<br />

glVertex3f(B.x,B.y,B.z);<br />

glVertex3f(A.x,A.y,A.z);<br />

glEnd();<br />

4

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!