Partage
  • Partager sur Facebook
  • Partager sur Twitter

Exercice... Plasma 1er round...

Toute lib graphique.

    19 décembre 2009 à 18:52:13

    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
    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...
    #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).
    #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...
    • Partager sur Facebook
    • Partager sur Twitter
    Zeste de Savoir, le site qui en a dans le citron !
      19 décembre 2009 à 22:15:36

      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 :)

      #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;
      }
      
      • Partager sur Facebook
      • Partager sur Twitter
        19 décembre 2009 à 22:20:07

        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?
        • Partager sur Facebook
        • Partager sur Twitter
        Zeste de Savoir, le site qui en a dans le citron !
          19 décembre 2009 à 23:41:02

          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 :

          Image utilisateur


          Le code :

          #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 :)
          • Partager sur Facebook
          • Partager sur Twitter
            20 décembre 2009 à 0:08:12

            2 fonctions, c'est a peine assez...
            Malgré tout, tu peux obtenir ça
            #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... :)
            • Partager sur Facebook
            • Partager sur Twitter
            Zeste de Savoir, le site qui en a dans le citron !
              20 décembre 2009 à 4:18:49

              @GurneyH : C'est très joli !! Bravo pour ce topic ;)
              • Partager sur Facebook
              • Partager sur Twitter
                20 décembre 2009 à 4:25:20

                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

                #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:
                • Partager sur Facebook
                • Partager sur Twitter
                Zeste de Savoir, le site qui en a dans le citron !
                  20 décembre 2009 à 7:08:58

                  Merci pour ton post,
                  ça va me booster pour entamer la SDL
                  • Partager sur Facebook
                  • Partager sur Twitter
                    20 décembre 2009 à 12:33:09

                    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

                    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

                    Image utilisateur
                    • Partager sur Facebook
                    • Partager sur Twitter
                      20 décembre 2009 à 14:00:44

                      Joli... :)
                      Avec la palette ça donne une résultat très... seventies :lol:
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Zeste de Savoir, le site qui en a dans le citron !
                        20 décembre 2009 à 14:57:37

                        Intéressent , sa donne un effet illusions d'optique et c'est très amusant , j'arrête pas de faire des essais :lol:
                        • Partager sur Facebook
                        • Partager sur Twitter
                          9 août 2010 à 10:23:22

                          Bon, détérage de topic, mais sa m'a bien fait triper ce p'tit "jeu", alors je poste mon image...

                          Je n'ai pas utiliser la technique de la palette, mais directement des variations des composantes RGB de chaque pixel.

                          A chaque démarrage, les couleurs sont choisies au hasard, ainsi que la vitesse de progression que chaque composante RGB, l'amplitude de la fonction periodique_pi, la fréquence de la fonction periodique_pi, ect...

                          On peut facilement changer la fonction de la fonction periodique_pi, il faut juste qu'elle soit comprise entre -1 et 1 quelque soit le float passé en paramètre. La fonction fmod peut être pratique... :D La valeur de f est "propotionnée" à PI (i.e. que l'on peut considérer que f est la paramètre d'une fonction PI périodique par rapport à l'écran...)

                          Le R avance horizontalement, le G verticalement et le B latéralement. Dans mes exemples, les fonction pour R, G et B sont identiques.

                          Avec periodique_pi: return sinf(f);
                          Image utilisateur

                          Avec periodique_pi: f = fmod(f, 2*M_PI); return f/(M_PI)-1;
                          Image utilisateur

                          On peux aussi tester sin(f*50): style à carreau très sympa... ect...
                          Voir faire des fonctions pour R, G, B différentes ect...
                          C'est un peu une variante à la palette, on est moins contraint, car on peut vraiment faire une fonction par couleur.


                          #include <SDL/SDL.h>
                          #include <SDL/SDL_ttf.h>
                          
                          #include <math.h>
                          #include <time.h>
                          #include <float.h>
                          
                          #define SCR_W           640
                          #define SCR_H           480
                          
                          #define TICK_INTERVAL   75
                          
                          #define FONT            "verdana.ttf"
                          #define FONT_SIZE       64
                          
                          // Speed:
                          #define R_SPEED_MINI    15
                          #define G_SPEED_MINI    20
                          #define B_SPEED_MINI    45
                          
                          #define R_SPEED_DELTA   10
                          #define G_SPEED_DELTA   10
                          #define B_SPEED_DELTA   10
                          
                          #define PLASMA_MODULO   5
                          
                          #define TEXT            "Mon texte défillant..."
                          #define TEXT_SPEED      2
                          
                          // M_AMP_DELTA + M_AMP_MINI <= 127
                          #define R_M_AMP_MINI    27
                          #define G_M_AMP_MINI    27
                          #define B_M_AMP_MINI    27
                          
                          #define R_M_AMP_DELTA   63
                          #define G_M_AMP_DELTA   63
                          #define B_M_AMP_DELTA   63
                          
                          // Amplitutde delta
                          #define R_AMP_DELTA     0
                          #define G_AMP_DELTA     0
                          #define B_AMP_DELTA     0
                          
                          // SINUS SIZE
                          #define R_RANGE_MINI    SCR_W*3
                          #define G_RANGE_MINI    SCR_H*3
                          #define B_RANGE_MINI    (SCR_W+SCR_H)*3
                          
                          #define R_RANGE_DELTA   SCR_W
                          #define G_RANGE_DELTA   SCR_H
                          #define B_RANGE_DELTA   (SCR_W+SCR_H)
                          
                          Uint32 time_left()
                          {
                              static Uint32 nextTime = SDL_GetTicks();
                              Uint32 now = SDL_GetTicks();
                              nextTime += TICK_INTERVAL;
                              return nextTime <= now ? 0 : nextTime - now;
                          }
                          
                          void setPixel(int x, int y, Uint32 color, SDL_Surface *map)
                          {
                            if(x>0 && y>0 && x<map->w && y<map->h)
                              *((Uint32*)(map->pixels) + x + y * map->w) = color;
                          }
                          
                          int setInRange(int value, int min, int max)
                          {
                              return fmin(fmax(value, min), max);
                          }
                          
                          float periodic_2piR(float f)
                          {
                              return sinf(f);
                          }
                          
                          float periodic_2piG(float f)
                          {
                              return sinf(f);
                          }
                          
                          float periodic_2piB(float f)
                          {
                              return sinf(f);
                          }
                          
                          void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y, int time)
                          {
                              static int r_speed = R_SPEED_MINI + rand()%R_SPEED_DELTA;
                              static int g_speed = G_SPEED_MINI + rand()%G_SPEED_DELTA;
                              static int b_speed = B_SPEED_MINI + rand()%B_SPEED_DELTA;
                          
                              static int r_m_amp = setInRange(R_M_AMP_MINI + rand()%R_M_AMP_DELTA, 0, 127);
                              static int g_m_amp = setInRange(G_M_AMP_MINI + rand()%G_M_AMP_DELTA, 0, 127);
                              static int b_m_amp = setInRange(B_M_AMP_MINI + rand()%B_M_AMP_DELTA, 0, 127);
                          
                              static int r_amp = fmin(r_m_amp, 255 - r_m_amp) - rand()%setInRange(R_AMP_DELTA, 1, r_m_amp);
                              static int g_amp = fmin(g_m_amp, 255 - g_m_amp) - rand()%setInRange(G_AMP_DELTA, 1, g_m_amp);
                              static int b_amp = fmin(b_m_amp, 255 - b_m_amp) - rand()%setInRange(B_AMP_DELTA, 1, b_m_amp);
                          
                              static int r_range = R_RANGE_MINI + rand()%R_RANGE_DELTA;
                              static int g_range = G_RANGE_MINI + rand()%G_RANGE_DELTA;
                              static int b_range = B_RANGE_MINI + rand()%B_RANGE_DELTA;
                          
                              static int r_shift = rand()%r_range;
                              static int g_shift = rand()%g_range;
                              static int b_shift = rand()%b_range;
                          
                              Uint32 color = SDL_MapRGBA(s->format, r_m_amp + periodic_2piR(float(x+time*r_speed+r_shift)*M_PI/r_range)*r_amp, g_m_amp + periodic_2piG(float(y+time*g_speed+g_shift)*M_PI/g_range)*g_amp,  b_m_amp + periodic_2piB(float((x+y)+time*b_speed+b_shift)*M_PI/b_range)*b_amp, 255);
                              setPixel(x, y, color, s);
                          }
                          
                          
                          void setPlasma(SDL_Surface *s)
                          {
                              Sint16 x, y;
                              static int time = 0;
                              time++;
                          
                              for (y = 0; y < SCR_H; ++y)
                                  for (x = 0; x < SCR_W; ++x)
                                      applyPlasma(s, x, y, time);
                          }
                          
                          int main (int argc, char* argv[])
                          {
                              SDL_bool done = SDL_FALSE;
                              SDL_Surface *screen = NULL;
                              SDL_Surface *plasma = NULL;
                              SDL_Surface *text = NULL;
                              SDL_Rect position_text, position_backgroud;
                              SDL_Color white_color = {255, 255, 255};
                              TTF_Font *font = NULL;
                              int text_x_position;
                              int i = 0;
                          
                              srand(time(NULL));
                          
                              if(SDL_Init(SDL_INIT_VIDEO)==-1) exit(EXIT_FAILURE);
                              if(TTF_Init()==-1) exit(EXIT_FAILURE);
                          
                              screen = SDL_SetVideoMode(SCR_W, SCR_H, 32, SDL_HWSURFACE | SDL_HWPALETTE);
                              plasma = SDL_CreateRGBSurface(SDL_HWSURFACE, SCR_W, SCR_W, 32, 0, 0, 0, 0);
                          
                              position_backgroud.x = 0;
                              position_backgroud.y = 0;
                          
                              font = TTF_OpenFont(FONT, FONT_SIZE);
                          
                              if(strcmp(TEXT, ""))
                                  text = TTF_RenderText_Blended (font, TEXT, white_color);
                              else
                                  text = SDL_CreateRGBSurface(SDL_HWSURFACE, 0, 0, 32, 0, 0, 0, 0);
                              text_x_position = SCR_W;
                              position_text.y = (SCR_H - text->h)/2;
                          
                              TTF_CloseFont(font);
                          
                              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 */
                                  if(!(i%PLASMA_MODULO))
                                      setPlasma(plasma);
                          
                                  if(text->w>SCR_W)
                                  {
                                      text_x_position-=TEXT_SPEED;
                                      if((text_x_position+text->w)<0)
                                          text_x_position = SCR_W;
                                  }
                                  else
                                      text_x_position = (SCR_W - text->w)/2;
                          
                                  position_text.x = text_x_position;
                                  SDL_BlitSurface(plasma, NULL, screen, &position_backgroud);
                                  SDL_BlitSurface(text, NULL, screen, &position_text);
                          
                                  /* On patiente avent le prochain affichage */
                                  SDL_Delay(time_left());
                          
                                  SDL_Flip(screen);
                                  i++;
                              }
                          
                              SDL_Quit();
                          
                              return 0;
                          }
                          
                          • Partager sur Facebook
                          • Partager sur Twitter
                            9 août 2010 à 16:21:36

                            Le problème en faisant une moyenne, c'est qu'on aura plus souvent des valeurs proches de la médiane si la distribution des fonctions est égale sur toutes ses valeurs de retour. (c'est pareil avec les dés : il est plus facile d'avoir 7 avec 2 dés que d'avoir 2 ou 12)
                            Plutôt que de faire une moyenne, pourquoi ne pas faire un modulo avec une palette de couleurs dont la fin rejoint le début. (il vaut mieux compter plus de 3 fonctions différentes pour avoir un rendu acceptable au niveau des couleurs).
                            Ou encore, pourquoi ne pas utiliser 4 fonctions différentes : 3 pour avoir une fonction par couleur et une dernière fonction pour la luminosité.

                            Je n'ai pas "le courage" de coder ça mais pourquoi ne pas utiliser des fonctions plus complexes puisque c'est du statique ?
                            Un exemple éventuel :
                            <math>\(\text{rouge : }\frac{e^{(x+y) \times coef_1}+e^{(-x-y) \times coef_2}}{2} + rand(-2,2)\)</math>
                            <math>\(\text{vert : }\frac{e^{(x-y) \times coef_3}-e^{(-x+y) \times coef_4}}{2} + rand(-2,2)\)</math>
                            <math>\(\text{bleu : }arctan(x+y)\times coef_5 + rand(-2,2)\)</math>
                            <math>\(\text{luminosite : }(x - x_1)^2 + (y - y_1)^2 - (x - x_2)^2 - (y - y_2)^2\)</math>
                            Des coefficients peuvent être pris au hasard ou calculés en fonction de l'image. Ne pas oublier de faire un modulo si ça dépasse.
                            Pour la luminosité, il s'agit de faire une différence entre la distance au carré entre un point et un autre.

                            La randomisation ne doit pas être trop grande pour éviter les sauts brutaux entre les différentes couleurs. Une autre manière de faire cette randomisation serait de prendre le rand des valeurs en haut et à gauche du pixel considérer et d'ajouter +- 1 à la moyenne de ce random.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              9 août 2010 à 16:59:11

                              Désolé, j'ai loupé le déterrage. :p

                              Alors AstroB ce que tu fais n'est plus trop un plasma(visuellement), mais c'est très sympa.
                              fmin et fmax, tu trouves ça ou? c'est inconnu chez moi.

                              @Alienore: effectivement, rien n'empêche d'utiliser des fonctions plus complexes.
                              Même si on était pas en "statique", on pourrait en précalculant. (même pas sur qu'aujourd'hui ce soit nécessaire.).
                              D'ailleurs sur le premier post je donne un lien pour tester des fonctions.
                              edit: ce n'était pas dans le premier post lien
                              Et un un lien sympa pour tester des fonctions. :soleil:

                              En fait, ce qui est présenté c'est juste un amuse bouche, un cycle de couleur.

                              Un vrai plasma consiste au "mélange" de différentes surfaces basées sur des fonctions, chacune se déplaçant selon son propre schéma.

                              Au départ je voulais le présenter mais vu le succès ahurissant du topic, j'ai stoppé.

                              Finalement, je prendrais peut être le temps de présenter ce plasma.
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Zeste de Savoir, le site qui en a dans le citron !
                                9 août 2010 à 17:08:04

                                Il suffit d'ajouter des points centraux aux différentes fonctions et de déplacer ces points petit à petit au cours du temps pour avoir un schéma pour chaque surface. Il suffit ensuite d'appliquer les bonnes couleurs pour chaque surface.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  9 août 2010 à 17:11:01

                                  Citation : Alienore

                                  Il suffit d'ajouter des points centraux aux différentes fonctions et de déplacer ces points petit à petit au cours du temps pour avoir un schéma pour chaque surface. Il suffit ensuite d'appliquer les bonnes couleurs pour chaque surface.


                                  C'est exactement cela.

                                  Mais on peut obtenir de superbes rendus.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Zeste de Savoir, le site qui en a dans le citron !
                                    9 août 2010 à 23:10:45

                                    Oui, ce n'est pas vraiment du plasma, mais c'était en fait plus pour montrer une "autre" manière qu'avec la palette cyclique, à savoir en agissant sur chaque composante de la couleur. Après on peut même ajouter des arguments aux fonctions periodic_2piX, tel que la position en x et y, et du coup, ne plus les nommer periodic_2piX mais juste colorX(x, y). J'avais juste fait un exemple simple avec 2-3 fonctions que j'avais sous la main pour m'amuser!

                                    Après comme le suggère Alienore, mais en allant même "plus loin" (i.e. plus réaliser), et même en dynamique, pour avoir quelquechose "d'ultra réaliste", il faudrai utiliser l'équation de la chaleur, que l'on va discrétiser... j'ai trouver un petit site sympa qui rappel (à ceux qui aurait oublié leurs cours de méthodes numériques et consort), comme faire la dicrétisation avec les conditions aux limites (qui dans le cas du plasma peuvent également être placée en interne ect...)

                                    Si on veut pas s'emmerder avec la physique, votre idée est pas mal non plus (et assez proche "thermodynamiquement parlant"), si j'ai bien compris, j'en déduit l'algo suivant:
                                    - On prend un certain nombre de cercles (de différentes taille) avec comme paramètre 3 chiffres (la puissance de R, G et B de chaque)
                                    - On fixe le fond à noir au début
                                    - On se fait se déplacer "aléatoirement" (disont la trajectoire est aléatoire mais une fois dans l'écran elle reste droite jusqu'à sortie)
                                    - Pour chaque x et y, si un cercle est présent, on augment chacune de ses composantes d'un certain nombre (fonction de la "puissance" fournie par le cercle), sinon, on décrémente d'un certain nombre (puissance "dissipée").

                                    Si j'ai le temps, je coderai un petit truc...

                                    fmin et fmax, c'est min et max, mais qui renvoie un float :D
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      10 août 2010 à 3:56:06

                                      Citation : AstroB


                                      fmin et fmax, c'est min et max, mais qui renvoie un float :D


                                      C'est du C99. Je ne connssais pas ces fonctions.



                                      Citation : AstroB


                                      Si j'ai le temps, je coderai un petit truc...


                                      Ne te prive surtout pas.

                                      Par contre on ne travaille pas forcément avec des cercles, mais avec n'importe quel type de forme.
                                      Je vais en coder un en dynamique de mon coté(sans trop de maths. :-°).

                                      edit:
                                      Un fond de tiroir pour commencer. :p
                                      #include <sdl/sdl.h>
                                      #include <math.h>
                                      #include <stdlib.h>
                                      #include <time.h>
                                      
                                      #define TICK_INTERVAL    20
                                      
                                      #define SCR_W   640
                                      #define SCR_H   480
                                      #define SCR_BPP 32
                                      
                                      #define NB_BUF  3
                                      #define random(a) (1 + (a) * rand() / (RAND_MAX + 1.0))
                                      
                                      Uint32 time_left( Uint32 *nxtTime )
                                      {
                                          Uint32 now = SDL_GetTicks();
                                          return *nxtTime <= now ? 0 : *nxtTime - now;
                                      }
                                      
                                      
                                      void subDivide( Uint8 *b, Uint16 x1, Uint16 y1, Uint16 x2,
                                                                      Uint16 y2, Uint16 w, Uint16 h )
                                      {
                                          if ( x2 - x1 < 2 && y2 - y1 < 2 )
                                              return;
                                          else
                                          {
                                              Uint16 xm = ( x2 + x1 ) / 2;
                                              Uint16 ym = ( y2 + y1 ) / 2;
                                              Uint16 d = x2 - x1 + y2 - y1;
                                              Uint16 hd = d / 2;
                                              Uint8 c1 = b[y1 * w + x1];
                                              Uint8 c2 = b[y1 * w + x2];
                                              Uint8 c3 = b[y2 * w + x1];
                                              Uint8 c4 = b[y2 * w + x2];
                                      
                                              if ( !b[y1 * w + xm] )
                                                  b[y1 * w + xm] = ( c1 + c2 + random( d ) - hd ) / 2;
                                              if ( !b[y2 * w + xm] )
                                                  b[y2 * w + xm] = ( c3 + c4 + random( d ) - hd ) / 2;
                                              if ( !b[ym * w + x1] )
                                                  b[ym * w + x1] = ( c1 + c3 + random( d ) - hd ) / 2;
                                              if ( !b[ym * w + x2] )
                                                  b[ym * w + x2] = ( c2 + c4 + random( d ) - hd ) / 2;
                                      
                                              b[ym * w + xm] = ( c1 + c2 + c3 + c4 + random( d ) - hd ) / 4;
                                      
                                              subDivide( b, x1, y1, xm, ym, w, h );
                                              subDivide( b, xm, y1, x2, ym, w, h );
                                              subDivide( b, x1, ym, xm, y2, w, h );
                                              subDivide( b, xm, ym, x2, y2, w, h );
                                          }
                                      }
                                      
                                      
                                      
                                      void draw( Uint8 *b, Uint16 w, Uint16 h )
                                      {
                                          b[0] = random( 0xff );
                                          b[w - 1] = random( 0xff );
                                          b[( h - 1 )] = random( 0xff );
                                          b[( h - 1 ) * w + w - 1 ] = random( 0xff );
                                      
                                          subDivide( b, 0, 0, w, h, w, h );
                                      }
                                      
                                      
                                      
                                      void display( SDL_Surface *s, Uint8 **b, Uint32 f )
                                      {
                                          Uint16 xt, yt;
                                          int mw = SCR_W / 2;
                                          int mh = SCR_H / 2;
                                          int dw = SCR_W * 2;
                                          int src1, src2, src3;
                                      
                                          xt = mw + mw * cos( f / 97.0 );
                                          yt = mh + mh * sin( -f / 123.0 );
                                          src1 = yt * dw + xt;
                                          xt = mw + mw * sin( -f /  114.0 );
                                          yt = mh + mh * sin( f /  500.0 );
                                          src2 = yt * dw + xt;
                                          xt = mw + mw * cos( -f / 137.0 );
                                          yt = mh + mh * cos( -f / 108.0 );
                                          src3 = yt * dw + xt;
                                      
                                      
                                          if ( SDL_MUSTLOCK( s ) && SDL_LockSurface( s ) < 0 )
                                          {
                                              fprintf( stderr, "Can't lock screen: %s\n", SDL_GetError() );
                                              return;
                                          }
                                      
                                          {
                                              Uint16 x, y;
                                              for ( y = 0; y < SCR_H; ++y )
                                              {
                                                  Uint8 *offset = ( Uint8 * )s->pixels + y * s->pitch ;
                                                  for ( x = 0; x < SCR_W * 4; x += sizeof( Uint32 ) )
                                                      * ( Uint32 * )( offset + x ) =   ( b[0][src1++] << 16 ) +
                                                                                       ( b[1][src2++] <<  8 ) +
                                                                                       ( b[2][src3++] );
                                      
                                                  src1 += SCR_W;
                                                  src2 += SCR_W;
                                                  src3 += SCR_W;
                                              }
                                          }
                                      
                                          if ( SDL_MUSTLOCK( s ) )
                                          {
                                              SDL_UnlockSurface( s );
                                          }
                                      
                                      }
                                      
                                      
                                      int main( int argc, char *argv[] )
                                      {
                                          SDL_Surface *screen;
                                          Uint8 **buf;
                                          static Uint32 nextTime;
                                          Uint32 currentFrame = 0;
                                          int i;
                                          SDL_bool done = SDL_FALSE;
                                          Uint32 startTime;
                                      
                                          srand( ( unsigned int )time( NULL ) );
                                          if(SDL_Init(SDL_INIT_VIDEO) < 0)
                                          {
                                              printf( "Unable init SDL : %s", SDL_GetError() );
                                              exit( EXIT_FAILURE );
                                          }
                                      
                                          screen = SDL_SetVideoMode( SCR_W, SCR_H, SCR_BPP, SDL_SWSURFACE | SDL_FULLSCREEN );
                                          if ( screen == NULL )
                                          {
                                              printf( "Unable to set video mode : %s", SDL_GetError() );
                                              exit( EXIT_FAILURE );
                                          }
                                      
                                          SDL_ShowCursor( 0 );
                                          SDL_EventState( SDL_ACTIVEEVENT, SDL_IGNORE );
                                          SDL_EventState( SDL_MOUSEMOTION, SDL_IGNORE );
                                          SDL_EventState( SDL_MOUSEBUTTONDOWN, SDL_IGNORE );
                                          SDL_EventState( SDL_MOUSEBUTTONUP, SDL_IGNORE );
                                          SDL_EventState( SDL_SYSWMEVENT, SDL_IGNORE );
                                      
                                          buf = malloc( NB_BUF * sizeof *buf );
                                          if( buf == NULL )
                                                  return EXIT_FAILURE;
                                      
                                          for ( i = 0; i < NB_BUF; ++i )
                                          {
                                              buf[i] = malloc( 4 * SCR_W * SCR_H * sizeof *buf[i] );
                                              if( buf[i] == NULL )
                                                  return EXIT_FAILURE;
                                      
                                              draw( buf[i], SCR_W * 2, SCR_H * 2 );
                                          }
                                      
                                          startTime = SDL_GetTicks();
                                          nextTime = SDL_GetTicks() + TICK_INTERVAL;
                                          while ( !done )
                                          {
                                              SDL_Event events;
                                              while ( SDL_PollEvent( &events ) )
                                              {
                                                  if ( events.type == SDL_KEYDOWN && events.key.keysym.sym == SDLK_ESCAPE )
                                                      done = SDL_TRUE;
                                              }
                                              display( screen, buf, currentFrame );
                                      
                                              SDL_Delay( time_left( &nextTime ) );
                                              SDL_Flip( screen );
                                      
                                              nextTime += TICK_INTERVAL;
                                              currentFrame++;
                                          }
                                      
                                          printf( "%.2f fps\n", currentFrame * 1000.0 / ( SDL_GetTicks() - startTime ) );
                                      
                                          for ( i = 0; i < NB_BUF; ++i )
                                              free( buf[i] ), buf[i] = NULL;
                                          free( buf ), buf = NULL;
                                      
                                          SDL_Quit();
                                      
                                          ( void )argc;
                                          ( void )argv;
                                      
                                          return EXIT_SUCCESS;
                                      }
                                      

                                      pour un screenshot.

                                      La fonction subdivide n'est pas de moi. Je l'avais vu dans un prog en Pascal, le problème, c'est que je ne retrouve pas le lien.

                                      l'effet est plutôt sympa et pas trop matheux.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Zeste de Savoir, le site qui en a dans le citron !
                                        10 août 2010 à 12:15:19

                                        Voila, mais sa rame à mort de chez à mort!

                                        #include <SDL/SDL.h>
                                        
                                        #include <math.h>
                                        #include <time.h>
                                        #include <float.h>
                                        
                                        #define SCR_W           640
                                        #define SCR_H           480
                                        
                                        #define TICK_INTERVAL   100
                                        
                                        #define NB_SHAPE        20
                                        
                                        #define INIT_R          0
                                        #define INIT_G          0
                                        #define INIT_B          0
                                        
                                        #define DEC_R           -1
                                        #define DEC_G           -1
                                        #define DEC_B           -1
                                        
                                        #define SHAPE_R         SCR_H/6
                                        #define SHAPE_COLOR_INC 10
                                        #define SHAPE_POS_INC   3
                                        
                                        
                                        typedef struct struct_shape{
                                            int x;
                                            int y;
                                            int r;
                                            int r_inc;
                                            int g_inc;
                                            int b_inc;
                                            int x_inc;
                                            int y_inc;
                                        } shape;
                                        
                                        Uint32 time_left()
                                        {
                                            static Uint32 nextTime = SDL_GetTicks();
                                            Uint32 now = SDL_GetTicks();
                                            nextTime += TICK_INTERVAL;
                                            return nextTime <= now ? 0 : nextTime - now;
                                        }
                                        
                                        int setInRange(int value, int min, int max)
                                        {
                                            return fmin(fmax(value, min), max);
                                        }
                                        
                                        int isAtDistance(int x, int y, int x1, int y1, int distance)
                                        {
                                            return (pow(x-x1, 2)+pow(y-y1, 2) < pow(distance, 2));
                                        }
                                        
                                        void setPixel(int x, int y, Uint32 color, SDL_Surface *map)
                                        {
                                          if(x>0 && y>0 && x<map->w && y<map->h)
                                            *((Uint32*)(map->pixels) + x + y * map->w) = color;
                                        }
                                        
                                        void getPixelColor(int x, int y, SDL_Surface *map, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
                                        {
                                          if(x>0 && y>0 && x<map->w && y<map->h)
                                            SDL_GetRGBA(*((Uint32 *)map->pixels + x + y * map->w),map->format,r,g,b,a);
                                        }
                                        
                                        void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y, int r_inc, int g_inc, int b_inc)
                                        {
                                            Uint8 r, g, b, a;
                                            getPixelColor(x, y, s, &r, &g, &b, &a);
                                            Uint32 color = SDL_MapRGBA(s->format, setInRange(r+r_inc, 0, 255), setInRange(g+g_inc, 0, 255), setInRange(b+b_inc, 0, 255), 255);
                                            setPixel(x, y, color, s);
                                        }
                                        
                                        void initPlasma(SDL_Surface *s)
                                        {
                                            int x, y;
                                            Uint32 color = SDL_MapRGBA(s->format, INIT_R, INIT_G, INIT_B, 255);
                                            for (y = 0; y < s->h; ++y)
                                                for (x = 0; x < s->w; ++x)
                                                    setPixel(x, y, color, s);
                                        }
                                        
                                        
                                        void setPlasma(SDL_Surface *s)
                                        {
                                            Sint16 x, y, n;
                                        
                                            static int time = 0;
                                            static shape shapes[NB_SHAPE];
                                            static int first_launch = 1;
                                        
                                            if(first_launch)
                                            {
                                                first_launch = 0;
                                        
                                                for(n = 0; n < NB_SHAPE; n++)
                                                {
                                                    shapes[n].x = rand()%SCR_W;
                                                    shapes[n].y = rand()%SCR_H;
                                                    shapes[n].r = rand()%SHAPE_R;
                                                    shapes[n].r_inc = rand()%SHAPE_COLOR_INC;
                                                    shapes[n].g_inc = rand()%SHAPE_COLOR_INC;
                                                    shapes[n].b_inc = rand()%SHAPE_COLOR_INC;
                                                    shapes[n].x_inc = rand()%(SHAPE_POS_INC*2) - SHAPE_POS_INC;
                                                    shapes[n].y_inc = rand()%(SHAPE_POS_INC*2) - SHAPE_POS_INC;
                                                }
                                            }
                                        
                                            time++;
                                        
                                            for(n = 0; n < NB_SHAPE; n++)
                                            {
                                                shapes[n].x += shapes[n].x_inc;
                                                shapes[n].y += shapes[n].y_inc;
                                        
                                                if(shapes[n].x-shapes[n].r<0 || shapes[n].x>SCR_W || shapes[n].y-shapes[n].r<0 || shapes[n].y>SCR_H)
                                                {
                                                    shapes[n].x = rand()%SCR_W;
                                                    shapes[n].y = rand()%SCR_H;
                                                    shapes[n].r = rand()%SHAPE_R;
                                                    shapes[n].r_inc = rand()%SHAPE_COLOR_INC;
                                                    shapes[n].g_inc = rand()%SHAPE_COLOR_INC;
                                                    shapes[n].b_inc = rand()%SHAPE_COLOR_INC;
                                                    shapes[n].x_inc = rand()%(SHAPE_POS_INC*2) - SHAPE_POS_INC;
                                                    shapes[n].y_inc = rand()%(SHAPE_POS_INC*2) - SHAPE_POS_INC;
                                                }
                                            }
                                        
                                            for(y = 0; y < s->h; ++y)
                                                for(x = 0; x < s->w; ++x)
                                                    for(n = 0; n < NB_SHAPE; n++)
                                                    {
                                                        if(isAtDistance(x, y, shapes[n].x, shapes[n].y, shapes[n].r))
                                                            applyPlasma(s, x, y, shapes[n].r_inc, shapes[n].g_inc, shapes[n].b_inc);
                                                        else
                                                            applyPlasma(s, x, y, DEC_R, DEC_G, DEC_B);
                                                    }
                                        }
                                        
                                        int main (int argc, char* argv[])
                                        {
                                            SDL_bool done = SDL_FALSE;
                                            SDL_Surface *screen = NULL;
                                        
                                            srand(time(NULL));
                                        
                                            if(SDL_Init(SDL_INIT_VIDEO)==-1) exit(EXIT_FAILURE);
                                        
                                            screen = SDL_SetVideoMode(SCR_W, SCR_H, 32, SDL_HWSURFACE | SDL_HWPALETTE);
                                            initPlasma(screen);
                                        
                                            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;
                                                    }
                                                }
                                        
                                                setPlasma(screen);
                                        
                                                SDL_Delay(time_left());
                                        
                                                SDL_Flip(screen);
                                            }
                                        
                                            SDL_Quit();
                                        
                                            return 0;
                                        }
                                        
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          10 août 2010 à 17:23:50

                                          @AstroB:
                                          J'ai des soucis avec ton code même en compilant en c99.

                                          static Uint32 nextTime = SDL_GetTicks();
                                          
                                          o_O
                                          pourquoi un static, du coup ça ne compile pas...

                                          Ensuite à l'exécution, je n'ai rien, écran noir.
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          Zeste de Savoir, le site qui en a dans le citron !
                                            10 août 2010 à 23:51:47

                                            Alors le static, c'est pour l'initialiser à "maintenant" et garder la valeur en mémoire pour la prochaine exécution, comme ça en faisant += TICK_INTERVAL, la comparaison reste bonne... si tu enlève le static, tu va avoir tout le temps nextTime = now => pas de delay... mais cela devrait marcher quand même! En fait, il me semble qu'en une version du C, les static doivent etre initialisés à une valeur constante, ce qui expliquerai que ton compilo gueule, car comme c'est une fonction, c'est non constant... y'a moyenne de contourner, ou alors tu met :

                                            Uint32 time_left()
                                            {
                                                static Uint32 nextTime = 0;
                                                static int first_time = 1;
                                                if(first_time)
                                                {
                                                   nextTime = SDL_GetTicks();
                                                   first_time = 0;
                                                }
                                            
                                                Uint32 now = SDL_GetTicks();
                                                nextTime += TICK_INTERVAL;
                                                return nextTime <= now ? 0 : nextTime - now;
                                            }
                                            


                                            Pour l'écran noir, c'est parce qu'il démarre à noir, puis il s'éclaire par les boules... il faut attendre un peu... (qq cycle) et comem sa rame pas mal, ça peu prendre du temps selon ton ordi... Remplace les INIT_X de 0 à 127 par exemple (sa devrait alors être gris...)
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              11 août 2010 à 4:03:56

                                              D'accord ça fonctionne.

                                              Effectivement en C, les static doivent êtres initialisés avec une constantes.
                                              Je gruge en passant un pointeur.
                                              Uint32 time_left( Uint32 *nxtTime )
                                              {
                                                  Uint32 now = SDL_GetTicks();
                                                  return *nxtTime <= now ? 0 : *nxtTime - now;
                                              }
                                              

                                              On pourrait en faire un globale également.
                                              Je viens de voir un truc
                                              #define TICK_INTERVAL   100
                                              

                                              Tu cherches à avoir 10 frames par secondes, c'est voulu?

                                              Et oui ça rame! Sur mon ordi je dois faire du 2 fps :-°

                                              C'est dommage. Faire les calculs en temps réel c'est très couteux.
                                              Je vais voir à essayer de précalculer.


                                              edit: voila. ;)
                                              Ca rame beaucoup moins. C'est très joli comme effet en tout cas.
                                              Tu m'excusera j'ai recodé à ma sauce pour bien comprendre ce que tu souhaitait faire.
                                              J'ai également modifié pour compiler en C90.

                                              #include <SDL/SDL.h>
                                              #include <time.h>
                                              
                                              #define SCR_W           640
                                              #define SCR_H           480
                                              
                                              #define TICK_INTERVAL   20
                                              
                                              #define NB_SHAPE        50
                                              
                                              #define DEC_R           -1
                                              #define DEC_G           -1
                                              #define DEC_B           -1
                                              
                                              #define SHAPE_R         (SCR_H/6)
                                              
                                              #define SHAPE_COLOR_INC 10
                                              #define SHAPE_POS_INC   3
                                              
                                              #define SQUARE(a)((a) * (a))
                                              #define MAX(a, b)((a) > (b) ? (a) : (b))
                                              #define MIN(a, b)((a) < (b) ? (a) : (b))
                                              #define RANDOM(a) ((a) * rand() / (RAND_MAX + 1.0))
                                              #define SET_IN_RANGE(value, min, max)(MIN( MAX( value, min ), max ))
                                              
                                              /* Shape -------------------------------------------------------------------- */
                                              typedef struct struct_shape {
                                                  unsigned char *data;
                                                  int x, y;
                                                  int r;
                                                  int r_inc, g_inc, b_inc;
                                                  int x_inc, y_inc;
                                              } Shape;
                                              
                                              /* -------------------------------------------------------------------------- */
                                              static int isAtDistance( int x, int y, int x1, int y1, int distance )
                                              {
                                                  return  SQUARE( x - x1 ) + SQUARE( y - y1 ) < SQUARE( distance );
                                              }
                                              
                                              
                                              /* -------------------------------------------------------------------------- */
                                              void Shape_fill( Shape *self )
                                              {
                                                  int x, y;
                                                  int r = self->r;
                                                  int d = r * 2;
                                              
                                                  for( y = 0; y < d; ++y )
                                                      for( x = 0; x < d; ++x )
                                                          self->data[y * d + x] = isAtDistance( x, y, r, r, r ) ;
                                              }
                                              
                                              
                                              
                                              Shape* Shape_new( void )
                                              {
                                                  Shape *p_new = malloc( sizeof * p_new );
                                                  if( p_new == NULL )
                                                  {
                                                      fprintf( stderr, "Error : Shape_new" );
                                                      exit( EXIT_FAILURE );
                                                  }
                                              
                                                  p_new->r = RANDOM( SHAPE_R );
                                                  p_new->data = malloc( 4 * SQUARE( p_new->r ) * sizeof * p_new->data );
                                                  if( p_new == NULL )
                                                  {
                                                      fprintf( stderr, "Error : Shape_new data" );
                                                      exit( EXIT_FAILURE );
                                                  }
                                              
                                                  /* Coordonnées */
                                                  p_new->x = RANDOM( SCR_W );
                                                  p_new->y = RANDOM( SCR_H );
                                              
                                                  /* Incrément pour les composantes RGB */
                                                  p_new->r_inc = RANDOM( SHAPE_COLOR_INC );
                                                  p_new->g_inc = RANDOM( SHAPE_COLOR_INC );
                                                  p_new->b_inc = RANDOM( SHAPE_COLOR_INC );
                                              
                                                  /* Vitesse en x et y */
                                                  do
                                                  {
                                                      p_new->x_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                      p_new->y_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                  } while( !p_new->x_inc && !p_new->y_inc );
                                              
                                                  Shape_fill( p_new );
                                              
                                                  return p_new;
                                              }
                                              
                                              
                                              void Shape_delete( Shape **self )
                                              {
                                                  if( *self )
                                                      free( ( *self )->data ), ( *self )->data = NULL;
                                                  free( *self ), *self = NULL;
                                              }
                                              
                                              
                                              void Shape_update( Shape *self )
                                              {
                                                  self->x += self->x_inc;
                                                  self->y += self->y_inc;
                                              }
                                              
                                              
                                              void Shape_display( Shape *self )
                                              {
                                                  SDL_Surface *s = SDL_GetVideoSurface();
                                                  int x, y;
                                                  int d = self->r * 2;
                                              
                                                  for( y = 0; y < d && self->y + y < s->h; y++ )
                                                  {
                                                      if( self->y + y >= 0 )
                                                      {
                                                          Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + ( self->y + y ) * s->pitch );
                                                          for( x = 0; x < d && self->x + x < s->w; x++ )
                                                          {
                                                              if( x + self->x >= 0 && self->data[y * d + x] )
                                                              {
                                                                  Uint8 r, g, b;
                                                                  SDL_GetRGB( *( offset + x + self->x ), s->format, &r, &g, &b );
                                                                  r = SET_IN_RANGE( r + self->r_inc, 0, 255 );
                                                                  g = SET_IN_RANGE( g + self->g_inc, 0, 255 );
                                                                  b = SET_IN_RANGE( b + self->b_inc, 0, 255 );
                                                                  *( offset + x + self->x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                              }
                                                          }
                                              
                                                      }
                                                  }
                                              }
                                              
                                              
                                              
                                              /* ShapeArray --------------------------------------------------------------- */
                                              Shape** ShapeArray_new( int n )
                                              {
                                                  Shape **p_new = malloc( n * sizeof * p_new );
                                                  int i;
                                                  for( i = 0; i < n; i++ )
                                                      p_new[i] = Shape_new();
                                              
                                                  return p_new;
                                              }
                                              
                                              
                                              void ShapeArray_update( Shape **shps, int n )
                                              {
                                                  int i;
                                                  for( i = 0; i < n; i++ )
                                                  {
                                                      int d = shps[i]->r * 2;
                                                      Shape_update( shps[i] );
                                                      if( shps[i]->x + d < 0
                                                              || shps[i]->x - d >= SCR_W
                                                              || shps[i]->y + d < 0
                                                              || shps[i]->y - d >= SCR_H )
                                                      {
                                                          Shape_delete( &shps[i] );
                                                          shps[i] = Shape_new();
                                                      }
                                                  }
                                              
                                              }
                                              
                                              void ShapeArray_display( Shape **shps, int n )
                                              {
                                                  int i;
                                                  for( i = 0; i < n; i++ )
                                                      Shape_display( shps[i] );
                                              }
                                              
                                              
                                              void ShapeArray_delete( Shape ***shps, int n )
                                              {
                                                  int i;
                                                  for( i = 0; i < n; i++ )
                                                      Shape_delete( &( *shps )[i] );
                                                  free( *shps ), *shps = NULL;
                                              }
                                              
                                              
                                              
                                              Uint32 time_left( Uint32 *nxtTime )
                                              {
                                                  Uint32 now = SDL_GetTicks();
                                                  return *nxtTime <= now ? 0 : *nxtTime - now;
                                              }
                                              
                                              
                                              void smooth( void )
                                              {
                                                  SDL_Surface *s = SDL_GetVideoSurface();
                                              
                                                  int x, y;
                                                  for( y = 0; y < s->h; y++ )
                                                  {
                                                      Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + y * s->pitch ) ;
                                                      for ( x = 0; x < s->w; x++ )
                                                      {
                                                          Uint8 r, g, b;
                                                          SDL_GetRGB( *( offset + x ), s->format, &r, &g, &b );
                                                          r = SET_IN_RANGE( DEC_R + r, 0, 255 );
                                                          g = SET_IN_RANGE( DEC_G + g, 0, 255 );
                                                          b = SET_IN_RANGE( DEC_B + b, 0, 255 );
                                              
                                                          *( offset + x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                      }
                                                  }
                                              }
                                              
                                              int main ( int argc, char* argv[] )
                                              {
                                                  SDL_Surface *screen = NULL;
                                                  Uint32 startTime, nextTime;
                                                  Uint32 currentFrame = 0;
                                                  Shape **shapes;
                                              
                                                  srand( time( NULL ) );
                                              
                                                  if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
                                                      exit( EXIT_FAILURE );
                                              
                                                  screen = SDL_SetVideoMode( SCR_W, SCR_H, 32, SDL_SWSURFACE );
                                                  if( screen == NULL )
                                                      exit( EXIT_FAILURE );
                                              
                                                  shapes = ShapeArray_new( NB_SHAPE );
                                              
                                                  SDL_FillRect( screen, NULL, 0 );
                                              
                                                  startTime = 0;
                                                  nextTime = SDL_GetTicks() + TICK_INTERVAL;
                                                  while( !SDL_QuitRequested() )
                                                  {
                                                      ShapeArray_update( shapes, NB_SHAPE );
                                                      smooth();
                                                      ShapeArray_display( shapes, NB_SHAPE );
                                              
                                                      SDL_Delay( time_left( &nextTime ) );
                                                      SDL_Flip( screen );
                                              
                                                      nextTime += TICK_INTERVAL;
                                                      currentFrame++;
                                              
                                                  }
                                                  printf( "%.2f fps\n", currentFrame * 1000.0 / ( SDL_GetTicks() - startTime ) );
                                              
                                                  ShapeArray_delete( &shapes, NB_SHAPE );
                                              
                                                  SDL_Quit();
                                              
                                                  ( void )argc;
                                                  ( void )argv;
                                              
                                                  return 0;
                                              }
                                              

                                              J'aimerais bien voir plus d'idées comme celle là. ;)
                                              screenshot
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              Zeste de Savoir, le site qui en a dans le citron !
                                                11 août 2010 à 10:56:38

                                                Si déja tu passes le nextTime en paramètre, limite pas besoin d'un pointeur (sauf p-e la temps de recopie de la valeur dans une variable locale?), j'avais fais pour faire tous le calcul du temps dans time_left directement... mais à priori, il faut soit passer en paramètre (comme tu as fait), soit utiliser l'astuce avec "first_time".

                                                Sinon, bravo pour le précalculé, je n'avais jamais expérimenté çà avant... j'ai bien compris l'histoire de l'allocution dynamique, mais elle n'a "rien" à voir avec le pré-calcul, le pré-calcul ne concerne que "data" et le fait de savoir si le cercle est présent à tel position x;y, ou j'ai manqué une étape.

                                                PS:
                                                1/ Pour compiler chez moi, il manque les cast de pointeurs lors des malloc (mais après ça marche)
                                                2/ sizeof(*p_new->data) est équivalent ) sizeof *p_new->data si j'ai bien compris, j'aurais après un 2e truc!

                                                Je remet le code avec les cast (si qq'un a un compilo capricieux comme le mien) et en une version "carrée" limite plus jolie je trouve (après les gouts hein!)... => un look très "micro chip"

                                                Image utilisateur


                                                #include <SDL/SDL.h>
                                                #include <time.h>
                                                
                                                #define SCR_W           640
                                                #define SCR_H           480
                                                
                                                #define TICK_INTERVAL   20
                                                
                                                #define NB_SHAPE        50
                                                
                                                #define DEC_R           -1
                                                #define DEC_G           -1
                                                #define DEC_B           -1
                                                
                                                #define SHAPE_R         (SCR_H/6)
                                                
                                                #define SHAPE_COLOR_INC 3
                                                #define SHAPE_POS_INC   3
                                                
                                                #define SQUARE(a)((a) * (a))
                                                #define MAX(a, b)((a) > (b) ? (a) : (b))
                                                #define MIN(a, b)((a) < (b) ? (a) : (b))
                                                #define RANDOM(a) ((a) * rand() / (RAND_MAX + 1.0))
                                                #define SET_IN_RANGE(value, min, max)(MIN( MAX( value, min ), max ))
                                                
                                                /* Shape -------------------------------------------------------------------- */
                                                typedef struct struct_shape {
                                                    unsigned char *data;
                                                    int x, y;
                                                    int r;
                                                    int r_inc, g_inc, b_inc;
                                                    int x_inc, y_inc;
                                                } Shape;
                                                
                                                /* -------------------------------------------------------------------------- */
                                                static int isAtDistance( int x, int y, int x1, int y1, int distance )
                                                {
                                                    return 1; // SQUARE( x - x1 ) + SQUARE( y - y1 ) < SQUARE( distance );
                                                }
                                                
                                                
                                                /* -------------------------------------------------------------------------- */
                                                void Shape_fill( Shape *self )
                                                {
                                                    int x, y;
                                                    int r = self->r;
                                                    int d = r * 2;
                                                
                                                    for( y = 0; y < d; ++y )
                                                        for( x = 0; x < d; ++x )
                                                            self->data[y * d + x] = isAtDistance( x, y, r, r, r ) ;
                                                }
                                                
                                                
                                                
                                                Shape* Shape_new( void )
                                                {
                                                    Shape *p_new = (Shape*) malloc( sizeof * p_new );
                                                    int vertical;
                                                
                                                    if( p_new == NULL )
                                                    {
                                                        fprintf( stderr, "Error : Shape_new" );
                                                        exit( EXIT_FAILURE );
                                                    }
                                                
                                                    p_new->r = RANDOM( SHAPE_R );
                                                    p_new->data = (unsigned char*) malloc( 4 * SQUARE( p_new->r ) * sizeof * p_new->data );
                                                    if( p_new == NULL )
                                                    {
                                                        fprintf( stderr, "Error : Shape_new data" );
                                                        exit( EXIT_FAILURE );
                                                    }
                                                
                                                    /* Coordonnées */
                                                    p_new->x = RANDOM( SCR_W );
                                                    p_new->y = RANDOM( SCR_H );
                                                
                                                    /* Incrément pour les composantes RGB */
                                                    p_new->r_inc = RANDOM( SHAPE_COLOR_INC );
                                                    p_new->g_inc = RANDOM( SHAPE_COLOR_INC );
                                                    p_new->b_inc = RANDOM( SHAPE_COLOR_INC );
                                                
                                                    /* Vitesse en x et y */
                                                    vertical = RANDOM(2);
                                                    if(vertical)
                                                        do
                                                        {
                                                            p_new->x_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                            p_new->y_inc = 0;
                                                        } while(!p_new->x_inc);
                                                    else
                                                        do
                                                        {
                                                            p_new->x_inc = 0;
                                                            p_new->y_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                        } while(!p_new->y_inc);
                                                
                                                    Shape_fill( p_new );
                                                
                                                    return p_new;
                                                }
                                                
                                                
                                                void Shape_delete( Shape **self )
                                                {
                                                    if( *self )
                                                        free( ( *self )->data ), ( *self )->data = NULL;
                                                    free( *self ), *self = NULL;
                                                }
                                                
                                                
                                                void Shape_update( Shape *self )
                                                {
                                                    self->x += self->x_inc;
                                                    self->y += self->y_inc;
                                                }
                                                
                                                
                                                void Shape_display( Shape *self )
                                                {
                                                    SDL_Surface *s = SDL_GetVideoSurface();
                                                    int x, y;
                                                    int d = self->r * 2;
                                                
                                                    for( y = 0; y < d && self->y + y < s->h; y++ )
                                                    {
                                                        if( self->y + y >= 0 )
                                                        {
                                                            Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + ( self->y + y ) * s->pitch );
                                                            for( x = 0; x < d && self->x + x < s->w; x++ )
                                                            {
                                                                if( x + self->x >= 0 && self->data[y * d + x] )
                                                                {
                                                                    Uint8 r, g, b;
                                                                    SDL_GetRGB( *( offset + x + self->x ), s->format, &r, &g, &b );
                                                                    r = SET_IN_RANGE( r + self->r_inc, 0, 255 );
                                                                    g = SET_IN_RANGE( g + self->g_inc, 0, 255 );
                                                                    b = SET_IN_RANGE( b + self->b_inc, 0, 255 );
                                                                    *( offset + x + self->x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                                }
                                                            }
                                                
                                                        }
                                                    }
                                                }
                                                
                                                
                                                
                                                /* ShapeArray --------------------------------------------------------------- */
                                                Shape** ShapeArray_new( int n )
                                                {
                                                    Shape **p_new = (Shape**) malloc( n * sizeof * p_new );
                                                    int i;
                                                    for( i = 0; i < n; i++ )
                                                        p_new[i] = Shape_new();
                                                
                                                    return p_new;
                                                }
                                                
                                                
                                                void ShapeArray_update( Shape **shps, int n )
                                                {
                                                    int i;
                                                    for( i = 0; i < n; i++ )
                                                    {
                                                        int d = shps[i]->r * 2;
                                                        Shape_update( shps[i] );
                                                        if( shps[i]->x + d < 0
                                                                || shps[i]->x - d >= SCR_W
                                                                || shps[i]->y + d < 0
                                                                || shps[i]->y - d >= SCR_H )
                                                        {
                                                            Shape_delete( &shps[i] );
                                                            shps[i] = Shape_new();
                                                        }
                                                    }
                                                
                                                }
                                                
                                                void ShapeArray_display( Shape **shps, int n )
                                                {
                                                    int i;
                                                    for( i = 0; i < n; i++ )
                                                        Shape_display( shps[i] );
                                                }
                                                
                                                
                                                void ShapeArray_delete( Shape ***shps, int n )
                                                {
                                                    int i;
                                                    for( i = 0; i < n; i++ )
                                                        Shape_delete( &( *shps )[i] );
                                                    free( *shps ), *shps = NULL;
                                                }
                                                
                                                
                                                
                                                Uint32 time_left( Uint32 *nxtTime )
                                                {
                                                    Uint32 now = SDL_GetTicks();
                                                    return *nxtTime <= now ? 0 : *nxtTime - now;
                                                }
                                                
                                                
                                                void smooth( void )
                                                {
                                                    SDL_Surface *s = SDL_GetVideoSurface();
                                                
                                                    int x, y;
                                                    for( y = 0; y < s->h; y++ )
                                                    {
                                                        Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + y * s->pitch ) ;
                                                        for ( x = 0; x < s->w; x++ )
                                                        {
                                                            Uint8 r, g, b;
                                                            SDL_GetRGB( *( offset + x ), s->format, &r, &g, &b );
                                                            r = SET_IN_RANGE( DEC_R + r, 0, 255 );
                                                            g = SET_IN_RANGE( DEC_G + g, 0, 255 );
                                                            b = SET_IN_RANGE( DEC_B + b, 0, 255 );
                                                
                                                            *( offset + x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                        }
                                                    }
                                                }
                                                
                                                int main ( int argc, char* argv[] )
                                                {
                                                    SDL_Surface *screen = NULL;
                                                    Uint32 startTime, nextTime;
                                                    Uint32 currentFrame = 0;
                                                    Shape **shapes;
                                                
                                                    srand( time( NULL ) );
                                                
                                                    if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
                                                        exit( EXIT_FAILURE );
                                                
                                                    screen = SDL_SetVideoMode( SCR_W, SCR_H, 32, SDL_SWSURFACE );
                                                    if( screen == NULL )
                                                        exit( EXIT_FAILURE );
                                                
                                                    shapes = ShapeArray_new( NB_SHAPE );
                                                
                                                    SDL_FillRect( screen, NULL, 0 );
                                                
                                                    startTime = 0;
                                                    nextTime = SDL_GetTicks() + TICK_INTERVAL;
                                                    while( !SDL_QuitRequested() )
                                                    {
                                                        ShapeArray_update( shapes, NB_SHAPE );
                                                        smooth();
                                                        ShapeArray_display( shapes, NB_SHAPE );
                                                
                                                        SDL_Delay( time_left( &nextTime ) );
                                                        SDL_Flip( screen );
                                                
                                                        nextTime += TICK_INTERVAL;
                                                        currentFrame++;
                                                
                                                    }
                                                    printf( "%.2f fps\n", currentFrame * 1000.0 / ( SDL_GetTicks() - startTime ) );
                                                
                                                    ShapeArray_delete( &shapes, NB_SHAPE );
                                                
                                                    SDL_Quit();
                                                
                                                    ( void )argc;
                                                    ( void )argv;
                                                
                                                    return 0;
                                                }
                                                
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  11 août 2010 à 13:48:14

                                                  C'est super avec des carrés!(J'y pensais!)
                                                  :)
                                                  Par contre si tu dois caster malloc, c'est que tu compiles en c++. ;)
                                                  C'est pour ça que j'ai mis self et non this, pour que tu n'ai pas trop de boulot pour compiler.

                                                  Et encore une fois merci pour l'idée.


                                                  Citation : AstroB


                                                  Si déja tu passes le nextTime en paramètre, limite pas besoin d'un pointeur


                                                  C'est toute l'astuce. ;) C'est équivalent au static.
                                                  edit: non, tu as raison le pointeur est inutile.

                                                  Pour l'alloc dynamique effectivement aucun rapport avec le précalculé, c'est juste que je gère mieux comme ça.

                                                  Merci encore pour ton code!

                                                  edit: comme quoi il y a de quoi s'amuser à tout niveau avec ce genre de choses.
                                                  Bon, si ça intéresse qq, on peut faire des trucs visuellement très sympa sans faire tous les hacks des qq codes dessus. :-°
                                                  Il faut essayer.

                                                  @alienore: Si jamais tu as le temps ce serait sympa, et certainement très intéressant. ;)
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  Zeste de Savoir, le site qui en a dans le citron !
                                                    11 août 2010 à 15:23:11

                                                    De rien pour l'idée, ça m'est venu aussi grâce aux idées de chacun...

                                                    Pour l'histoire du pointeur, je demande si c'est n'est pas un poil plus rapide dans le sens où il n'y a pas besoin de recopier la valeur de la variable dans une variable temporaire, mais d'aller pointer directement à l'adresse donnée... je ne sais pas...

                                                    En fait, c'est bien ce qui me semblait, mais le pré-calcul n'est utile que pour les cercles, en carré, il n'y en a pas besoin...
                                                    En fait, même avec les cercles, sans pré-calcule sa passerai aussi, c'est surtout qu'il y avait un "problème" dans mon algo', il était mal optimisé, je bouclais sur tout l'écran pour chaque carré, alors qu'il suffisait, comme tu le fait, de boucler sur la zone de l'écran où le carré est... C'est ce que j'ai fais une ma version corrigée:

                                                    EDIT: Ma version corrigée marche mieux, mais est toujours plus lente que la tienne, mais je ne vois pas pourquoi... si jamais tu trouve, ça m'intéresse! Car j'ai viré le pré-calcul (dans la struct data) dans ta version (car elle ne servais pas dans les carrés) et j'ai corrigé mon algo, donc là cela devrait être globalement équivalent, mais non, c'est toujours plus lent!

                                                    D'où les 2 versions (avec allocation dynamique et sans, i.e. ma version d'origine, corrigée et modifiée):


                                                    #include <SDL/SDL.h>
                                                    #include <time.h>
                                                    
                                                    #define SCR_W           640
                                                    #define SCR_H           480
                                                    
                                                    #define TICK_INTERVAL   40
                                                    
                                                    #define NB_SHAPE        50
                                                    
                                                    #define DEC_R           -1
                                                    #define DEC_G           -1
                                                    #define DEC_B           -1
                                                    
                                                    #define SHAPE_R         (SCR_H/6)
                                                    
                                                    #define SHAPE_COLOR_INC 3
                                                    #define SHAPE_POS_INC   3
                                                    
                                                    #define SQUARE(a)((a) * (a))
                                                    #define MAX(a, b)((a) > (b) ? (a) : (b))
                                                    #define MIN(a, b)((a) < (b) ? (a) : (b))
                                                    #define RANDOM(a) ((a) * rand() / (RAND_MAX + 1.0))
                                                    #define SET_IN_RANGE(value, min, max)(MIN( MAX( value, min ), max ))
                                                    
                                                    /* Shape -------------------------------------------------------------------- */
                                                    typedef struct struct_shape {
                                                        int x, y;
                                                        int r;
                                                        int r_inc, g_inc, b_inc;
                                                        int x_inc, y_inc;
                                                    } Shape;
                                                    
                                                    
                                                    Shape* Shape_new( void )
                                                    {
                                                        Shape *p_new = (Shape*) malloc( sizeof * p_new );
                                                        int vertical;
                                                    
                                                        if( p_new == NULL )
                                                        {
                                                            fprintf( stderr, "Error : Shape_new" );
                                                            exit( EXIT_FAILURE );
                                                        }
                                                    
                                                        p_new->r = RANDOM( SHAPE_R );
                                                        if( p_new == NULL )
                                                        {
                                                            fprintf( stderr, "Error : Shape_new data" );
                                                            exit( EXIT_FAILURE );
                                                        }
                                                    
                                                        /* Coordonnées */
                                                        p_new->x = RANDOM( SCR_W );
                                                        p_new->y = RANDOM( SCR_H );
                                                    
                                                        /* Incrément pour les composantes RGB */
                                                        p_new->r_inc = RANDOM( SHAPE_COLOR_INC );
                                                        p_new->g_inc = RANDOM( SHAPE_COLOR_INC );
                                                        p_new->b_inc = RANDOM( SHAPE_COLOR_INC );
                                                    
                                                        /* Vitesse en x et y */
                                                        vertical = RANDOM(2);
                                                        if(vertical)
                                                            do
                                                            {
                                                                p_new->x_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                                p_new->y_inc = 0;
                                                            } while(!p_new->x_inc);
                                                        else
                                                            do
                                                            {
                                                                p_new->x_inc = 0;
                                                                p_new->y_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                            } while(!p_new->y_inc);
                                                    
                                                        return p_new;
                                                    }
                                                    
                                                    
                                                    void Shape_delete( Shape **self )
                                                    {
                                                        free( *self ), *self = NULL;
                                                    }
                                                    
                                                    
                                                    void Shape_update( Shape *self )
                                                    {
                                                        self->x += self->x_inc;
                                                        self->y += self->y_inc;
                                                    }
                                                    
                                                    
                                                    void Shape_display( Shape *self )
                                                    {
                                                        SDL_Surface *s = SDL_GetVideoSurface();
                                                        int x, y;
                                                        int d = self->r * 2;
                                                    
                                                        for( y = 0; y < d && self->y + y < s->h; y++ )
                                                        {
                                                            if( self->y + y >= 0 )
                                                            {
                                                                Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + ( self->y + y ) * s->pitch );
                                                                for( x = 0; x < d && self->x + x < s->w; x++ )
                                                                {
                                                                    if( x + self->x >= 0)
                                                                    {
                                                                        Uint8 r, g, b;
                                                                        SDL_GetRGB( *( offset + x + self->x ), s->format, &r, &g, &b );
                                                                        r = SET_IN_RANGE( r + self->r_inc, 0, 255 );
                                                                        g = SET_IN_RANGE( g + self->g_inc, 0, 255 );
                                                                        b = SET_IN_RANGE( b + self->b_inc, 0, 255 );
                                                                        *( offset + x + self->x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                                    }
                                                                }
                                                    
                                                            }
                                                        }
                                                    }
                                                    
                                                    
                                                    
                                                    /* ShapeArray --------------------------------------------------------------- */
                                                    Shape** ShapeArray_new( int n )
                                                    {
                                                        Shape **p_new = (Shape**) malloc( n * sizeof * p_new );
                                                        int i;
                                                        for( i = 0; i < n; i++ )
                                                            p_new[i] = Shape_new();
                                                    
                                                        return p_new;
                                                    }
                                                    
                                                    
                                                    void ShapeArray_update( Shape **shps, int n )
                                                    {
                                                        int i;
                                                        for( i = 0; i < n; i++ )
                                                        {
                                                            int d = shps[i]->r * 2;
                                                            Shape_update( shps[i] );
                                                            if( shps[i]->x + d < 0
                                                                    || shps[i]->x - d >= SCR_W
                                                                    || shps[i]->y + d < 0
                                                                    || shps[i]->y - d >= SCR_H )
                                                            {
                                                                Shape_delete( &shps[i] );
                                                                shps[i] = Shape_new();
                                                            }
                                                        }
                                                    
                                                    }
                                                    
                                                    void ShapeArray_display( Shape **shps, int n )
                                                    {
                                                        int i;
                                                        for( i = 0; i < n; i++ )
                                                            Shape_display( shps[i] );
                                                    }
                                                    
                                                    
                                                    void ShapeArray_delete( Shape ***shps, int n )
                                                    {
                                                        int i;
                                                        for( i = 0; i < n; i++ )
                                                            Shape_delete( &( *shps )[i] );
                                                        free( *shps ), *shps = NULL;
                                                    }
                                                    
                                                    
                                                    
                                                    Uint32 time_left( Uint32 *nxtTime )
                                                    {
                                                        Uint32 now = SDL_GetTicks();
                                                        return *nxtTime <= now ? 0 : *nxtTime - now;
                                                    }
                                                    
                                                    
                                                    void smooth( void )
                                                    {
                                                        SDL_Surface *s = SDL_GetVideoSurface();
                                                    
                                                        int x, y;
                                                        for( y = 0; y < s->h; y++ )
                                                        {
                                                            Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + y * s->pitch ) ;
                                                            for ( x = 0; x < s->w; x++ )
                                                            {
                                                                Uint8 r, g, b;
                                                                SDL_GetRGB( *( offset + x ), s->format, &r, &g, &b );
                                                                r = SET_IN_RANGE( DEC_R + r, 0, 255 );
                                                                g = SET_IN_RANGE( DEC_G + g, 0, 255 );
                                                                b = SET_IN_RANGE( DEC_B + b, 0, 255 );
                                                    
                                                                *( offset + x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                            }
                                                        }
                                                    }
                                                    
                                                    int main ( int argc, char* argv[] )
                                                    {
                                                        SDL_Surface *screen = NULL;
                                                        Uint32 startTime, nextTime;
                                                        Uint32 currentFrame = 0;
                                                        Shape **shapes;
                                                    
                                                        srand( time( NULL ) );
                                                    
                                                        if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
                                                            exit( EXIT_FAILURE );
                                                    
                                                        screen = SDL_SetVideoMode( SCR_W, SCR_H, 32, SDL_SWSURFACE );
                                                        if( screen == NULL )
                                                            exit( EXIT_FAILURE );
                                                    
                                                        shapes = ShapeArray_new( NB_SHAPE );
                                                    
                                                        SDL_FillRect( screen, NULL, 0 );
                                                    
                                                        startTime = 0;
                                                        nextTime = SDL_GetTicks() + TICK_INTERVAL;
                                                        while( !SDL_QuitRequested() )
                                                        {
                                                            ShapeArray_update( shapes, NB_SHAPE );
                                                            smooth();
                                                            ShapeArray_display( shapes, NB_SHAPE );
                                                    
                                                            SDL_Delay( time_left( &nextTime ) );
                                                            SDL_Flip( screen );
                                                    
                                                            nextTime += TICK_INTERVAL;
                                                            currentFrame++;
                                                    
                                                        }
                                                        printf( "%.2f fps\n", currentFrame * 1000.0 / ( SDL_GetTicks() - startTime ) );
                                                    
                                                        ShapeArray_delete( &shapes, NB_SHAPE );
                                                    
                                                        SDL_Quit();
                                                    
                                                        ( void )argc;
                                                        ( void )argv;
                                                    
                                                        return 0;
                                                    }
                                                    




                                                    #include <SDL/SDL.h>
                                                    
                                                    #include <math.h>
                                                    #include <time.h>
                                                    #include <float.h>
                                                    
                                                    #define SCR_W           640
                                                    #define SCR_H           480
                                                    
                                                    #define TICK_INTERVAL   40
                                                    
                                                    #define NB_SHAPE        50
                                                    
                                                    #define INIT_R          0
                                                    #define INIT_G          0
                                                    #define INIT_B          0
                                                    
                                                    #define DEC_R           -1
                                                    #define DEC_G           -1
                                                    #define DEC_B           -1
                                                    
                                                    #define SHAPE_R         SCR_H/6
                                                    #define SHAPE_COLOR_INC 3
                                                    #define SHAPE_POS_INC   3
                                                    
                                                    
                                                    typedef struct struct_shape{
                                                        int x;
                                                        int y;
                                                        int r;
                                                        int r_inc;
                                                        int g_inc;
                                                        int b_inc;
                                                        int x_inc;
                                                        int y_inc;
                                                    } shape;
                                                    
                                                    Uint32 time_left()
                                                    {
                                                        static Uint32 nextTime = SDL_GetTicks();
                                                        Uint32 now = SDL_GetTicks();
                                                        nextTime += TICK_INTERVAL;
                                                        return nextTime <= now ? 0 : nextTime - now;
                                                    }
                                                    
                                                    int setInRange(int value, int min, int max)
                                                    {
                                                        return fmin(fmax(value, min), max);
                                                    }
                                                    
                                                    int isAtDistance(int x, int y, int x1, int y1, int distance)
                                                    {
                                                        return (pow(x-x1, 2)+pow(y-y1, 2) < pow(distance, 2));
                                                    }
                                                    
                                                    void setPixel(int x, int y, Uint32 color, SDL_Surface *map)
                                                    {
                                                      if(x>0 && y>0 && x<map->w && y<map->h)
                                                        *((Uint32*)(map->pixels) + x + y * map->w) = color;
                                                    }
                                                    
                                                    void getPixelColor(int x, int y, SDL_Surface *map, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
                                                    {
                                                      if(x>0 && y>0 && x<map->w && y<map->h)
                                                        SDL_GetRGBA(*((Uint32 *)map->pixels + x + y * map->w),map->format,r,g,b,a);
                                                    }
                                                    
                                                    void applyPlasma(SDL_Surface *s, Sint16 x, Sint16 y, int r_inc, int g_inc, int b_inc)
                                                    {
                                                        Uint8 r, g, b, a;
                                                        getPixelColor(x, y, s, &r, &g, &b, &a);
                                                        Uint32 color = SDL_MapRGBA(s->format, setInRange(r+r_inc, 0, 255), setInRange(g+g_inc, 0, 255), setInRange(b+b_inc, 0, 255), 255);
                                                        setPixel(x, y, color, s);
                                                    }
                                                    
                                                    void initPlasma(SDL_Surface *s)
                                                    {
                                                        int x, y;
                                                        Uint32 color = SDL_MapRGBA(s->format, INIT_R, INIT_G, INIT_B, 255);
                                                        for (y = 0; y < s->h; ++y)
                                                            for (x = 0; x < s->w; ++x)
                                                                setPixel(x, y, color, s);
                                                    }
                                                    
                                                    
                                                    void setPlasma(SDL_Surface *s)
                                                    {
                                                        Sint16 x, y, n;
                                                    
                                                        static shape shapes[NB_SHAPE];
                                                        static int first_launch = 1;
                                                        int vertical;
                                                    
                                                        if(first_launch)
                                                        {
                                                            first_launch = 0;
                                                    
                                                            for(n = 0; n < NB_SHAPE; n++)
                                                            {
                                                                shapes[n].x = rand()%SCR_W;
                                                                shapes[n].y = rand()%SCR_H;
                                                                shapes[n].r = rand()%SHAPE_R;
                                                                shapes[n].r_inc = rand()%SHAPE_COLOR_INC;
                                                                shapes[n].g_inc = rand()%SHAPE_COLOR_INC;
                                                                shapes[n].b_inc = rand()%SHAPE_COLOR_INC;
                                                                vertical = rand()%2;
                                                                if(vertical)
                                                                    do
                                                                    {
                                                                        shapes[n].x_inc = rand()%(SHAPE_POS_INC*2) - SHAPE_POS_INC;
                                                                        shapes[n].y_inc = 0;
                                                                    } while(!shapes[n].x_inc);
                                                                else
                                                                    do
                                                                    {
                                                                        shapes[n].x_inc = 0;
                                                                        shapes[n].y_inc = rand()%(SHAPE_POS_INC*2) - SHAPE_POS_INC;
                                                                    } while(!shapes[n].y_inc);
                                                            }
                                                        }
                                                    
                                                        for(n = 0; n < NB_SHAPE; n++)
                                                        {
                                                            shapes[n].x += shapes[n].x_inc;
                                                            shapes[n].y += shapes[n].y_inc;
                                                    
                                                            if(shapes[n].x-shapes[n].r<0 || shapes[n].x>SCR_W || shapes[n].y-shapes[n].r<0 || shapes[n].y>SCR_H)
                                                            {
                                                                shapes[n].x = rand()%SCR_W;
                                                                shapes[n].y = rand()%SCR_H;
                                                                shapes[n].r = rand()%SHAPE_R;
                                                                shapes[n].r_inc = rand()%SHAPE_COLOR_INC;
                                                                shapes[n].g_inc = rand()%SHAPE_COLOR_INC;
                                                                shapes[n].b_inc = rand()%SHAPE_COLOR_INC;
                                                                vertical = rand()%2;
                                                                if(vertical)
                                                                    do
                                                                    {
                                                                        shapes[n].x_inc = rand()%(SHAPE_POS_INC*2) - SHAPE_POS_INC;
                                                                        shapes[n].y_inc = 0;
                                                                    } while(!shapes[n].x_inc);
                                                                else
                                                                    do
                                                                    {
                                                                        shapes[n].x_inc = 0;
                                                                        shapes[n].y_inc = rand()%(SHAPE_POS_INC*2) - SHAPE_POS_INC;
                                                                    } while(!shapes[n].y_inc);
                                                            }
                                                        }
                                                    
                                                        for(n = 0; n < NB_SHAPE; n++)
                                                            for(y = shapes[n].y; y < shapes[n].y + shapes[n].r*2; y++)
                                                                if(y<s->h)
                                                                    for( x = shapes[n].x; x < shapes[n].x + shapes[n].r*2; x++)
                                                                        if(x<s->w)
                                                                            applyPlasma(s, x, y, shapes[n].r_inc, shapes[n].g_inc, shapes[n].b_inc);
                                                    
                                                    
                                                        for(y = 0; y < s->h; ++y)
                                                            for(x = 0; x < s->w; ++x)
                                                                applyPlasma(s, x, y, DEC_R, DEC_G, DEC_B);
                                                    }
                                                    
                                                    int main (int argc, char* argv[])
                                                    {
                                                        SDL_bool done = SDL_FALSE;
                                                        SDL_Surface *screen = NULL;
                                                    
                                                        srand(time(NULL));
                                                    
                                                        if(SDL_Init(SDL_INIT_VIDEO)==-1) exit(EXIT_FAILURE);
                                                    
                                                        screen = SDL_SetVideoMode(SCR_W, SCR_H, 32, SDL_HWSURFACE | SDL_HWPALETTE);
                                                        initPlasma(screen);
                                                    
                                                        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;
                                                                }
                                                            }
                                                    
                                                            setPlasma(screen);
                                                    
                                                            SDL_Delay(time_left());
                                                    
                                                            SDL_Flip(screen);
                                                        }
                                                    
                                                        SDL_Quit();
                                                    
                                                        return 0;
                                                    }
                                                    



                                                    EDIT:
                                                    En bonus, une fonction pour faire un flou (gaussien? pas vraiment car la distribution est linéaire...), fonction à lancer dans la boucle du main après avoir fait ShapeArray_display()

                                                    Attention, ça fait chauffer le CPU!

                                                    void blur(void)
                                                    {
                                                        SDL_Surface *s = SDL_GetVideoSurface();
                                                        SDL_Surface *s_backup = SDL_CreateRGBSurface(SDL_HWSURFACE, s->w, s->h, 32, 0, 0, 0, 0); ;
                                                        SDL_Rect position;
                                                        int x, y, i, j;
                                                        position.x = 0;
                                                        position.y = 0;
                                                    
                                                        SDL_BlitSurface(s, NULL, s_backup, &position);
                                                    
                                                        for( y = BLUR_WIDTH; y < s->h-BLUR_WIDTH; y++ )
                                                        {
                                                            Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + y * s->pitch ) ;
                                                            for ( x = BLUR_WIDTH; x < s->w-BLUR_WIDTH; x++ )
                                                            {
                                                                Uint32 r, g, b;
                                                                Uint8 r_temp, g_temp, b_temp;
                                                                r = 0;
                                                                g = 0;
                                                                b = 0;
                                                                for(i = -BLUR_WIDTH; i <= BLUR_WIDTH; i++)
                                                                    for(j = -BLUR_WIDTH; j <= BLUR_WIDTH; j++)
                                                                    {
                                                                        getPixelColor(x + i, y + j, s_backup, &r_temp, &g_temp, &b_temp);
                                                                        r += r_temp;
                                                                        g += g_temp;
                                                                        b += b_temp;
                                                                    }
                                                    
                                                                r /= SQUARE(BLUR_WIDTH*2+1);
                                                                g /= SQUARE(BLUR_WIDTH*2+1);
                                                                b /= SQUARE(BLUR_WIDTH*2+1);
                                                                *( offset + x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                            }
                                                        }
                                                    }
                                                    
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      11 août 2010 à 17:42:12

                                                      En jetant un oeil rapidement, je dirais que c'est juste le nombre d'appel de fonction qui diffère lors de l'affichage.

                                                      Pour chaque pixel tu appelel les fonctions getPixelColor et setPixel, alors que j'ai tout mis en dur dans la double boucle.
                                                      Dans le même genre je ne calcule l'adresse du début de la ligne qu'à chaque ligne, tandis que tu le calcules plusieurs fois(2), pour chaque pixel.

                                                      Tu retrouves ces problèmes lorsque tu atténues chaque pixel également.

                                                      L'écart est ici, je pense.

                                                      Une autre solution pour atténuer, serait de créer une surface noire avec un alpha de 1 et de blitter cette surface sur l'écran. ;)
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                      Zeste de Savoir, le site qui en a dans le citron !
                                                        11 août 2010 à 17:51:43

                                                        Le blittage avec alpha 1 j'y avais pensé aussi, c'est p-e plus efficace (car fait à partir d'une fonction codé dans la SDL...)

                                                        Effectivement ,cela doit être le nombre d'appel...

                                                        T'a testé le blur (qui rame), pour le coup, sa commence vraiment à ressembler à du plasma (avec un blur width plus important, ça le fait vraiment!) Avec les cercles, plutôt qu'avec les carrés, cela doit être encore mieux!
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          11 août 2010 à 17:57:23

                                                          Scuse, qu'appelle tu le blur?

                                                          Sinon j'ai testé, les 2 versions, et en modifiant les tailles max des carrés ou cercles, la vitesse de décrémént de chaque composante, oui on obtient quelque chose qui ressemble à un plasma.

                                                          En fait, un plasma, ce serait plutôt l'addition de plusieurs surfaces occupant tout l'écrna.

                                                          j'avais zappé.

                                                          Citation : AstroB


                                                          2/ sizeof(*p_new->data) est équivalent ) sizeof *p_new->data si j'ai bien compris, j'aurais après un 2e truc!


                                                          Ce serait plutôt équivalent à *(p_new->data)...
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Zeste de Savoir, le site qui en a dans le citron !
                                                            11 août 2010 à 18:53:33

                                                            Le blur c'est la fonction blur (flou) que j'ai ajoutée en haut (dans l'édit) voila un code complet:


                                                            #include <SDL/SDL.h>
                                                            #include <time.h>
                                                            
                                                            #define SCR_W           640
                                                            #define SCR_H           480
                                                            
                                                            #define TICK_INTERVAL   40
                                                            
                                                            #define NB_SHAPE        50
                                                            
                                                            #define DEC_R           -1
                                                            #define DEC_G           -1
                                                            #define DEC_B           -1
                                                            
                                                            #define SHAPE_R         (SCR_H/6)
                                                            
                                                            #define SHAPE_COLOR_INC 3
                                                            #define SHAPE_POS_INC   3
                                                            
                                                            #define BLUR_WIDTH      1
                                                            
                                                            #define SQUARE(a)((a) * (a))
                                                            #define MAX(a, b)((a) > (b) ? (a) : (b))
                                                            #define MIN(a, b)((a) < (b) ? (a) : (b))
                                                            #define RANDOM(a) ((a) * rand() / (RAND_MAX + 1.0))
                                                            #define SET_IN_RANGE(value, min, max)(MIN( MAX( value, min ), max ))
                                                            
                                                            /* Shape -------------------------------------------------------------------- */
                                                            typedef struct struct_shape {
                                                                int x, y;
                                                                int r;
                                                                int r_inc, g_inc, b_inc;
                                                                int x_inc, y_inc;
                                                            } Shape;
                                                            
                                                            
                                                            Shape* Shape_new( void )
                                                            {
                                                                Shape *p_new = (Shape*) malloc( sizeof * p_new );
                                                                int vertical;
                                                            
                                                                if( p_new == NULL )
                                                                {
                                                                    fprintf( stderr, "Error : Shape_new" );
                                                                    exit( EXIT_FAILURE );
                                                                }
                                                            
                                                                p_new->r = RANDOM( SHAPE_R );
                                                                if( p_new == NULL )
                                                                {
                                                                    fprintf( stderr, "Error : Shape_new data" );
                                                                    exit( EXIT_FAILURE );
                                                                }
                                                            
                                                                /* Coordonnées */
                                                                p_new->x = RANDOM( SCR_W );
                                                                p_new->y = RANDOM( SCR_H );
                                                            
                                                                /* Incrément pour les composantes RGB */
                                                                p_new->r_inc = RANDOM( SHAPE_COLOR_INC );
                                                                p_new->g_inc = RANDOM( SHAPE_COLOR_INC );
                                                                p_new->b_inc = RANDOM( SHAPE_COLOR_INC );
                                                            
                                                                /* Vitesse en x et y */
                                                                vertical = RANDOM(2);
                                                                if(vertical)
                                                                    do
                                                                    {
                                                                        p_new->x_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                                        p_new->y_inc = 0;
                                                                    } while(!p_new->x_inc);
                                                                else
                                                                    do
                                                                    {
                                                                        p_new->x_inc = 0;
                                                                        p_new->y_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                                    } while(!p_new->y_inc);
                                                            
                                                                return p_new;
                                                            }
                                                            
                                                            
                                                            void Shape_delete( Shape **self )
                                                            {
                                                                free( *self ), *self = NULL;
                                                            }
                                                            
                                                            
                                                            void Shape_update( Shape *self )
                                                            {
                                                                self->x += self->x_inc;
                                                                self->y += self->y_inc;
                                                            }
                                                            
                                                            
                                                            void Shape_display( Shape *self )
                                                            {
                                                                SDL_Surface *s = SDL_GetVideoSurface();
                                                                int x, y;
                                                                int d = self->r * 2;
                                                            
                                                                for( y = 0; y < d && self->y + y < s->h; y++ )
                                                                {
                                                                    if( self->y + y >= 0 )
                                                                    {
                                                                        Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + ( self->y + y ) * s->pitch );
                                                                        for( x = 0; x < d && self->x + x < s->w; x++ )
                                                                        {
                                                                            if( x + self->x >= 0)
                                                                            {
                                                                                Uint8 r, g, b;
                                                                                SDL_GetRGB( *( offset + x + self->x ), s->format, &r, &g, &b );
                                                                                r = SET_IN_RANGE( r + self->r_inc, 0, 255 );
                                                                                g = SET_IN_RANGE( g + self->g_inc, 0, 255 );
                                                                                b = SET_IN_RANGE( b + self->b_inc, 0, 255 );
                                                                                *( offset + x + self->x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                                            }
                                                                        }
                                                            
                                                                    }
                                                                }
                                                            }
                                                            
                                                            
                                                            
                                                            /* ShapeArray --------------------------------------------------------------- */
                                                            Shape** ShapeArray_new( int n )
                                                            {
                                                                Shape **p_new = (Shape**) malloc( n * sizeof * p_new );
                                                                int i;
                                                                for( i = 0; i < n; i++ )
                                                                    p_new[i] = Shape_new();
                                                            
                                                                return p_new;
                                                            }
                                                            
                                                            
                                                            void ShapeArray_update( Shape **shps, int n )
                                                            {
                                                                int i;
                                                                for( i = 0; i < n; i++ )
                                                                {
                                                                    int d = shps[i]->r * 2;
                                                                    Shape_update( shps[i] );
                                                                    if( shps[i]->x + d < 0
                                                                            || shps[i]->x - d >= SCR_W
                                                                            || shps[i]->y + d < 0
                                                                            || shps[i]->y - d >= SCR_H )
                                                                    {
                                                                        Shape_delete( &shps[i] );
                                                                        shps[i] = Shape_new();
                                                                    }
                                                                }
                                                            
                                                            }
                                                            
                                                            void ShapeArray_display( Shape **shps, int n )
                                                            {
                                                                int i;
                                                                for( i = 0; i < n; i++ )
                                                                    Shape_display( shps[i] );
                                                            }
                                                            
                                                            
                                                            void ShapeArray_delete( Shape ***shps, int n )
                                                            {
                                                                int i;
                                                                for( i = 0; i < n; i++ )
                                                                    Shape_delete( &( *shps )[i] );
                                                                free( *shps ), *shps = NULL;
                                                            }
                                                            
                                                            
                                                            
                                                            Uint32 time_left( Uint32 *nxtTime )
                                                            {
                                                                Uint32 now = SDL_GetTicks();
                                                                return *nxtTime <= now ? 0 : *nxtTime - now;
                                                            }
                                                            
                                                            void getPixelColor(int x, int y, SDL_Surface *map, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
                                                            {
                                                              if(x>0 && y>0 && x<map->w && y<map->h)
                                                                SDL_GetRGBA(*((Uint32 *)map->pixels + x + y * map->w),map->format,r,g,b,a);
                                                            }
                                                            
                                                            
                                                            void smooth( void )
                                                            {
                                                                SDL_Surface *s = SDL_GetVideoSurface();
                                                            
                                                                int x, y;
                                                                for( y = 0; y < s->h; y++ )
                                                                {
                                                                    Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + y * s->pitch ) ;
                                                                    for ( x = 0; x < s->w; x++ )
                                                                    {
                                                                        Uint8 r, g, b;
                                                                        SDL_GetRGB( *( offset + x ), s->format, &r, &g, &b );
                                                                        r = SET_IN_RANGE( DEC_R + r, 0, 255 );
                                                                        g = SET_IN_RANGE( DEC_G + g, 0, 255 );
                                                                        b = SET_IN_RANGE( DEC_B + b, 0, 255 );
                                                            
                                                                        *( offset + x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                                    }
                                                                }
                                                            }
                                                            
                                                            void blur(void)
                                                            {
                                                                SDL_Surface *s = SDL_GetVideoSurface();
                                                                SDL_Surface *s_backup = SDL_CreateRGBSurface(SDL_HWSURFACE, s->w, s->h, 32, 0, 0, 0, 0); ;
                                                                SDL_Rect position;
                                                                int x, y, i, j;
                                                                position.x = 0;
                                                                position.y = 0;
                                                            
                                                                SDL_BlitSurface(s, NULL, s_backup, &position);
                                                            
                                                                for( y = BLUR_WIDTH; y < s->h-BLUR_WIDTH; y++ )
                                                                {
                                                                    Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + y * s->pitch ) ;
                                                                    for ( x = BLUR_WIDTH; x < s->w-BLUR_WIDTH; x++ )
                                                                    {
                                                                        Uint32 r, g, b;
                                                                        Uint8 r_temp, g_temp, b_temp;
                                                                        r = 0;
                                                                        g = 0;
                                                                        b = 0;
                                                                        for(i = -BLUR_WIDTH; i <= BLUR_WIDTH; i++)
                                                                            for(j = -BLUR_WIDTH; j <= BLUR_WIDTH; j++)
                                                                            {
                                                                                getPixelColor(x + i, y + j, s_backup, &r_temp, &g_temp, &b_temp);
                                                                                r += r_temp;
                                                                                g += g_temp;
                                                                                b += b_temp;
                                                                            }
                                                            
                                                                        r /= SQUARE(BLUR_WIDTH*2+1);
                                                                        g /= SQUARE(BLUR_WIDTH*2+1);
                                                                        b /= SQUARE(BLUR_WIDTH*2+1);
                                                                        *( offset + x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                                    }
                                                                }
                                                            }
                                                            
                                                            
                                                            int main ( int argc, char* argv[] )
                                                            {
                                                                SDL_Surface *screen = NULL;
                                                                Uint32 startTime, nextTime;
                                                                Uint32 currentFrame = 0;
                                                                Shape **shapes;
                                                            
                                                                srand( time( NULL ) );
                                                            
                                                                if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
                                                                    exit( EXIT_FAILURE );
                                                            
                                                                screen = SDL_SetVideoMode( SCR_W, SCR_H, 32, SDL_SWSURFACE );
                                                                if( screen == NULL )
                                                                    exit( EXIT_FAILURE );
                                                            
                                                                shapes = ShapeArray_new( NB_SHAPE );
                                                            
                                                                SDL_FillRect( screen, NULL, 0 );
                                                            
                                                                startTime = 0;
                                                                nextTime = SDL_GetTicks() + TICK_INTERVAL;
                                                                while( !SDL_QuitRequested() )
                                                                {
                                                                    ShapeArray_update( shapes, NB_SHAPE );
                                                                    smooth();
                                                                    ShapeArray_display( shapes, NB_SHAPE );
                                                                    blur();
                                                            
                                                                    SDL_Delay( time_left( &nextTime ) );
                                                                    SDL_Flip( screen );
                                                            
                                                                    nextTime += TICK_INTERVAL;
                                                                    currentFrame++;
                                                            
                                                                }
                                                                printf( "%.2f fps\n", currentFrame * 1000.0 / ( SDL_GetTicks() - startTime ) );
                                                            
                                                                ShapeArray_delete( &shapes, NB_SHAPE );
                                                            
                                                                SDL_Quit();
                                                            
                                                                ( void )argc;
                                                                ( void )argv;
                                                            
                                                                return 0;
                                                            }
                                                            



                                                            Je m'attaque à ça demain, mais cette histoire de décrément/incrémente était une "mauvaise idée"...
                                                            1/ Il ne faut plus faire de décrément (comme sa, sa va plus vite)
                                                            2/ Il faut juste blitter des cercles qui avancent et plus aucun incrément de la couleur de fond => dc sans trainée, juste des cercles pleine couleur, comme sa c'est ultra rapide à blitter
                                                            3/ Et l'ingrédient magique: faire un gros flou, i.e. mettre BLUR_WIDTH à une grosse valeur...
                                                            ... et là, cela devrait vraiment ressembler à un plasma (car le flou "ressemble" à l'équation de diffusion de la chaleur)
                                                            Si tu veux valider ce principe, tu peux déja tester avec le code ci-dessus en mettant un gros flou et un gros incrément de couleur, mais sa risque de ramer, à cause du décrément et des formes qui incrémentent la couleur...). Je te met le code (je suis pas chez moi, dc non testé, mais sa devrait marcher):


                                                            #include <SDL/SDL.h>
                                                            #include <time.h>
                                                            
                                                            #define SCR_W           640
                                                            #define SCR_H           480
                                                            
                                                            #define TICK_INTERVAL   40
                                                            
                                                            #define NB_SHAPE        50
                                                            
                                                            #define DEC_R           0
                                                            #define DEC_G           0
                                                            #define DEC_B           0
                                                            
                                                            #define SHAPE_R         (SCR_H/6)
                                                            
                                                            #define SHAPE_COLOR_INC 225
                                                            #define SHAPE_POS_INC   3
                                                            
                                                            #define BLUR_WIDTH      20
                                                            
                                                            #define SQUARE(a)((a) * (a))
                                                            #define MAX(a, b)((a) > (b) ? (a) : (b))
                                                            #define MIN(a, b)((a) < (b) ? (a) : (b))
                                                            #define RANDOM(a) ((a) * rand() / (RAND_MAX + 1.0))
                                                            #define SET_IN_RANGE(value, min, max)(MIN( MAX( value, min ), max ))
                                                            
                                                            /* Shape -------------------------------------------------------------------- */
                                                            typedef struct struct_shape {
                                                                int x, y;
                                                                int r;
                                                                int r_inc, g_inc, b_inc;
                                                                int x_inc, y_inc;
                                                            } Shape;
                                                            
                                                            
                                                            Shape* Shape_new( void )
                                                            {
                                                                Shape *p_new = (Shape*) malloc( sizeof * p_new );
                                                                int vertical;
                                                            
                                                                if( p_new == NULL )
                                                                {
                                                                    fprintf( stderr, "Error : Shape_new" );
                                                                    exit( EXIT_FAILURE );
                                                                }
                                                            
                                                                p_new->r = RANDOM( SHAPE_R );
                                                                if( p_new == NULL )
                                                                {
                                                                    fprintf( stderr, "Error : Shape_new data" );
                                                                    exit( EXIT_FAILURE );
                                                                }
                                                            
                                                                /* Coordonnées */
                                                                p_new->x = RANDOM( SCR_W );
                                                                p_new->y = RANDOM( SCR_H );
                                                            
                                                                /* Incrément pour les composantes RGB */
                                                                p_new->r_inc = RANDOM( SHAPE_COLOR_INC );
                                                                p_new->g_inc = RANDOM( SHAPE_COLOR_INC );
                                                                p_new->b_inc = RANDOM( SHAPE_COLOR_INC );
                                                            
                                                                /* Vitesse en x et y */
                                                                vertical = RANDOM(2);
                                                                if(vertical)
                                                                    do
                                                                    {
                                                                        p_new->x_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                                        p_new->y_inc = 0;
                                                                    } while(!p_new->x_inc);
                                                                else
                                                                    do
                                                                    {
                                                                        p_new->x_inc = 0;
                                                                        p_new->y_inc = RANDOM( SHAPE_POS_INC * 2 ) - SHAPE_POS_INC;
                                                                    } while(!p_new->y_inc);
                                                            
                                                                return p_new;
                                                            }
                                                            
                                                            
                                                            void Shape_delete( Shape **self )
                                                            {
                                                                free( *self ), *self = NULL;
                                                            }
                                                            
                                                            
                                                            void Shape_update( Shape *self )
                                                            {
                                                                self->x += self->x_inc;
                                                                self->y += self->y_inc;
                                                            }
                                                            
                                                            
                                                            void Shape_display( Shape *self )
                                                            {
                                                                SDL_Surface *s = SDL_GetVideoSurface();
                                                                int x, y;
                                                                int d = self->r * 2;
                                                            
                                                                for( y = 0; y < d && self->y + y < s->h; y++ )
                                                                {
                                                                    if( self->y + y >= 0 )
                                                                    {
                                                                        Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + ( self->y + y ) * s->pitch );
                                                                        for( x = 0; x < d && self->x + x < s->w; x++ )
                                                                        {
                                                                            if( x + self->x >= 0)
                                                                            {
                                                                                Uint8 r, g, b;
                                                                                SDL_GetRGB( *( offset + x + self->x ), s->format, &r, &g, &b );
                                                                                r = SET_IN_RANGE( r + self->r_inc, 0, 255 );
                                                                                g = SET_IN_RANGE( g + self->g_inc, 0, 255 );
                                                                                b = SET_IN_RANGE( b + self->b_inc, 0, 255 );
                                                                                *( offset + x + self->x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                                            }
                                                                        }
                                                            
                                                                    }
                                                                }
                                                            }
                                                            
                                                            
                                                            
                                                            /* ShapeArray --------------------------------------------------------------- */
                                                            Shape** ShapeArray_new( int n )
                                                            {
                                                                Shape **p_new = (Shape**) malloc( n * sizeof * p_new );
                                                                int i;
                                                                for( i = 0; i < n; i++ )
                                                                    p_new[i] = Shape_new();
                                                            
                                                                return p_new;
                                                            }
                                                            
                                                            
                                                            void ShapeArray_update( Shape **shps, int n )
                                                            {
                                                                int i;
                                                                for( i = 0; i < n; i++ )
                                                                {
                                                                    int d = shps[i]->r * 2;
                                                                    Shape_update( shps[i] );
                                                                    if( shps[i]->x + d < 0
                                                                            || shps[i]->x - d >= SCR_W
                                                                            || shps[i]->y + d < 0
                                                                            || shps[i]->y - d >= SCR_H )
                                                                    {
                                                                        Shape_delete( &shps[i] );
                                                                        shps[i] = Shape_new();
                                                                    }
                                                                }
                                                            
                                                            }
                                                            
                                                            void ShapeArray_display( Shape **shps, int n )
                                                            {
                                                                int i;
                                                                for( i = 0; i < n; i++ )
                                                                    Shape_display( shps[i] );
                                                            }
                                                            
                                                            
                                                            void ShapeArray_delete( Shape ***shps, int n )
                                                            {
                                                                int i;
                                                                for( i = 0; i < n; i++ )
                                                                    Shape_delete( &( *shps )[i] );
                                                                free( *shps ), *shps = NULL;
                                                            }
                                                            
                                                            
                                                            
                                                            Uint32 time_left( Uint32 *nxtTime )
                                                            {
                                                                Uint32 now = SDL_GetTicks();
                                                                return *nxtTime <= now ? 0 : *nxtTime - now;
                                                            }
                                                            
                                                            void getPixelColor(int x, int y, SDL_Surface *map, Uint8 *r, Uint8 *g, Uint8 *b)
                                                            {
                                                              if(x>0 && y>0 && x<map->w && y<map->h)
                                                                SDL_GetRGB(*((Uint32 *)map->pixels + x + y * map->w),map->format,r,g,b);
                                                            }
                                                            
                                                            
                                                            void smooth( void )
                                                            {
                                                                SDL_Surface *s = SDL_GetVideoSurface();
                                                            
                                                                int x, y;
                                                                for( y = 0; y < s->h; y++ )
                                                                {
                                                                    Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + y * s->pitch ) ;
                                                                    for ( x = 0; x < s->w; x++ )
                                                                    {
                                                                        Uint8 r, g, b;
                                                                        SDL_GetRGB( *( offset + x ), s->format, &r, &g, &b );
                                                                        r = SET_IN_RANGE( DEC_R + r, 0, 255 );
                                                                        g = SET_IN_RANGE( DEC_G + g, 0, 255 );
                                                                        b = SET_IN_RANGE( DEC_B + b, 0, 255 );
                                                            
                                                                        *( offset + x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                                    }
                                                                }
                                                            }
                                                            
                                                            void blur(void)
                                                            {
                                                                SDL_Surface *s = SDL_GetVideoSurface();
                                                                SDL_Surface *s_backup = SDL_CreateRGBSurface(SDL_HWSURFACE, s->w, s->h, 32, 0, 0, 0, 0); ;
                                                                SDL_Rect position;
                                                                int x, y, i, j;
                                                                position.x = 0;
                                                                position.y = 0;
                                                            
                                                                SDL_BlitSurface(s, NULL, s_backup, &position);
                                                            
                                                                for( y = BLUR_WIDTH; y < s->h-BLUR_WIDTH; y++ )
                                                                {
                                                                    Uint32 *offset = ( Uint32 * )( ( Uint8 * )s->pixels + y * s->pitch ) ;
                                                                    for ( x = BLUR_WIDTH; x < s->w-BLUR_WIDTH; x++ )
                                                                    {
                                                                        Uint32 r, g, b;
                                                                        Uint8 r_temp, g_temp, b_temp;
                                                                        r = 0;
                                                                        g = 0;
                                                                        b = 0;
                                                                        for(i = -BLUR_WIDTH; i <= BLUR_WIDTH; i++)
                                                                            for(j = -BLUR_WIDTH; j <= BLUR_WIDTH; j++)
                                                                            {
                                                                                getPixelColor(x + i, y + j, s_backup, &r_temp, &g_temp, &b_temp);
                                                                                r += r_temp;
                                                                                g += g_temp;
                                                                                b += b_temp;
                                                                            }
                                                            
                                                                        r /= SQUARE(BLUR_WIDTH*2+1);
                                                                        g /= SQUARE(BLUR_WIDTH*2+1);
                                                                        b /= SQUARE(BLUR_WIDTH*2+1);
                                                                        *( offset + x ) = ( r << 16 ) + ( g <<  8 ) + ( b );
                                                                    }
                                                                }
                                                            }
                                                            
                                                            
                                                            int main ( int argc, char* argv[] )
                                                            {
                                                                SDL_Surface *screen = NULL;
                                                                Uint32 startTime, nextTime;
                                                                Uint32 currentFrame = 0;
                                                                Shape **shapes;
                                                            
                                                                srand( time( NULL ) );
                                                            
                                                                if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
                                                                    exit( EXIT_FAILURE );
                                                            
                                                                screen = SDL_SetVideoMode( SCR_W, SCR_H, 32, SDL_SWSURFACE );
                                                                if( screen == NULL )
                                                                    exit( EXIT_FAILURE );
                                                            
                                                                shapes = ShapeArray_new( NB_SHAPE );
                                                            
                                                                SDL_FillRect( screen, NULL, 0 );
                                                            
                                                                startTime = 0;
                                                                nextTime = SDL_GetTicks() + TICK_INTERVAL;
                                                                while( !SDL_QuitRequested() )
                                                                {
                                                                    ShapeArray_update( shapes, NB_SHAPE );
                                                                    smooth();
                                                                    ShapeArray_display( shapes, NB_SHAPE );
                                                                    blur();
                                                            
                                                                    SDL_Delay( time_left( &nextTime ) );
                                                                    SDL_Flip( screen );
                                                            
                                                                    nextTime += TICK_INTERVAL;
                                                                    currentFrame++;
                                                            
                                                                }
                                                                printf( "%.2f fps\n", currentFrame * 1000.0 / ( SDL_GetTicks() - startTime ) );
                                                            
                                                                ShapeArray_delete( &shapes, NB_SHAPE );
                                                            
                                                                SDL_Quit();
                                                            
                                                                ( void )argc;
                                                                ( void )argv;
                                                            
                                                                return 0;
                                                            }
                                                            



                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              12 août 2010 à 1:02:00

                                                              Le "problème", c'est que je suis plus à l'aise en C++ pour ce genre de code or ici, c'est du C. Par ailleurs, la SFML est plus simple à utiliser en C++ qu'en C.

                                                              Mon premier essai aléatoire ressemble plus à une télévision qui ne capte pas qu'à du plasma :
                                                              Image utilisateur
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Exercice... Plasma 1er round...

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown