
|
Salut,
Je vous propose un exercice ou plutôt un jeu consistant à coder un effet de plasma.
Pour avoir un apercu, une vidéo
C'est visuellement plutôt sympa, et très abordable niveau C.
On va commencer par le type de plasma le plus simple, celui basé sur un cycle de couleur.
Pour que tous monde puisse participer, je vais d'abord essayer d'expliquer le principe.
Le principe :
Sur une forme statique, on fait évoluer la palette pour créer une impression de mouvement.
Les ingrédients:
Il faut une palette cyclique comme celle ci par exemple...

Notez que les bords gauche et droit sont identiques.
On peut générer des palettes cycliques de plusieurs façons.
- en faisant varier la teinte(hue) dans un espace colorimétrique HSV
- utiliser des fonctions mathématiques péridodique(sinus par exemple...)
Dans un premier temps, le plus simple est de travailler avec des surface ayant une profondeur de 8bpp et une palette.
Pour les librairies comme la SFML qui ne permettent de travailler qu'en "true color", il faudra simuler une palette en stockant les valeurs dans un tableau.
Ensuite, il faut générer une forme statique...
Pour ça, une méthode est d'appliquer une fonction à chaque pixel de notre surface...
Exemple en en utilisant la fonctions sinus.
On sait que cette fonction varie de -1 à 1 sur l'intervalle [0, pi]. C'est très bien, mais nous, on souhaite obtenir une composante RGB(une valeur comprise entre 0 et 255)...
Comment faire ? C'est simple...
Pour une valeur a donnée
Code : Autre1
2
3
| sin(a) est dans l'intervalle [-1, 1]
127 * sin(a) est dans l'intervalle [-127, 127]
128 + 127 * sin(a) est dans l'inervalle [0, 255]. |
Gagné.
En pratique on peut avoir des fonctions :
appliquée à 1 axe
f(x) = 128 + 127 * sin(x)
f(y) = 128 + 127 * sin(y)
appliquée à 2 axes
f(x, y) = 128 + 127 * sin(x + y)
f(x, y) = sqrt(x * x + y * y)
Comme vous pouvez le voir l'utilisation des sinus n'est pas une obligation.
Un petit exemple, pour avoir un aperçu des formes générées...
Secret (cliquez pour afficher)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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176 | #include <SDL.h>
#include <math.h>
void putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
Uint8 f1(Sint16 a, Sint16 b)
{
return 128 + 127 * sin(a / 16.0);
}
Uint8 f2(Sint16 a, Sint16 b)
{
return 128 + 127 * sin(b / 16.0);
}
Uint8 f3(Sint16 a, Sint16 b)
{
return 128 + 127 * sin((a + b) / 16.0);
}
Uint8 f4(Sint16 a, Sint16 b)
{
return 128 + 127 * sin(sqrt(a * a + b * b) / 16.0);
}
void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y, Uint8(*f)(Sint16, Sint16))
{
Uint8 color = f(x, y);
putPixel(s, x, y, color);
}
void draw(SDL_Surface *s, Uint8(*f)(Sint16, Sint16))
{
Sint16 x, y;
if ( SDL_MUSTLOCK(s) )
if ( SDL_LockSurface(s) < 0 )
{
fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
exit (EXIT_FAILURE);
}
for(y = 0; y < s->h; ++y)
for(x = 0; x < s->w; ++x)
applyPlasma(s, x, y, f);
if (SDL_MUSTLOCK(s))
SDL_UnlockSurface(s);
}
void setPalette(SDL_Surface *s)
{
SDL_Color colors[256];
int i;
for(i = 0; i < 256; i++)
{
colors[i].r = i;
colors[i].g = colors[i].r;
colors[i].b = colors[i].r;
}
SDL_SetColors(s, colors, 0 , 256);
}
int main (int argc, char* argv[])
{
typedef struct
{
Uint8 (*fun)(Sint16, Sint16);
}t_fun;
t_fun functions[] = {f1, f2, f3, f4};
size_t nFun = sizeof functions / sizeof *functions;
size_t curFun = 0;
SDL_bool done = SDL_FALSE;
SDL_Surface *screen;
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError() );
return EXIT_FAILURE;
}
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE | SDL_HWPALETTE);
if(screen == NULL)
{
fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
return EXIT_FAILURE;
}
setPalette(screen);
draw(screen, functions[0].fun);
while (!done)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
done = SDL_TRUE;
break;
case SDL_KEYDOWN:
{
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE :
done = SDL_TRUE;
break;
case SDLK_SPACE:
curFun++;
curFun %= nFun;
draw(screen, functions[curFun].fun);
break;
default:
break;
}
}
}
}
SDL_Flip(screen);
}
SDL_Quit();
return 0;
}
|
   
