La structure du programme est quasiment la même que celle utilisée par Kayl dans ses tutos, je ne vais donc pas la détailler, je me contente de vous fournir le code.
Code : C 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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113 | #include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
/* Attention, j'utilise la bibliothèque de Kayl pour */
/* afficher les axes donc pensez à l'inclure */
#include "sdlglutils.h"
/* CONSTANTES */
#define LARGEUR 640
#define HAUTEUR 480
#define REFRESH_DELAY 20
...
/* FONCTIONS */
double myRand(double min, double max);
void dessinerScene();
...
/* FONCTION PRINCIPALE */
int main(int argc, char *argv[])
{ SDL_Surface *ecran = NULL;
SDL_Event event;
int continuer = 1;
int previousTime = SDL_GetTicks();
int elapsedTime = 0;
/* INITIALISATIONS */
SDL_Init(SDL_INIT_VIDEO); /* Initialisation de la SDL */
SDL_WM_SetCaption("Particle Engine", NULL);
/* Ouverture de la fenêtre */
ecran = SDL_SetVideoMode(LARGEUR, HAUTEUR, 32, SDL_OPENGL);
/* Initialisation du mode 3D */
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
gluPerspective(70,(double)LARGEUR/HAUTEUR,1,1000);
glEnable(GL_DEPTH_TEST); /* Initialisation du Z-Buffer */
glEnable(GL_BLEND); // Autoriser la transparence
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Type de transparence
/* Ces 2 lignes améliorent le rendu mais ne sont pas nécessaires */
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);
/* On efface le tampon d'affichage */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glFlush();
SDL_GL_SwapBuffers();
...
/* Boucle Générale */
while (continuer)
{ SDL_PollEvent(&event);
switch(event.type)
{ case SDL_QUIT:
continuer = 0;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{ case SDLK_ESCAPE:
continuer=0;
break;
default:break;
}
break;
}
/* Appel de la fonction principale de dessin */
dessinerScene();
/* On attend le tour suivant */
elapsedTime = SDL_GetTicks() - previousTime;
if (elapsedTime < REFRESH_DELAY)
{
SDL_Delay(REFRESH_DELAY - elapsedTime);
}
previousTime = SDL_GetTicks();
}
SDL_Quit(); /* Arrêt de la SDL */
return EXIT_SUCCESS; /* Fermeture du programme */
}
/* FONCTIONS SECONDAIRES */
double myRand(double min, double max)
{ return (double) (min + ((float) rand() / RAND_MAX * (max - min + 1.0)));
}
void dessinerScene()
{ /* Initialisation */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* Position Camera gluLookAt(positionCamera, positionCible, vecteurVertical) */
gluLookAt(2,2,-1, 0,0,0, 0,0,1);
drawAxis(1.0);
/* Dessin */
...
/* MAJ de l'écran */
glFlush();
SDL_GL_SwapBuffers();
}
|
Normalement vous devez obtenir une fenêtre qui ressemble à ça :
J'ai choisi l'axe Z comme axe vertical parceque j'ai l'habitude comme ça mais rien ne vous interdit de changer. J'ai aussi pour habitude de sortir la fonction de dessin du
main() mais là aussi ça n'a pas vraiment d'importance
Enfin j'ai rajouté une petite fonction secondaire:
Code : C1
2
3 | double myRand(double min, double max)
{ return (double) (min + ((float) rand() / RAND_MAX * (max - min + 1.0)));
}
|
C'est une fonction ultra-simple pour programmeur paresseux

qui renvoie un nombre aléatoire compris entre
min et
max. On en aura besoin plus tard.
Maintenant qu'on à un squelette correct on va pouvoir remplir les pointillés
Définition des particules
On va commencer par définir le nombre total de particules que le générateur devra gérer. Pour l'instant, on va se contenter de 1000 objets. Il faut donc rajouter la ligne suivante dans le code:
Code : C1 | #define MAX_PARTICLES 1000
|
Maintenant qu'on sait combien on en veut, il va falloir expliquer au programme ce que c'est qu'une particule. Pour cela nous allons définir une structure "
particles" qui contiendra 7 paramètres:
Code : C1
2
3
4
5
6
7
8
9 | typedef struct // Création de la structure
{ bool active; // Active (1=Oui/0=Non)
double life; // Durée de vie
double fade; // Vitesse de disparition
double r, g, b; // Valeurs RGB pour la couleur
double x, y, z; // Position
double xi, yi, zi; // Vecteur de déplacement
double xg, yg, zg; // Gravité
}particles;
|
Cette structure définit l'état d'une particule
à un instant donné. Son "état de santé" et représenté par un taux de transparence (le paramètre
life). Une particule "meurt" quand elle devient totalement transparente. Le paramètre
fade représentent la quantité de "vie" que la particule va perdre à la prochaine itération de la boucle principale du programme. Les vecteurs
position et
déplacement représente où est la particule et de combien elle va bouger. Quand au vecteur
gravité il va venir perturber le mouvement pour le rendre plus réaliste (du genre si vous codez une fontaine, ça serait bien si l'eau retombait vers le sol, non ?

).
Enfin, il faut réserver la mémoire dont on aura besoin pour stocker tous ces objets. Pour cela on construit un tableau de taille MAX_PARTICLES et du type
particles défini précédemment.
Code : C1
2 | /* Tableau de stockage des particules */
particles particle[MAX_PARTICLES];
|
Bon, on en a fini avec les déclarations, il ne reste plus qu'à coder le générateur

.