Bonjour, je suis en ce moment entrain de développer un simulateur d'orages, et je cherche à modéliser également des tornades, au moyen d'un générateur de particules. Il n'y a pas moins de 100000 particules (Représentées par des triangles équilatéraux) ; pour les modéliser, pas de problème avec les Vertex Arrays ; mais pour les animer, c'est autrechose : Je compte faire pivoter les particules, mais je n'ai d'autre choix que de réaliser cela vertex par vertex dans une boucle pendant le rendu, j'ai essayé cete solution et bien entendu, le rendu est devenu plus lent qu'une tortue.
Mon code :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
void InitTornade(Principale *ptr)
{
    int compteurPart=0;
    int compteurBoucle=0;
    float X,Y,Z;
    float rayonMax,A,htPart,rayon;
    const float largPart=1;           //Longueur côtés triangle équilatéral
    const float htTri=largPart*sin(60*M_PI/180);		//Calcul hauteur triangle
    double angle;
    const int nbToursBoucle=NB_PARTICULES_TORNADE;
 
    ptr->La_meteo.tornade.positionInit[0]=1000;//myRand(0,TAILLE_MAP/2);		//Position initiale de la tornade
    /*if(rand()%2==1)
        ptr->La_meteo.tornade.positionInit[0]*=-1;*/
 
    ptr->La_meteo.tornade.positionInit[1]=0;//myRand(0,TAILLE_MAP/2);
    if(rand()%2==1)
        ptr->La_meteo.tornade.positionInit[1]*=-1;
 
    ptr->La_meteo.tornade.hauteur=myRand(800,1000);			//Calcul caractéristiques tornade
    ptr->La_meteo.tornade.largBase=myRand(40,80);
    ptr->La_meteo.tornade.largHaut=myRand(500,1000);
    ptr->La_meteo.tornade.dureeDeVie=myRand(10,120);
 
    A=(ptr->La_meteo.tornade.largHaut-ptr->La_meteo.tornade.largBase)/pow(ptr->La_meteo.tornade.hauteur,2);
 
    while(1)
    {
        Z=((float)compteurBoucle/nbToursBoucle)*ptr->La_meteo.tornade.hauteur;		//Hauteur particule
 
        htPart=Z;
 
        rayonMax=A*pow(htPart,2)+ptr->La_meteo.tornade.largBase;		//Fonction du second degré permettant d'avoir une forme d'entonnoir
 
        rayon=myRand(0.9*rayonMax,rayonMax);		//Coordonnées polaires particule
        angle=(double)(rand()%360);
 
        X=rayon*cos(angle*M_PI/180);		//Coordonnées cartésiennes particule
        Y=rayon*sin(angle*M_PI/180);
 
        ptr->La_meteo.tornade.particules[compteurPart]=X;					//Calcul des coordonnées de chacun des trois vertices
        ptr->La_meteo.tornade.particules[compteurPart+1]=Y;
        ptr->La_meteo.tornade.particules[compteurPart+2]=Z+(2.0/3)*htTri;
 
        ptr->La_meteo.tornade.particules[compteurPart+3]=X-(largPart/2)*sin(angle*M_PI/180);
        ptr->La_meteo.tornade.particules[compteurPart+4]=Y+(largPart/2)*cos(angle*M_PI/180);
        ptr->La_meteo.tornade.particules[compteurPart+5]=Z-htTri/3;
 
        ptr->La_meteo.tornade.particules[compteurPart+6]=X+(largPart/2)*sin(angle*M_PI/180);
        ptr->La_meteo.tornade.particules[compteurPart+7]=Y-(largPart/2)*cos(angle*M_PI/180);
        ptr->La_meteo.tornade.particules[compteurPart+8]=Z-htTri/3;
 
        ///////////////////////////////////////////////////////////////////////////////////////////////
 
        ptr->La_meteo.tornade.couleurs[compteurPart]=0.3;			//Couleur gris foncé
        ptr->La_meteo.tornade.couleurs[compteurPart+1]=0.3;
        ptr->La_meteo.tornade.couleurs[compteurPart+2]=0.3;
 
        ptr->La_meteo.tornade.couleurs[compteurPart+3]=0.3;
        ptr->La_meteo.tornade.couleurs[compteurPart+4]=0.3;
        ptr->La_meteo.tornade.couleurs[compteurPart+5]=0.3;
 
        ptr->La_meteo.tornade.couleurs[compteurPart+6]=0.3;
        ptr->La_meteo.tornade.couleurs[compteurPart+7]=0.3;
        ptr->La_meteo.tornade.couleurs[compteurPart+8]=0.3;
 
        compteurBoucle++;
        compteurPart+=9;
 
        if(compteurPart==9*NB_PARTICULES_TORNADE)
            break;
    }
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void animTornade(Tornade *tornade)
{
    int compteurPart=0;
 
    while(1)		//Calcul nouvelles coordonnées après rotation (Très long !!!)
    {
        matriceRotation(&tornade->particules[compteurPart],&tornade->particules[compteurPart+1],&tornade->particules[compteurPart+2],tornade->vitesseRotation,AXE_Z);
        matriceRotation(&tornade->particules[compteurPart+3],&tornade->particules[compteurPart+4],&tornade->particules[compteurPart+5],tornade->vitesseRotation,AXE_Z);
        matriceRotation(&tornade->particules[compteurPart+6],&tornade->particules[compteurPart+7],&tornade->particules[compteurPart+8],tornade->vitesseRotation,AXE_Z);
 
        compteurPart+=9;
        if(compteurPart==9*NB_PARTICULES_TORNADE)
            break;
    }
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void tornade(Principale *ptr)
{
    glDisable(GL_TEXTURE_2D);
 
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
 
    glVertexPointer(3,GL_FLOAT,3*sizeof(float),ptr->La_meteo.tornade.particules);
    glColorPointer(3,GL_FLOAT,3*sizeof(float),ptr->La_meteo.tornade.couleurs);
 
    glPushMatrix();
    glTranslated(ptr->La_meteo.tornade.positionInit[0],ptr->La_meteo.tornade.positionInit[1],0);
    glDrawArrays(GL_TRIANGLES,0,3*NB_PARTICULES_TORNADE);		//Dessin particules
    glPopMatrix();
 
    glEnable(GL_TEXTURE_2D);
 
    animTornade(&ptr->La_meteo.tornade);
}
Une solution consisterait à se contenter d'un glRotated(), mais je souhaite faire pivoter les particules dans la tornade et non faire pivoter la tornade sur elle-même si vous voyez ce que le veux dire.
Auriez-vous une solution pour animer 100000 particules de manière fluide ?