L'astuce pour avoir des formes moins monotones consiste à additionner le résultat de plusieurs fonctions. Mais attention, il faut prendre garde à ce que la somme soit dans l'intervalle[0, 255].
Là encore, plusieurs méthodes.
Un exemple avec l'addition de 2 fonctions...
Soit on s'arrange pour que f1 et f2 retourne une valeur dans l'intervalle[0, 128], soit on divise la somme par 2, tout simplement.
Je commence donc en vous proposant un plasma, avec les fonctions présentées plus haut, et avec une palette en dégardé de gris(r, g, b de même valeur).
Secret (cliquez pour afficher)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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 | #include <SDL.h>
#include <math.h>
#define PI 3.14159265
#define PI2 6.28318531
#define TICK_INTERVAL 20
#define SHIFT_SPEED 2
Uint32 time_left(Uint32 nextTime)
{
Uint32 now = SDL_GetTicks();
return nextTime <= now ? 0 : nextTime - now;
}
void putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
Uint8 f1(Sint16 a)
{
return 128 + 127 * sin(a / 16.0);
}
Uint8 f2(Sint16 b)
{
return 128 + 127 * sin(b / 16.0);
}
Uint8 f3(Sint16 a, Sint16 b)
{
return 128 + 127 * sin((a + b) / 32.0);
}
Uint8 f4(Sint16 a, Sint16 b)
{
return 128 + 127 * sin(sqrt(a * a + b * b) / 16.0);
}
void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y)
{
Uint8 color = (f1(x) + f2(y) + f3(x, y) + f4(x, y)) / 4;
putPixel(s, x, y, color);
}
void init(SDL_Surface *s)
{
Sint16 x, y;
if ( SDL_MUSTLOCK(s) )
if ( SDL_LockSurface(s) < 0 )
{
fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
exit (EXIT_FAILURE);
}
for(y = 0; y < s->h; ++y)
for(x = 0; x < s->w; ++x)
applyPlasma(s, x, y);
if (SDL_MUSTLOCK(s))
SDL_UnlockSurface(s);
}
void setPalette(SDL_Surface *s, Uint8 shift)
{
SDL_Color colors[256];
int i;
/* Décalage */
double f = SHIFT_SPEED * (2 * PI * shift / 256);
for(i = 0; i < 256; i++)
{
double angle = i * PI / 128.0 + f;
colors[i].r = 128 + 127 * sin(angle);
colors[i].g = colors[i].r;
colors[i].b = colors[i].r;
}
SDL_SetColors(s, colors, 0 , 256);
}
int main (int argc, char* argv[])
{
SDL_bool done = SDL_FALSE;
SDL_Surface *screen;
Uint32 nextTime;
Uint8 shift = 0;
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError() );
return EXIT_FAILURE;
}
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE | SDL_HWPALETTE);
if(screen == NULL)
{
fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
return EXIT_FAILURE;
}
init(screen);
nextTime = SDL_GetTicks() + TICK_INTERVAL;
while (!done)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
done = SDL_TRUE;
break;
case SDL_KEYDOWN:
{
if (event.key.keysym.sym == SDLK_ESCAPE)
done = SDL_TRUE;
break;
}
}
}
/* On actualise la palette enfonction du décalage actuel */
setPalette(screen, shift);
/* On augmente le décalage */
shift++;
/* On maintient le décalage dans la plage 0 - 255 */
shift %= 256;/* -> /*shift &= 0xff c'est plus geek! */
/* On patiente avent le prochain affichage */
SDL_Delay(time_left(nextTime));
nextTime += TICK_INTERVAL;
SDL_Flip(screen);
}
SDL_Quit();
return 0;
}
|
Avec ces petits trucs, vous pouvez arriver à avoir des résultats bluffants.
Variez les palettes, testez des fonctions...
Postez vos créations ici, avec peut être une miniature du résultat si c'est possible.
En éspérant voir bientôt pleins de jolis plasmas dans ce topic.
a+
Et n'hésitez pas si vous avez la moindre question...
Édité
le 19/12/2009 à 20:31:58
par GurneyH
|
Trance forever :)

|
Bon ça m'énerve ton truc j'arrive pas à faire des trucs jolis 
J'ai fait un truc aléatoire et c'est moche encore
Voilà le code (c'est le même que le tiens avec quelques touches perso  ) et quelques fonctions en plus
Secret (cliquez pour afficher)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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185 | #include <SDL.h>
#include <math.h>
#define PI 3.14159265
#define PI2 6.28318531
#define TICK_INTERVAL 20
#define SHIFT_SPEED 1
void fatal_error(char *msg, char *error) {
fprintf(stderr, "%s: %s\n", msg, error);
exit(EXIT_FAILURE);
}
Uint32 time_left(Uint32 nextTime)
{
Uint32 now = SDL_GetTicks();
return nextTime <= now ? 0 : nextTime - now;
}
void putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
Uint8 f1(Sint16 a, Sint16 b)
{
return 128 + 127 * sin(a / 16.);
}
Uint8 f2(Sint16 a, Sint16 b)
{
return 128 + 127 * sin(b / 16.0);
}
Uint8 f3(Sint16 a, Sint16 b)
{
return 128 + 127 * sin((a + b) / 32.0);
}
Uint8 f4(Sint16 a, Sint16 b)
{
return 128 + 127 * sin(sqrt(a * a + b * b) / 16.0);
}
Uint8 rond(Sint16 x, Sint16 y) {
return 128 + 127 * sin(sqrt(x * x + y * y) / 16.);
}
Uint8 carre(Sint16 x, Sint16 y) {
return 128 + 127 * sin(sqrt(x * y) / 16.);
}
void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y)
{
struct fct {
Uint8 (*fct) (Sint16, Sint16);
};
struct fct st[6] = { f1, f2, f3, f4, rond, carre };
Uint8 color = st[rand()%6].fct(x, y);
putPixel(s, x, y, color);
}
void init_screen(SDL_Surface *s)
{
Sint16 x, y;
if ( SDL_MUSTLOCK(s) )
if ( SDL_LockSurface(s) < 0 )
fatal_error("Can't lock screen", SDL_GetError());
for(y = 0; y < s->h; ++y)
for(x = 0; x < s->w; ++x)
applyPlasma(s, x, y);
if (SDL_MUSTLOCK(s))
SDL_UnlockSurface(s);
}
void setPalette(SDL_Surface *s, Uint8 shift)
{
SDL_Color colors[256];
int i;
/* Décalage */
double f = SHIFT_SPEED * (2 * PI * shift / 256);
for(i = 0; i < 256; i++)
{
double angle = i * PI / 128.0 + f;
colors[i].r = 128 + 127 * sin(angle);
colors[i].g = colors[i].r;
colors[i].b = colors[i].r;
}
SDL_SetColors(s, colors, 0 , 256);
}
SDL_Surface * init(void) {
SDL_Surface *screen;
if (SDL_Init( SDL_INIT_VIDEO ) < 0)
fatal_error("Unable to init SDL", SDL_GetError());
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE | SDL_HWPALETTE);
if(screen == NULL)
fatal_error("Unable to set 640x480 video", SDL_GetError());
return screen;
}
int main (int argc, char* argv[])
{
SDL_Surface *screen = init();
SDL_bool done = SDL_FALSE;
Uint32 nextTime;
Uint8 shift = 0;
srand(time(NULL));
init_screen(screen);
nextTime = SDL_GetTicks() + TICK_INTERVAL;
while (!done)
{
SDL_Event event;
while (SDL_PollEvent(&event))
if (event.type == SDL_QUIT || event.key.keysym.sym == SDLK_ESCAPE)
done = SDL_TRUE;
/* On actualise la palette enfonction du décalage actuel */
setPalette(screen, shift);
/* On augmente le décalage */
shift++;
/* On maintient le décalage dans la plage 0 - 255 */
shift %= 256;/* -> /*shift &= 0xff c'est plus geek! */
/* On patiente avent le prochain affichage */
SDL_Delay(time_left(nextTime));
nextTime += TICK_INTERVAL;
SDL_Flip(screen);
}
SDL_Quit();
return 0;
}
|
Tuto sur le préprocesseur C
Pourquoi en vieillissant les biscuits durs deviennent mous et les biscuits mous deviennent durs ?
Est-ce que le mot «tumeur» a été inventé par un médecin qui aime l'humour noir?
warning: target of assignment not really an lvalue; this will be a hard error in the future
|

