Partage
  • Partager sur Facebook
  • Partager sur Twitter

Programme SDL qui ne répond pas

ça répond pas

    1 avril 2021 à 15:43:59

    Bonjour, je débute en c et pour m'amuser, j'ai codé la fractal de Mandelbrot avec la SDL2 : pour afficher la fractal il faut faire beaucoup de calculs et ça peut prendre un peu de temps. 

    Pour la dessiner, il faut utiliser la suite Z(n+1) = Z² + c mais on peut aussi utiliser une formule plus général en mettant Z^d (ou d peut varier) au lieu de Z². (on utilise la suite Z(n+1) = Z^d +c)

    Je me suis amusé à faire un programme qui affiche donc la fractale plusieurs fois, en faisant varier l'exposant de la formule entre 2 et 10 avec un pas de 0.1, en exportant une image du résultat à chaque incrémentation de d. Mon problème, (j'y viens enfin) est qu'au lieu de voir sur l'écran la fractale qui change de forme au fur et à mesure, il y a écrit que ma fenêtre "ne répond pas" alors que pourtant, je vois que le programme exporte bien les images...

    Du coup j'aimerais savoir pourquoi mon programme ne répond pas et affiche une image figée, alors qu'il continue de fonctionner?

    Bon jsp si j'ai été clair mais j'espère que vous comprendrez !

    Merci

    • Partager sur Facebook
    • Partager sur Twitter

    jaj de jej

      1 avril 2021 à 15:51:19

      Salut,

      Dans tous les cas, il faut que tu dépiles les events : 

      while(SDL_Pollevent(&event))

      C'est souvent un soucis qui bloque.

      Ensuite, si tu es en double buffering, il faut que tu n'oublies pas de faire SDL_Flip

      • Partager sur Facebook
      • Partager sur Twitter

      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        1 avril 2021 à 18:15:18

        Hello

        Fvirtman a écrit:

        il faut que tu n'oublies pas de faire SDL_Flip

        Le PO utilise sdl 2 :)

        -
        Edité par edgarjacobs 1 avril 2021 à 18:16:01

        • Partager sur Facebook
        • Partager sur Twitter

        On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

          1 avril 2021 à 18:42:21

          Salut,

          Avec du code, ce serait plus facile de répondre. :)

          • Partager sur Facebook
          • Partager sur Twitter
          Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs
            6 avril 2021 à 16:48:59

            yo@n97one a écrit:

            Salut,

            Avec du code, ce serait plus facile de répondre. :)


            Effectivement c'est pas faux :

            donc voici le code qui permet de mettre chaque pixel de la bonne couleur  :

            et voici le code qui actualise la fenêtre :

            je vous ai épargné les initialisations qui ne changent pas grand chose...

            Ensuite, qu'est ce que ça veut dire " il faut que tu dépiles les events" et qu'est ce que le double buffering?? (je débute donc je connais pas encore tout ça o_O

            Et au passage je rectifie un truc : la fenêtre ne répond pas dès que je clique qq part ou que je fais une action avec l'ordi , si je ne touche à rien, je vois la fenêtre qui s'actualise comme je veux...

            • Partager sur Facebook
            • Partager sur Twitter

            jaj de jej

              6 avril 2021 à 18:49:04

              Hello,

              On évite les printscreen

              • Partager sur Facebook
              • Partager sur Twitter

              On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                6 avril 2021 à 19:56:12

                edgarjacobs a écrit:

                Hello,

                On évite les printscreen


                Ah dsl je savais pas du coup voici ma réponse sans capture d'écran :

                Voilà mon code :

                //Les librairies
                #include <SDL.h>
                #include <stdio.h>
                #include <stdlib.h>
                #include <complex.h>
                #include<SDL_image.h>
                //Les constantes
                #define LARGEUR 1200
                #define HAUTEUR 1200
                #define XMIN -2
                #define XMAX 5
                #define YMIN -1.25
                #define YMAX 1.25
                #define ITERATIONS 50
                
                //Les prototypes
                int initialisations(SDL_Window ** fenetre, SDL_Renderer **rendu, SDL_Surface **surface);
                int dessiner_le_fractal(SDL_Surface *surface, double exposant, double xmin, double xmax, double ymin, double ymax);
                
                
                int main(int argc, char * argv[])
                {
                    //Variables utiles :
                    SDL_Window * fenetre = NULL;
                    SDL_Renderer* rendu = NULL;
                    SDL_Surface* surface = NULL;
                    SDL_Texture* texture = NULL;
                
                    //initialisation de tout
                    initialisations(&fenetre, &rendu, &surface);
                    double exposant = 2, xmin = -2, xmax = 0.5, ymin = -1.25, ymax = 1.25;
                    char nom_du_fichier[100] = {0};
                    int nombre = 1;
                    int activation =1;
                    double zoomx =  -1.401155;
                    double zoomy = 0;
                    double vzoom = 1.05;
                    for(exposant = 2; exposant <10; exposant += 0.1)
                    {
                        dessiner_le_fractal(surface, exposant, xmin, xmax, ymin, ymax);
                        texture = SDL_CreateTextureFromSurface(rendu, surface);
                        SDL_RenderCopy(rendu, texture, NULL, NULL);
                        SDL_RenderPresent(rendu);
                       /* sprintf(nom_du_fichier, "mandelbrot/mandelbrot_%d.jpg", nombre);
                        IMG_SaveJPG(surface, nom_du_fichier, 100);
                        ymin = ((ymin - zoomy) / vzoom) + zoomy;
                        ymax = ((ymax - zoomy)/vzoom) + zoomy;
                        xmin = ((xmin - zoomx) / vzoom) + zoomx;
                        xmax = ((xmax - zoomx)/vzoom) + zoomx;  ==> on s'en fiche de ça aussi, c'est juste pour zoomer*/
                         SDL_Delay(100);
                    }
                
                
                
                
                    SDL_Delay(15000);
                    IMG_Quit();
                    SDL_FreeSurface(surface);
                    SDL_DestroyWindow(fenetre);
                    SDL_DestroyRenderer(rendu);
                    SDL_Quit();
                
                }
                
                int initialisations(SDL_Window ** fenetre, SDL_Renderer **rendu, SDL_Surface **surface)
                {
                    //initialise la SDL
                    if(SDL_Init(SDL_INIT_VIDEO) != 0)
                    {
                        fprintf(stderr, "Erreur d'initialisation de la SDL : %s", SDL_GetError());
                        SDL_Quit();
                        return -1;
                    }
                    IMG_Init(IMG_INIT_JPG);
                    //créer une fenetre
                    *fenetre = SDL_CreateWindow("Le fractale de toto", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
                                                 LARGEUR, HAUTEUR, SDL_WINDOW_SHOWN);
                     if(*fenetre == NULL)
                     {
                         fprintf(stderr, "Erreur de création de la fenetre : %s", SDL_GetError());
                         SDL_DestroyWindow(*fenetre);
                         SDL_Quit();
                         return -1;
                     }
                     //creer un rendu
                     *rendu = SDL_CreateRenderer(*fenetre, -1, SDL_RENDERER_ACCELERATED);
                     if(*rendu == NULL)
                     {
                         fprintf(stderr, "Le rendu est kapout : %s", SDL_GetError());
                         SDL_DestroyRenderer(*rendu);
                         SDL_DestroyWindow(*fenetre);
                         SDL_Quit();
                         return -1;
                        }
                
                         //création de la surface!
                         *surface = SDL_CreateRGBSurfaceWithFormat(0, LARGEUR, HAUTEUR, 32, SDL_PIXELFORMAT_RGBA8888);
                         if(*surface == NULL)
                         {
                             fprintf("Erreur de création de la surface : %s", SDL_GetError());
                             SDL_FreeSurface(surface);
                             SDL_DestroyRenderer(*rendu);
                             SDL_DestroyWindow(*fenetre);
                             SDL_Quit();
                             return -1;
                         }
                
                     return 0;
                }
                
                
                int dessiner_le_fractal(SDL_Surface *surface, double exposant, double xmin, double xmax, double ymin, double ymax)
                {
                    double x=0, y=0;
                    Uint32 *pixels = surface->pixels;
                    Uint32 couleur = SDL_MapRGB(surface->format, 0, 255, 0);
                    SDL_LockSurface(surface);
                    size_t i, j;
                    for(i = 0; i < HAUTEUR; i++)
                    {
                        for(j = 0; j < LARGEUR; j++)
                        {
                            x = (j*((xmax-xmin)/(double)LARGEUR)+xmin);
                            y = (i*((ymax-ymin)/(double)HAUTEUR)+ymin);
                            double complex c = x + y*I;
                            double complex vieuxz = 0.0 + 0.0*I;
                            double complex z= 0+0*I;
                            int cpt = 0;
                            while((creal(z) *creal(z)) + (cimag(z) *cimag(z)) < 4 && cpt <ITERATIONS)
                            {
                                vieuxz = z;
                              // z = (vieuxz * vieuxz) + c;
                              //c = c*c -0.8 +0.156*I;   ==> il ne faut pas regarder ces lignes, c'est juste quand je veux changer la forme de la fractal
                               z = cpow(vieuxz, exposant) + c;
                                cpt ++;
                
                            }
                            if(cpt >= ITERATIONS)
                            {
                                pixels[i * LARGEUR + j] = SDL_MapRGBA(surface->format, 0, 0, 0, 255);
                            }else{
                                pixels[i * LARGEUR + j] = SDL_MapRGBA(surface->format, (Uint8)(1*cpt), (Uint8)(5*cpt), (Uint8)(10*cpt), 255);
                            }
                
                
                    }
                    surface->pixels = pixels;
                    SDL_UnlockSurface(surface);
                
                
                }
                }

                Qqu'est ce que ça veut dire " il faut que tu dépiles les events" et qu'est ce que le double buffering?? (je débute donc je connais pas encore tout ça o_O) 

                Et au passage je rectifie un truc : la fenêtre ne répond pas dès que je clique qq part ou que je fais une action avec l'ordi , si je ne touche à rien, je vois la fenêtre qui s'actualise comme je veux...

                • Partager sur Facebook
                • Partager sur Twitter

                jaj de jej

                  6 avril 2021 à 20:47:14

                  Salut,

                  Tout d'abord, comme tu génères une texture a chaque tour de boucle, ligne 41, il faut la détruire à la fin : par exemple après ton SDL_delay ligne 50 :

                  SDL_DestroyTexture(texture);

                  Ensuite ton dernier soucis, c'est du dépilage d'event :

                  Essaie par exemple ligne 49 tu mets :

                  SDL_Event event;
                  while(SDL_PollEvent(&event))
                  {
                  }
                  


                  Pour faire simple :

                  Chaque fois que tu bouges la souris, que tu appuies sur une touche, que tu cliques, ou n'importe quel événement extérieur, un "bonhomme qui porte la pancarte de ce qui s'est passé" se met dans une file d'attente.

                  Si tu laisses pourrir la file d'attente, au bout d'un moment elle va saturer.

                  Donc il faut... "faire passer les gens", fait défiler.

                  Pour l'instant je vois que tu n'as pas envie de savoir sur quelle touches on a appuyé etc, donc laisse les passer sans les regarder :  d'ou le while vide dont je te parle : tant qu'il y a des events, laisse passer.... dépile (de empiler/dépiler)

                  -
                  Edité par Fvirtman 6 avril 2021 à 20:50:44

                  • Partager sur Facebook
                  • Partager sur Twitter

                  Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

                  Programme SDL qui ne répond pas

                  × 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