• STATISTIQUES
  • Il y a eu un total de 3 membres et 5431 visiteurs sur le site dans les dernières 24h pour un total de 5 434 personnes!


    2 membres se sont inscrits dans les dernières 24h!


    Membres: 2 608
    Discussions: 3 580
    Messages: 32 820
    Tutoriels: 78
    Téléchargements: 38
    Sites dans l'annuaire: 58


  • ANNUAIRE
  • [EN] Dare your mind
    JavaScript: 6, Crypto: 44, Stegano: 36, Logic: 13, Special: 27, Science: 11, Realistic: 7, Programming: 10, Crack It: 6,...
    Challenges
    [EN] Listbrain Version 3
    Site proposant 66 challenges présentés dans une liste mélangée.
    Challenges
    [FR] Le site du zero
    Découvrez gratuitement la programmation (C, C++, PHP, MySQL, XHTML, CSS...), Linux, le Mapping, la modé...
    Programmation
    [FR] Comment ca marche
     Gratuit et accessible à tous, ce site de communauté permet de se dépanner, se faire aider ...
    Webmaster
    [FR] Asp-php
    Tutoriaux sur ASP, PHP, ASP.net, XML, SQL, Javascript, HTML, VML - Scripts et ressources pour webmasters - Forums d&#...
    Programmation
    [EN] w3challs
    Ce site propose différents types de défis informatiques: piratage, craquage, cryptographie, stég...
    Hacking
    [FR] dcode
    dcode.fr est le site indispensable pour décoder des messages, tricher aux jeux de lettres, résoudre des énigmes...
    Outils / Add-on

  • DONATION
  • Si vous avez trouvé ce site internet utile, nous vous invitons à nous faire un don du montant de votre choix via Paypal. Ce don servira à financer notre hébergement.

    MERCI!




Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
[C] effet plasma C/SDL
07-09-2013, 17h12
Message : #1
gruik Hors ligne
gouteur de savon
*



Messages : 757
Sujets : 44
Points: 482
Inscription : Oct 2012
[C] effet plasma C/SDL
histoire de rompre la monotonie de ces derniers temps...

si vous avez des questions hésitez évidement pas à me les poser

[Image: 338740plasma.png]
pastebin
Code C :
/*
 * apt-get install libsdl1.2-dev (ubuntu)
 * gcc plasma.c -o plasma -Wall -lSDL
 *
 * n'importe quelle touche ou la croix pour quitter
 */


#include <SDL/SDL.h>
#include <malloc.h>
#include <math.h>

#define LARGEUR 500
#define HAUTEUR 500
#define PI 3.14159265359
#define STEP 1000

double distance (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) {
        // trigonometrie de ~15/16 ans : calcul de l'hypothenuse
        unsigned int i = x1 - x2, j = y1 - y2;
        return sqrt(i*i+j*j);
}

int main (void) {
        SDL_Surface *screen;
        SDL_Event event;
        unsigned int x,y,t=0;
        unsigned long c, hlarg=LARGEUR/2, hhaut=HAUTEUR/2;
        unsigned long pal[1024];
        double f1, f2, f3, deg = PI/180;
        double *_sin = calloc(360*STEP,sizeof(double)), *_cos = calloc(360*STEP,sizeof(double));
        if (!_sin || !_cos) return -1; // au cas ou malloc se chie dessus, pas la peine d'aller plus loin

        // on initialise la sdl et le mode gfx
        SDL_Init(SDL_INIT_VIDEO);
        screen = SDL_SetVideoMode(LARGEUR, HAUTEUR, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);

        // sine/cosine tables pre-computation
        for (x=0; x<360*STEP; x++) {
                _sin[x] = floor(sin(x*PI/180/STEP)*STEP)/STEP;
                _cos[x] = floor(cos(x*PI/180/STEP)*STEP)/STEP;
        }
        // colors palette
        for (x=0; x<1024; x++) {
                pal[x] = (unsigned long)(
                        ((unsigned char)(96+95*sin(x*0.6*deg))) << 16 |
                        ((unsigned char)(128+127*sin(x*0.5*deg))) << 8 |
                        ((unsigned char)(192+63*cos(x*0.1*deg)))
                );
        }

        // la boucle principale
        while (1) {
                if (SDL_PollEvent(&event)) // on check le clavier, si on presse une touche on sort
                        if ((event.type == SDL_QUIT) || (event.type == SDL_KEYDOWN))
                                break;

                if (SDL_MUSTLOCK(screen)) // on lock la surface si necessaire
                        SDL_LockSurface(screen);

                for (y=0;y<HAUTEUR;y++) { // la routine principale, on balaye l'ecran, pour chaque pixel on calcule son index dans la palette
                        for (x=0;x<LARGEUR;x++) {
                                // nos fonctions trigo horribles et consomatrices de cycles
                                f1 = sin(distance(x, y, LARGEUR + LARGEUR * _sin[(t*2)%(360*STEP)], HAUTEUR + (hhaut * _sin[(t)%(360*STEP)])) * deg * 0.3);
                                f2 = cos(distance(x, y, LARGEUR + hlarg * _sin[(t*3)%(360*STEP)], HAUTEUR + (HAUTEUR * _cos[(t*4)%(360*STEP)])) * deg * 0.7);
                                f3 = sin(distance(x, y, LARGEUR + hlarg * _cos[(t)%(360*STEP)], HAUTEUR + (hhaut * _cos[(t*2)%(360*STEP)])) * deg * 1.1);
                                // on somme et fait la moyenne des trois fonctions point a point, et on "anime" en ajoutant t, le tout donne l'indice dans la palette de couleurs
                                c = pal[((unsigned char)(512 + 512 * ((f1+f2+f3)/3))+t)%1024];
                                // putpixel
                                *(unsigned long *)(screen->pixels + y * screen->pitch + x * screen->format->BytesPerPixel) = c;
                        }
                }

                if (SDL_MUSTLOCK(screen)) // si c'etait necessaire de lock on unlock la surface prete pour affichage maintenant
                        SDL_UnlockSurface(screen);

                t += STEP;

                SDL_UpdateRect(screen,0,0,0,0); // on update l'affichage
        }

        // on quitte proprement
        SDL_Quit();
        free (_cos);
        free (_sin);
        return 0;
}
+1 (11) -1 (1) Répondre
07-09-2013, 17h35
Message : #2
Atlas Hors ligne
Membre actif
*