|
Là, j'ai pas le temps, :'
mais promis, je regarde. Dans peu de temps...
Et je donne des astuces pour faire des trucs jolis...
Je rappelle, c'est accessible à tout le monde...
et, merci Pouet...
Alors, tu as tenté... Génération de surface aléatoire!
Je n'y avais pas pensé, et c'est pour ça, que j'ai ouvert ce topic...
Pour être surpris...
Normalement, si tout va bien, je reposte des exemples plus tard...
Mais, en restant simple, on obtient des choses jolies...
Qui pour la couleur?
Édité
le 19/12/2009 à 23:10:42
par GurneyH
|
Trance forever :)

|
A vrai dire l'aléatoire je l'ai tenté vraiment parce que j'arrivais pas à avoir un bon rendu
Sinon en modifiant un peu mes fonctions j'arrive à ce résultat :
Secret (cliquez pour afficher)
Le code :
Secret (cliquez pour afficher)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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157 | #include <SDL.h>
#include <math.h>
#define PI 3.14159265
#define PI2 6.28318531
#define TICK_INTERVAL 20
#define SHIFT_SPEED 2
void fatal_error(char *msg, char *error) {
fprintf(stderr, "%s: %s\n", msg, error);
exit(EXIT_FAILURE);
}
Uint32 time_left(Uint32 nextTime)
{
Uint32 now = SDL_GetTicks();
return nextTime <= now ? 0 : nextTime - now;
}
void putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
Uint8 rond(Sint16 x, Sint16 y) {
return (x * x + y * y) % 256;
}
Uint8 carre(Sint16 x, Sint16 y) {
return (x * y) % 256;
}
void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y)
{
Uint8 color = (rond(x, y) + carre(x, y)) / 2;
putPixel(s, x, y, color);
}
void init_screen(SDL_Surface *s)
{
Sint16 x, y;
if ( SDL_MUSTLOCK(s) )
if ( SDL_LockSurface(s) < 0 )
fatal_error("Can't lock screen", SDL_GetError());
for(y = 0; y < s->h; ++y)
for(x = 0; x < s->w; ++x)
applyPlasma(s, x, y);
if (SDL_MUSTLOCK(s))
SDL_UnlockSurface(s);
}
void setPalette(SDL_Surface *s, Uint8 shift)
{
SDL_Color colors[256];
int i;
/* Décalage */
double f = SHIFT_SPEED * (2 * PI * shift / 256);
for(i = 0; i < 256; i++)
{
double angle = i * PI / 128.0 + f;
colors[i].r = 128 + 127 * sin(angle);
colors[i].g = colors[i].r;
colors[i].b = colors[i].r;
}
SDL_SetColors(s, colors, 0 , 256);
}
SDL_Surface * init(void) {
SDL_Surface *screen;
if (SDL_Init( SDL_INIT_VIDEO ) < 0)
fatal_error("Unable to init SDL", SDL_GetError());
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE | SDL_HWPALETTE);
if(screen == NULL)
fatal_error("Unable to set 640x480 video", SDL_GetError());
return screen;
}
int main (int argc, char* argv[])
{
SDL_Surface *screen = init();
SDL_bool done = SDL_FALSE;
Uint32 nextTime;
Uint8 shift = 0;
srand(time(NULL));
init_screen(screen);
nextTime = SDL_GetTicks() + TICK_INTERVAL;
while (!done)
{
SDL_Event event;
while (SDL_PollEvent(&event))
if (event.type == SDL_QUIT || event.key.keysym.sym == SDLK_ESCAPE)
done = SDL_TRUE;
/* On actualise la palette enfonction du décalage actuel */
setPalette(screen, shift);
/* On augmente le décalage */
shift++;
/* On maintient le décalage dans la plage 0 - 255 */
shift %= 256;/* -> /*shift &= 0xff c'est plus geek! */
/* On patiente avent le prochain affichage */
SDL_Delay(time_left(nextTime));
nextTime += TICK_INTERVAL;
SDL_Flip(screen);
}
SDL_Quit();
return 0;
}
|
Pour la couleur j'ai essayé mais j'ai toujours les mêmes variantes et c'est pas forcement joli joli je vais tenter autre chose 
Jouer un peu avec SDL_SetColors
Tuto sur le préprocesseur C
Pourquoi en vieillissant les biscuits durs deviennent mous et les biscuits mous deviennent durs ?
Est-ce que le mot «tumeur» a été inventé par un médecin qui aime l'humour noir?
warning: target of assignment not really an lvalue; this will be a hard error in the future
|

