Aller au menu - Aller au contenu

Exercice... Plasma 1er round...

Toute lib graphique.

Pour accéder à cette section
Connectez-vous !
connexion_rpx
Page 1 
Auteur Message
1 visiteur sur ce sujet (1 Anonyme)
Page 1 
Hors ligne GurneyH # Posté le 19/12/2009 à 18:52:12
Avatar

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...
Image utilisateur
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 : Autre
1
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;
}

Image utilisateurImage utilisateurImage utilisateurImage utilisateur
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;
}

Image utilisateur


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
 
Hors ligne Pouet_forever # Posté le 19/12/2009 à 22:15:36
Trance forever :)
Avatar

Bon ça m'énerve ton truc j'arrive pas à faire des trucs jolis :lol:
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 :p ) 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? :lol:
warning: target of assignment not really an lvalue; this will be a hard error in the future

Codes sources Apple c'est par là -> Apple Open Source

 
Hors ligne GurneyH # Posté le 19/12/2009 à 22:20:07
Avatar

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
 
Hors ligne Pouet_forever # Posté le 19/12/2009 à 23:41:01
Trance forever :)
Avatar

A vrai dire l'aléatoire je l'ai tenté vraiment parce que j'arrivais pas à avoir un bon rendu :p

Sinon en modifiant un peu mes fonctions j'arrive à ce résultat :

Secret (cliquez pour afficher)
Image utilisateur


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? :lol:
warning: target of assignment not really an lvalue; this will be a hard error in the future

Codes sources Apple c'est par là -> Apple Open Source

 
Hors ligne GurneyH # Posté le 20/12/2009 à 00:08:12
Avatar

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;
}

Image utilisateur
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... :pirate:
Et merci pour ta participation... :)
 
Hors ligne Arthurus # Posté le 20/12/2009 à 04:18:48
Traqueur de conneries.
Avatar

Ville : Grenoble
Pays : France métropolitaine
études : Ensimag

@GurneyH : C'est très joli !! Bravo pour ce topic ;)

 
Hors ligne GurneyH # Posté le 20/12/2009 à 04:25:19
Avatar

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.
Image utilisateur
Image utilisateur
Image utilisateur

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. :soleil:
Édité le 20/12/2009 à 07:18:32 par GurneyH
 
Hors ligne darkipod # Posté le 20/12/2009 à 07:08:57
Avatar

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 !
 
Hors ligne Pouet_forever # Posté le 20/12/2009 à 12:33:09
Trance forever :)
Avatar

Ah le rond c'est celui-là que je voulais faire :lol:
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 :D

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 :

Image utilisateur

Secret (cliquez pour afficher)
Image utilisateur

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? :lol:
warning: target of assignment not really an lvalue; this will be a hard error in the future

Codes sources Apple c'est par là -> Apple Open Source

 
Hors ligne GurneyH # Posté le 20/12/2009 à 14:00:44
Avatar

Joli... :)
Avec la palette ça donne une résultat très... seventies :lol:
 
Hors ligne sercus i # Posté le 20/12/2009 à 14:57:37
This ass hole.
Avatar

Intéressent , sa donne un effet illusions d'optique et c'est très amusant , j'arrête pas de faire des essais :lol:

Outside of my real world!
 

Retour au forum "Langage C" ou à la liste des forums

Pour accéder à cette section
Connectez-vous !
connexion_rpx