Messages : 69
Sujets : 7
Points: 3
Inscription : Aug 2012
RE: [C] effet plasma C/SDL
Vraiment sympa l'effet , je vais essayer de comprendre le code , merci du partage !
+1 (0) -1 (0) Répondre
07-09-2013, 19h46
Message : #3
-Mat-
Non-enregistré



 
RE: [C] effet plasma C/SDL
C'est cool en effet, pour l'instant j'ai pas regardé le cœur du code et je pense que j'aurais beaucoup de mal à l'assimiler.
Au début, j'ai juste voulu voir le SDL_Delay() ou autre qui faisait ralentir tout jusqu'à ce que je me rende compte qu'il n'y en avait pas ! Chez moi ça monte pas plus haut que 3/4 FPS. C'est vrai que j'ai pas une super config' (Pentium 4) mais je m'attendais pas à ce que ça bouffe autant de CPU. Il faut que la fenêtre soit en 200 x 200 pour que ça soit bien fluide.

Bref super principe. Bien optimisé, ça doit rendre vraiment classe.
positive (0) negative (0) Répondre
07-09-2013, 20h28
Message : #4
gruik Hors ligne
gouteur de savon
*



Messages : 757
Sujets : 44
Points: 482
Inscription : Oct 2012
RE: [C] effet plasma C/SDL
(07-09-2013, 19h46)-Mat- a écrit : Chez moi ça monte pas plus haut que 3/4 FPS. (...) je m'attendais pas à ce que ça bouffe autant de CPU.

héhé oui, j'ai hésité à l'optimiser et j'ai flemme j'avoue :p

ce qui fait que ca bouffe c'est que pour chaque pixel on a plusieurs sin/cos et que des calculs sur des double, j'ai sorti deux tables pré-calculées et sur mon proc ça a suffit à fluidifier le bouzin mais c'est de l'optimisation très laxiste Wink
également - et c'est une des optimisations les plus importantes - le principe est souvent de créer 2/3 grands tableaux mappés avec les fonctions et ensuite se contenter de prendre une portion dedans correspondant aux dimensions de ce qu'on veut afficher

pour ce qui est du fonctionnement général je pense que les commentaires dans le code sont pas trop mal sentis et résument bien le truc, le reste c'est de reload le module "trigonométrie de 3e" en mémoire et essayer de se représenter les différentes étapes mais c'est assez simple...
+1 (0) -1 (1) Répondre
08-09-2013, 16h08
Message : #5
Kiwazaru Hors ligne
Padawan d'un super escargot
*



Messages : 284
Sujets : 26
Points: 139
Inscription : Mar 2012
RE: [C] effet plasma C/SDL
Si ça prend tant que ça des capacités du CPU on pourrait pas se servir de cet exemple pour faire un benchmark ?
Toucher au Kernel, c'est un peut comme se shooter au LSD, on pense pouvoir tout faire mais ça finit souvent mal.
+1 (0) -1 (0) Répondre
09-09-2013, 22h11
Message : #6
sakiir Hors ligne
[sakiir@Ubuntu]:~$ ./ExploitMe ShellC0de
*