|
2 fonctions, c'est a peine assez...
Malgré tout, tu peux obtenir ça
Secret (cliquez pour afficher)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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 | #include <SDL.h>
#include <math.h>
#include <time.h>
#define PI 3.14159265
#define PI2 6.28318531
#define TICK_INTERVAL 20
#define SHIFT_SPEED 2
void fatal_error(char *msg, char *error) {
fprintf(stderr, "%s: %s\n", msg, error);
exit(EXIT_FAILURE);
}
Uint32 time_left(Uint32 nextTime)
{
Uint32 now = SDL_GetTicks();
return nextTime <= now ? 0 : nextTime - now;
}
void putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
} else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
Uint8 rond(Sint16 x, Sint16 y) {
return (x * x + y * y) / 32.0;
}
Uint8 carre(Sint16 x, Sint16 y) {
return (x * y) / 64.0;
}
void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y)
{
Uint8 color = (rond(x, y) + carre(x, y)) / 2;
putPixel(s, x, y, color);
}
void init_screen(SDL_Surface *s)
{
Sint16 x, y;
if ( SDL_MUSTLOCK(s) )
if ( SDL_LockSurface(s) < 0 )
fatal_error("Can't lock screen", SDL_GetError());
for(y = 0; y < s->h; ++y)
for(x = 0; x < s->w; ++x)
applyPlasma(s, x, y);
if (SDL_MUSTLOCK(s))
SDL_UnlockSurface(s);
}
void setPalette(SDL_Surface *s, Uint8 shift)
{
SDL_Color colors[256];
int i;
/* Décalage */
double f = SHIFT_SPEED * (2 * PI * shift / 256);
for(i = 0; i < 256; i++)
{
double angle = i * PI / 128.0 + f;
colors[i].r = 128 + 127 * cos(i * PI / 128 + f);
colors[i].g = 128 + 127 * sin(i * PI / 128 + f) ;
colors[i].b = 128 - 127 * cos(i * PI / 128 + f);
}
SDL_SetColors(s, colors, 0 , 256);
}
SDL_Surface * init(void) {
SDL_Surface *screen;
if (SDL_Init( SDL_INIT_VIDEO ) < 0)
fatal_error("Unable to init SDL", SDL_GetError());
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE | SDL_HWPALETTE);
if(screen == NULL)
fatal_error("Unable to set 640x480 video", SDL_GetError());
return screen;
}
int main (int argc, char* argv[])
{
SDL_Surface *screen = init();
SDL_bool done = SDL_FALSE;
Uint32 nextTime;
Uint8 shift = 0;
srand(time(NULL));
init_screen(screen);
nextTime = SDL_GetTicks() + TICK_INTERVAL;
while (!done)
{
SDL_Event event;
while (SDL_PollEvent(&event))
if (event.type == SDL_QUIT || event.key.keysym.sym == SDLK_ESCAPE)
done = SDL_TRUE;
/* On actualise la palette enfonction du décalage actuel */
setPalette(screen, shift);
/* On augmente le décalage */
shift++;
/* On maintient le décalage dans la plage 0 - 255 */
shift %= 256;/* -> /*shift &= 0xff c'est plus geek! */
/* On patiente avent le prochain affichage */
SDL_Delay(time_left(nextTime));
nextTime += TICK_INTERVAL;
SDL_Flip(screen);
}
SDL_Quit();
return 0;
}
|

Ce n'est pas si mal...
Essaye de cumuler plus de fonctions.
Sinon rien qu'avec les 4 malheureuses fonctions que j'ai montré et une palette sympa, on fait des trucs de warrior...
Et merci pour ta participation...
|
Traqueur de conneries.

Ville : Grenoble
Pays : France métropolitaine études : Ensimag
|
@GurneyH : C'est très joli !! Bravo pour ce topic
|

|
Citation : Arthurus@GurneyH : C'est très joli !! Bravo pour ce topic 
Merci.
Je me rend compte que je n'ai pas été très clair sur la création des fonctions...
prenons la fonction f(x) = sin(2 * PI * x / SCR_W)
Les fonctions de <math.h> travaillent avec des angles en radian.
Ici, je découpe mon cercle en SCR_W parties.
la plage 0 à 2 * PI s'étendra de 0 à SCR_W.
en multipliant l'angle je change la fréquence...
f(x) = sin((2 * PI * x / SCR_W) * fréquence)
Un autre pour la route.  Et peux être pour vous donner envie d'essayer.
Secret (cliquez pour afficher)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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202 | #include <SDL.h>
#include <math.h>
#define SCR_W 640
#define SCR_H 480
#define PI 3.14159265
#define PI2 6.28318531
#define TICK_INTERVAL 20
/* Vitesses des décalages appliqué aux composantes RGB */
#define R_SHIFT_SPEED 1
#define G_SHIFT_SPEED 2
#define B_SHIFT_SPEED 3
#define dist(a, b)(sqrt((a) * (a) + (b) * (b)))
Uint32 time_left(Uint32 nextTime)
{
Uint32 now = SDL_GetTicks();
return nextTime <= now ? 0 : nextTime - now;
}
void putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch (bpp)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
}
}
Uint8 f1(Sint16 x, Sint16 y)
{
return 128 + 127 * sin(dist(SCR_W / 2.0 - x, SCR_H / 2.0 - y) / 32.0);
}
Uint8 f2(Sint16 x)
{
return 128 + 127 * sin(x * PI2 / SCR_W);
}
Uint8 f3(Sint16 y)
{
return 128 + 127 * sin(y * PI2 / SCR_H);
}
Uint8 f4(Sint16 x, Sint16 y)
{
return 128 + 127 * sin((x + y) * PI2 / (SCR_W + SCR_H));
}
void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y)
{
Uint8 color = (f1(x, y) + f2(x) + f3(y) + f4(x, y))/ 4;
putPixel(s, x, y, color);
}
void init(SDL_Surface *s)
{
Sint16 x, y;
if ( SDL_MUSTLOCK(s) )
if ( SDL_LockSurface(s) < 0 )
{
fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
exit (EXIT_FAILURE);
}
for (y = 0; y < s->h; ++y)
for (x = 0; x < s->w; ++x)
applyPlasma(s, x, y);
if (SDL_MUSTLOCK(s))
SDL_UnlockSurface(s);
}
void setPalette(SDL_Surface *s, Uint8 shift)
{
SDL_Color colors[256];
int i;
for (i = 0; i < 256; i++)
{
double f = PI2 * ((shift + i) % 256) / 256;
colors[i].r = 128 + 127 * sin(R_SHIFT_SPEED * f);
colors[i].g = 128 + 127 * sin(G_SHIFT_SPEED * f);
colors[i].b = 128 + 127 * sin(B_SHIFT_SPEED * f);
}
SDL_SetColors(s, colors, 0 , 256);
}
int main (int argc, char* argv[])
{
SDL_bool done = SDL_FALSE;
SDL_Surface *screen;
Uint32 nextTime;
Uint8 shift = 0;
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError() );
return EXIT_FAILURE;
}
screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE | SDL_HWPALETTE);
if (screen == NULL)
{
fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
return EXIT_FAILURE;
}
init(screen);
nextTime = SDL_GetTicks() + TICK_INTERVAL;
while (!done)
{
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
done = SDL_TRUE;
break;
case SDL_KEYDOWN:
{
if (event.key.keysym.sym == SDLK_ESCAPE)
done = SDL_TRUE;
break;
}
}
}
/* On actualise la palette enfonction du décalage actuel */
setPalette(screen, shift);
/* On augmente le décalage */
shift++;
/* On maintient le décalage dans la plage 0 - 255 */
shift %= 256;/* -> shift &= 0xff c'est plus geek! */
/* On patiente avent le prochain affichage */
SDL_Delay(time_left(nextTime));
nextTime += TICK_INTERVAL;
SDL_Flip(screen);
}
SDL_Quit();
return 0;
}
|
Et un un lien sympa pour tester des fonctions.
Édité
le 20/12/2009 à 07:18:32
par GurneyH
|