Messages : 411
Sujets : 51
Points: 34
Inscription : Sep 2012
RE: [C] effet plasma C/SDL
C'est vraiment fort ! bravo Smile
+1 (0) -1 (0) Répondre
10-09-2013, 09h08 (Modification du message : 10-09-2013, 11h19 par Jek0.)
Message : #7
Jek0 Hors ligne
Regular Everyday Normal Mazafaka
*



Messages : 113
Sujets : 5
Points: 40
Inscription : Jul 2013
RE: [C] effet plasma C/SDL
Ah le raytracing, le jour ou il font un jeu avec cette techno faudra une salle serveur pour le faire tourner Smile

Edit : Effectivement, j'avais fait un projet de raytracing y'a quelques années, à vu d’œil (myope et astigmate) ça m'a rappelé ça, my bad.
Pour finir un mail avec panache :
Cordialement,
Va donc te reproduire avec ta propre ethnie, enfant malpropre de fille de joie,
[Insert-Your-Name-Here]
Si vous ne comprenez pas, traduisez dans le langage "2 la téci tavu".
+1 (0) -1 (0) Répondre
10-09-2013, 11h01
Message : #8
gruik Hors ligne
gouteur de savon
*



Messages : 757
Sujets : 44
Points: 482
Inscription : Oct 2012
RE: [C] effet plasma C/SDL
(08-09-2013, 16h08)ReVeRse a écrit : Si ça prend tant que ça des capacités du CPU on pourrait pas se servir de cet exemple pour faire un benchmark ?

(vu en pv) le propos d'un benchmark comme 3DMark par exemple c'est pas uniquement de bencher le CPU, bref non ça en fait pas forcément un bon candidat

(09-09-2013, 22h11)sakiir a écrit : C'est vraiment fort ! bravo Smile

merki ! Big Grin

(10-09-2013, 09h08)Jek0 a écrit : Ah le raytracing, le jour ou il font un jeu avec cette techno faudra une salle serveur pour le faire tourner Smile

humm... oui enfin, le raytracing c'est un rendu 3D "à la main" (comme ici), là il s'agit d'un plasma (même démo, ici), y'a pas trop de rapport ^^
Avant donc que d'écrire, apprenez à penser.
Selon que notre idée est plus ou moins obscure, l'expression la suit, ou moins nette, ou plus pure.
Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément.
(Nicolas Boileau, L'Art poétique)
+1 (0) -1 (1) Répondre
13-09-2013, 20h34
Message : #9
gruik Hors ligne
gouteur de savon
*



Messages : 757
Sujets : 44
Points: 482
Inscription : Oct 2012
RE: [C] effet plasma C/SDL
l'optimisation spéciale -Mat-, tardive mais y'a un SDL_Delay() maintenant Wink

Code DIFF :
--- a/plasma.c  2013-09-13 20:23:06.017363199 +0200
+++ b/plasma.c  2013-09-13 20:23:12.537281232 +0200
@@ -13,6 +13,7 @@
 #define HAUTEUR        500
 #define PI 3.14159265359
 #define STEP 1000
+#define COEF 1000
 
 double distance (unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2) {
        // trigonometrie de ~15/16 ans : calcul de l'hypothenuse
@@ -29,6 +30,11 @@
        double f1, f2, f3, deg = PI/180;
        double *_sin = calloc(360*STEP,sizeof(double)), *_cos = calloc(360*STEP,sizeof(double));
        if (!_sin || !_cos) return -1; // au cas ou malloc se chie dessus, pas la peine d'aller plus loin
+       unsigned int step = 360 * STEP;
+       double *func1 = calloc(LARGEUR*HAUTEUR*16, sizeof(double));
+       double *func2 = calloc(LARGEUR*HAUTEUR*16, sizeof(double));
+       double *func3 = calloc(LARGEUR*HAUTEUR*16, sizeof(double));
+       if (!func1 || !func2 || !func3) return -2;
 
        // on initialise la sdl et le mode gfx
        SDL_Init(SDL_INIT_VIDEO);
@@ -47,6 +53,14 @@
                        ((unsigned char)(192+63*cos(x*0.1*deg)))
                );
        }
+       // precalcul des images en memoire (optimisation)
+       for (x=0; x<LARGEUR*4;x++) {
+               for (y=0;y<HAUTEUR*4;y++) {
+                       func1[y*LARGEUR*4+x] = sin(distance(x, y, LARGEUR*2, HAUTEUR*2) * deg * 0.3);
+                       func2[y*LARGEUR*4+x] = cos(distance(x, y, LARGEUR*2, HAUTEUR*2) * deg * 0.7);
+                       func3[y*LARGEUR*4+x] = cos(distance(x, y, LARGEUR*2, HAUTEUR*2) * deg * 1.1);
+               }
+       }
 
        // la boucle principale
        while (1) {
@@ -60,9 +74,9 @@
                for (y=0;y<HAUTEUR;y++) { // la routine principale, on balaye l'ecran, pour chaque pixel on calcule son index dans la palette
                        for (x=0;x<LARGEUR;x++) {
                                // nos fonctions trigo horribles et consomatrices de cycles
-                               f1 = sin(distance(x, y, LARGEUR + LARGEUR * _sin[(t*2)%(360*STEP)], HAUTEUR + (hhaut * _sin[(t)%(360*STEP)])) * deg * 0.3);
-                               f2 = cos(distance(x, y, LARGEUR + hlarg * _sin[(t*3)%(360*STEP)], HAUTEUR + (HAUTEUR * _cos[(t*4)%(360*STEP)])) * deg * 0.7);
-                               f3 = sin(distance(x, y, LARGEUR + hlarg * _cos[(t)%(360*STEP)], HAUTEUR + (hhaut * _cos[(t*2)%(360*STEP)])) * deg * 1.1);
+                               f1 = func1[((y+(int)(HAUTEUR + hhaut * _sin[t%step]))*(LARGEUR<<2))+(x+(int)(LARGEUR + LARGEUR * _sin[(t<<1)%step]))];
+                               f2 = func2[((y+(int)(HAUTEUR+HAUTEUR*_cos[(t<<2)%step]))*(LARGEUR<<2))+(x+(int)(LARGEUR+hlarg*_sin[(t*3)%step]))];
+                               f3 = func3[((y+(int)(HAUTEUR+hhaut*_cos[(t<<1)%step]))*(LARGEUR<<2))+(x+(int)(LARGEUR+hlarg*_cos[(t)%step]))];
                                // on somme et fait la moyenne des trois fonctions point a point, et on "anime" en ajoutant t, le tout donne l'indice dans la palette de couleurs
                                c = pal[((unsigned char)(512 + 512 * ((f1+f2+f3)/3))+t)%1024];
                                // putpixel
@@ -76,6 +90,7 @@
                t += STEP;
 
                SDL_UpdateRect(screen,0,0,0,0); // on update l'affichage
+               SDL_Delay(20);
        }
 
        // on quitte proprement
 

le pastebin du nouveau code

finalement ça m'aura également permis de me rendre compte, c'était mon premier plasma, et les formules que j'ai choisi si elles donnent un résultat qu'est joli à regarder sont pour autant pas forcément très heureuses, ce serait à refaire il y aurait moyen de choisir plus habilement tous les paramètres pour un résultat tout aussi eye-candy
Avant donc que d'écrire, apprenez à penser.
Selon que notre idée est plus ou moins obscure, l'expression la suit, ou moins nette, ou plus pure.
Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément.
(Nicolas Boileau, L'Art poétique)
+1 (2) -1 (1) Répondre
14-09-2013, 13h50
Message : #10
-Mat-
Non-enregistré



 
RE: [C] effet plasma C/SDL
En effet c'est beaucoup plus drôle comme ça, c'est vraiment cool !
Comment t'as fait pour trouver tes formules ? En tâtonnant ?
positive (2) negative (0) Répondre
14-09-2013, 14h07
Message : #11
gruik Hors ligne
gouteur de savon
*



Messages : 757
Sujets : 44
Points: 482
Inscription : Oct 2012
RE: [C] effet plasma C/SDL
ok tu me confirme que ça passe et que c'est fluide sur ta békane, c'est ce que je voulais savoir surtout Wink

(14-09-2013, 13h50)-Mat- a écrit : Comment t'as fait pour trouver tes formules ? En tâtonnant ?

plus ou moins oui, disons que je suis parti du principe global d'un plasma (le propos étant de le faire entièrement sans repomper un code existant évidement) et ensuite j'ai effectivement tâtonné jusqu'à avoir un résultat pas trop dégueu
du coup pour l'optimisation je tenais malgré tout à conserver les mêmes formules plutôt que de glisser vers des formules plus pratiques en terme de cout mémoire et cpu

il y a moyen de l'accelerer encore énormément, en choisissant des formules qui permettent de ne précalculer qu'une seule image au lieu de trois, 4x plus petites en mémoire, des "mouvements" sinusoïdaux plus simples en termes de calculs, à ça on peut envisager de threader le calcul de chacune des trois fonctions f1,f2,f3 (voire même d'en faire sauter une carrément), d'utiliser un algo type CORDIC pour le calcul des sin/cos... pour les grandes lignes :p
Avant donc que d'écrire, apprenez à penser.
Selon que notre idée est plus ou moins obscure, l'expression la suit, ou moins nette, ou plus pure.
Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément.
(Nicolas Boileau, L'Art poétique)
+1 (0) -1 (1) Répondre


Atteindre :


Utilisateur(s) parcourant ce sujet : 1 visiteur(s)
N-PN
Accueil | Challenges | Tutoriels | Téléchargements | Forum | Retourner en haut