|
Merci pour ton post,
ça va me booster pour entamer la SDL
On est pas responsable de la gueule que l'on a.
En revanche on est responsable de la tronche que l'on fait !
|
Trance forever :)

|
Ah le rond c'est celui-là que je voulais faire 
J'étais sur la mauvaise voie
Voilà un petit truc avec la fonction rond (f1) et ma fonction carre remodelée d'après ce que GurneyH a dit 
Ca me donne enfin un résultat assez joli
Code : C 1
2
3
4
5
6
7
8
9
10
11
12
13
14 | Uint8 f1(Sint16 x, Sint16 y)
{
return 128 + 127 * sin(dist(SCR_W / 2.0 - x, SCR_H / 2.0 - y) / 32.0);
}
Uint8 rect(Sint16 x, Sint16 y) {
return 128 + 127 * sin((((SCR_W / 2.0 - x) * PI2 / SCR_W) * ((SCR_H / 2.0 - y) * PI2 / SCR_H)) / 2.);
}
void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y)
{
Uint8 color = (rect(x, y) + f1(x, y)) / 2;
putPixel(s, x, y, color);
}
|
Ya peut-être des parenthèses en trop
Voilà le rendu :
Secret (cliquez pour afficher)
Tuto sur le préprocesseur C
Pourquoi en vieillissant les biscuits durs deviennent mous et les biscuits mous deviennent durs ?
Est-ce que le mot «tumeur» a été inventé par un médecin qui aime l'humour noir?
warning: target of assignment not really an lvalue; this will be a hard error in the future
|

|
Joli...
Avec la palette ça donne une résultat très... seventies
|
This ass hole.

|
Intéressent , sa donne un effet illusions d'optique et c'est très amusant , j'arrête pas de faire des essais
Outside of my real world!
|