Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème pour l'effacement d'écran en SDL

on voit plus rien !!!

    28 avril 2006 à 18:26:51

    Mon code est sensé être un petit menu, mais là n'est pas le probleme

    Lorsque, pour effacer l'écran, je fais un SDL_FillRect JUSTE devant le blittage, TOUTE la fenêtre que j'ai ouverte est blanche !!! La seule solution est d'effacer la surfce vant la boucle principale... Ce qui n'est donc pas une solution :p .

    Mon code :

    int main(int argc, char *argv[])
    {
        SDL_Surface *ecran = NULL, *menu[2] = {NULL, NULL}, *fleche = NULL;
        SDL_Rect positionElementMenu, positionFleche;                                                             
        long continuer = 1, pointe = 0, i = 0;
        SDL_Event evenement;

        positionElementMenu.y = 0;
        positionElementMenu.x = 50;
       
        positionFleche.y = 0;
        positionFleche.x = 0;
                                                             
        SDL_Init(SDL_INIT_VIDEO);
       

       
        SDL_WM_SetIcon(IMG_Load("sdl_icone.bmp"), NULL);

        ecran = SDL_SetVideoMode(150, 100, 32, SDL_HWSURFACE | SDL_RESIZABLE | SDL_DOUBLEBUF);
        SDL_WM_SetCaption("Test menu", NULL);
       
        menu[0] = IMG_Load("barre.bmp");
        menu[1] = IMG_Load("degrade.bmp");
        fleche = IMG_Load("fleche.bmp");
             
        SDL_EnableKeyRepeat(100, 100);
       
        SDL_ShowCursor(SDL_DISABLE);
         
       
         
        while(continuer)
        {
                        SDL_WaitEvent(&evenement);
                       
                        if(evenement.type == SDL_KEYDOWN)
                        {
                                          if(evenement.key.keysym.sym == SDLK_ESCAPE)
                                          {
                                                                      continuer = 0;
                                          }
                                         
                                          else if(evenement.key.keysym.sym == SDLK_UP)
                                          {
                                                                      pointe--;
                                          }
                                         
                                          else if(evenement.key.keysym.sym == SDLK_DOWN)
                                          {
                                                                      pointe++;
                                          }
                        }
                       
                        if(evenement.type == SDL_QUIT)
                        {
                                          continuer = 0;
                        }
                       
                       
                        if(pointe < 0)
                        {
                                  pointe = 1;
                        }
                       
                        if(pointe > 1)
                        {
                                  pointe = 0;
                        }
                       
                        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
                                           
                        while(i < 2)
                        {
                                SDL_BlitSurface(menu[i], NULL, ecran, &positionElementMenu);
                               
                                if(pointe == i)
                                {
                                          positionFleche.y = positionElementMenu.y;
                                         
                                          SDL_BlitSurface(fleche, NULL, ecran, &positionFleche);
                                }
                               
                                i++;
                                positionElementMenu.y += 50;
                        }
                       
               
                                         
                        SDL_Flip(ecran);
        }               
         

         SDL_FreeSurface(fleche);
         
         for( i = 0; i < 2; i++)
         {
              SDL_FreeSurface(menu[i]);
         }

        SDL_Quit();

        return EXIT_SUCCESS;
    }


    Merci d'avance ! ;)
    • Partager sur Facebook
    • Partager sur Twitter
      28 avril 2006 à 18:32:22

      Ben il faut que tu flip _avant_ de blitter, puisque le flip efface.

      Donc au lieu de flipper à la fin, tu n'as qu'à flipper que dans le cas où tu vas blitter, c'est à dire mettre le Flip juste avant le
      SDL_BlitSurface(fleche, NULL, ecran, &positionFleche);
      dans le if. (si j'ai bien vu, c'est le seul blit)

      C'est du bon sens.
      • Partager sur Facebook
      • Partager sur Twitter
        28 avril 2006 à 18:33:23

        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));

        Ta fonction signifie que tu veux remplir TOUT l'écran de blanc. Rien d'anormal donc.

        Maintenant, si tu ne veux pas remplir tout l'écran de blanc (j'avoue que je n'ai pas bien compris ce que tu veux faire), tu dois remplacer le NULL par un SDL_Rect qui contiendra le rectangle à remplir :)
        • Partager sur Facebook
        • Partager sur Twitter
          30 avril 2006 à 9:11:23

          Citation : bluestorm

          Donc au lieu de flipper à la fin, tu n'as qu'à flipper que dans le cas où tu vas blitter, c'est à dire mettre le Flip juste avant le Code :

          SDL_BlitSurface(fleche, NULL, ecran, &positionFleche);

          dans le if. (si j'ai bien vu, c'est le seul blit)



          Non, il y a aussi le
          SDL_BlitSurface(menu[i], NULL, ecran, &positionElementMenu);
          pour blitter les éléments du menu

          Citation : florent28

          Maintenant, si tu ne veux pas remplir tout l'écran de blanc (j'avoue que je n'ai pas bien compris ce que tu veux faire), tu dois remplacer le NULL par un SDL_Rect qui contiendra le rectangle à remplir :)



          Moi, je veux réinitialiser l'écran (effacer tout ce qu'il y a dessus quoi) pour éviter que lorsqu'on déplace la flèche, ça ne laisse des traces. D'ailleurs c'est bizarre, parce que le code pour effacer l'écran est le même que celui utilisé par M@teo pour son Mario Sokoban... et comme lui, je l'ai mis juste avant le blittage...
          • Partager sur Facebook
          • Partager sur Twitter
            1 mai 2006 à 11:08:33

            Utilise une indentation de 2 ou 4 (4 plus clair) parce que là c'est franchement trop...
            Apparement, tu n'initialises pas les champs w et h de tes SDL_Rect, ce qui est une mauvaise habitude.
            Sinon, tu dis que l'écran est tout blanc ?
            • Partager sur Facebook
            • Partager sur Twitter
              1 mai 2006 à 11:12:56

              Ouais, entièrement blanc !!!

              En fait, j'ai l'impression que ce sont surtout les surfaces contenues dans les tableaux qui sont recouvertes (ça m'a fait ça avec d'autres programmes), mais alors la variable "fleche" devrait être visible !!! Beuheuheu :'( ...
              • Partager sur Facebook
              • Partager sur Twitter
                1 mai 2006 à 19:33:47

                Salut,

                as-tu bien placé tes images dans le meme repertoire que ton projet et non dans un sous-dossier?

                A+
                • Partager sur Facebook
                • Partager sur Twitter
                  1 mai 2006 à 19:48:06

                  Ben t'as essayé de flipper juste avant tes blits, et à ce moment là seulement ? (avant ton fill_rect aussi).

                  Ou alors vire carrément le flip.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    2 mai 2006 à 17:39:59

                    Citation : Ptitlue

                    as-tu bien placé tes images dans le meme repertoire que ton projet et non dans un sous-dossier?



                    Oui, d'ailleurs lorsque je sors le FillRect de la boucle principale, les images s'affichent !

                    Citation : bluestorm

                    Ben t'as essayé de flipper juste avant tes blits, et à ce moment là seulement ? (avant ton fill_rect aussi).

                    Ou alors vire carrément le flip.



                    J'ai essayé quasiment toutes les positions pour le blit... Ca marche pas.
                    Et je peux pas virer le flip, mon programme est sensé être interactif !
                    • Partager sur Facebook
                    • Partager sur Twitter
                      3 mai 2006 à 19:21:47

                      Euh mais euh et alors ? Ça pose un grave problème de virer le flip, juste pour tester ?
                      • Partager sur Facebook
                      • Partager sur Twitter
                        3 mai 2006 à 23:08:58

                        if(pointe < 0)
                                            {
                                                      pointe = 1;
                                            }
                                           
                                            if(pointe > 1)
                                            {
                                                      pointe = 0;
                                            }
                                           
                                            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
                                                               
                                            while(i < 2)
                                            {
                                                    SDL_BlitSurface(menu[i], NULL, ecran, &positionElementMenu);
                                                   
                                                    if(pointe == i)
                                                    {
                                                              positionFleche.y = positionElementMenu.y;
                                                             
                                                              SDL_BlitSurface(fleche, NULL, ecran, &positionFleche);
                                                    }
                                                   
                                                    i++;
                                                    positionElementMenu.y += 50;
                                            }
                                           
                                   
                                                             
                                            SDL_Flip(ecran);
                            }               


                        je crois avoir trouvé !
                        Changer les lignes if
                        la comparaison < ou > doit être <= et >=
                        donc la boucle où se trouve les blit ne marchent pas.

                        Parce que chez moi, le SDL_Fillrect puis le blit et bien ça marche.

                        Pardon, mais je crois que j'ai posté trop vite, j'ai dit une bêtise :(
                        • Partager sur Facebook
                        • Partager sur Twitter
                          4 mai 2006 à 16:48:01

                          Citation : bluestorm

                          Euh mais euh et alors ? Ça pose un grave problème de virer le flip, juste pour tester ?



                          Certes non :p . Mais la SDL ne semble pas apprécier qu'on fasse une boucle principale sans flip, et me renvoie un écran noir.

                          Citation : lucky55

                          donc la boucle où se trouve les blit ne marchent pas.

                          Parce que chez moi, le SDL_Fillrect puis le blit et bien ça marche.



                          Si, la boucle avec les blits marche : si on enlève le FillRect de la boucle principale, tout s'affiche correctement... Par contre, pourquoi ça marche chez toi alors que chez moi non ? J'dois être maudit :'( ...
                          • Partager sur Facebook
                          • Partager sur Twitter
                            7 mai 2006 à 0:11:11

                            Je cro ique si tu expliquais clairement ce que tu veut faire... Parce que j'ai lu le topic au complet 2 fois et jai toujours absolument rien compris....
                            • Partager sur Facebook
                            • Partager sur Twitter
                              7 mai 2006 à 9:39:54

                              Mon code est sensé être un petit menu classique : il y a plusieurs choix, une flèche devant l'un d'eux et qui se déplace, indiquant ainsi quel élément du menu est actuellemnt sélectionné. Cependant, il n'est ici qu'un exemple, car le problème que j'ai s'est déjà remarqué dans d'autres de mes scripts.

                              Lorsque (comme le faisais M@teo) j'efface l'écran juste avant le blittage (afin d'éviter de garder des "traces" si un élément a été déplacé), TOUT est blanc : les images que j'ai blitté sont toujours là, mais recouvertes, et cela même après avoir testé toutes les positions possibles pour le Flip et le FillRect.

                              Donc voilà, j'espère avoir été assez clair ce coup-ci :)
                              • Partager sur Facebook
                              • Partager sur Twitter
                                8 mai 2006 à 8:58:08

                                ça c'est du up ;)

                                Il faut que tu réaffiche toutes les images
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  8 mai 2006 à 10:01:07

                                  Citation : Natim

                                  Il faut que tu réaffiche toutes les images



                                  Comment ça ? Désolé, pas bien compris... :-°

                                  (et désolé pour le triple up, mon ordi rame aujourd'hui et j'ai pas la patience d'attendre... :euh: )
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    8 mai 2006 à 10:31:28

                                    Bah, tu recouvre l'ecran de blanc pour leffacer, normal, donc il recouvre TOUT. Ensuite, il faut tout réaficher pour voir.

                                    Il faut généralement effacer ton écran en fin de boucle infinie, après le blittage, ou en début, avant de mettre toute autre surface.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      8 mai 2006 à 16:25:24

                                      Citation : Benjitheone

                                      Bah, tu recouvre l'ecran de blanc pour leffacer, normal, donc il recouvre TOUT. Ensuite, il faut tout réaficher pour voir.



                                      Euh... Sans vouloir jouer les attardés, c'est pas ce que je fais :p ? J'ai déjà testé au début de la boucle infinie... Et bin non :'( . Rien.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        10 mai 2006 à 14:54:18

                                        while(i < 2)
                                                            {
                                                                    SDL_BlitSurface(menu[i], NULL, ecran, &positionElementMenu);
                                                                   
                                                                    if(pointe == i)
                                                                    {
                                                                              positionFleche.y = positionElementMenu.y;
                                                                             
                                                                              SDL_BlitSurface(fleche, NULL, ecran, &positionFleche);
                                                                    }
                                                                   
                                                                    i++;
                                                                    positionElementMenu.y += 50;
                                                            }
                                                           
                                                   
                                                                             
                                                            SDL_Flip(ecran);


                                        Le i de la boucle while n'est pas réinitialisé à zéro.
                                        Tu devrais faire une boucle for :

                                        for (i=0;i<2;i++)


                                        Comme ça, tu affiche à chaque tour de boucle principale.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          10 mai 2006 à 15:12:05

                                          positionElementMenu.y += 50;
                                          sa me parait strange... logiquement au bout de un dixieme de seconde il se retrouve ejecter hors de l'écran non? Vu qui si positionElementMenu.y = 50000 sa aura du mal a rentrer dans ton petit ecran d'ordi.
                                          Pareil pour ton i qui ne cesse d'augmenter. Du coup i peut etre egal a pointe que les deux premiere fois que le boucle de ton programme(ce qui ce passe tres vite)apres quand i=3 et ta boucle elle a du mal.
                                          Apres pour ta boucle principal elle est plein de if t'aurais pus utiliser un while sa aurait été plus claire pour tout le monde
                                          SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
                                          Il vient faire quoi ici lui? y'a deja un flip a la fin de ta boucle sa me parait bon
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            11 mai 2006 à 11:41:13

                                            Citation : lucky55

                                            Le i de la boucle while n'est pas réinitialisé à zéro.
                                            Tu devrais faire une boucle for :

                                            for (i=0;i<2;i++)



                                            Comme ça, tu affiche à chaque tour de boucle principale.



                                            Citation : Skelletons

                                            positionElementMenu.y += 50;

                                            sa me parait strange... logiquement au bout de un dixieme de seconde il se retrouve ejecter hors de l'écran non? Vu qui si positionElementMenu.y = 50000 sa aura du mal a rentrer dans ton petit ecran d'ordi.
                                            Pareil pour ton i qui ne cesse d'augmenter. Du coup i peut etre egal a pointe que les deux premiere fois que le boucle de ton programme(ce qui ce passe tres vite)apres quand i=3 et ta boucle elle a du mal.



                                            Bah merci vous deux : le problème principal de ce topic reste, mais mon programme marche (enfin :) ) .

                                            Bon, maintenant, GRANDE explication, haute en image, pour expliquer la nature exacte de mon problème :

                                            Oublions le code de mon petit menu : les images que je montre sont celles d'un autre de mes programmes, tout bête d'ailleurs : c'est une barre d'énergie qui s'allonge lorsque on appuie sur "droite" et qui se rétrécit quand on appuie sur "gauche" (enfin jusqu'à un certain point ;) ).

                                            Capture d'écran de mon programme : j'ai allongé la barre au maximum, avant de la rétrécir :

                                            Image utilisateur


                                            Remarquez les petits traits qui apparaissent (j'ai augmenté le contraste pour qu'on voit mieux) :

                                            Image utilisateur


                                            La solution est donc de recolorier l'écran en blanc A CHAQUE TOUR DE BOUCLE, avant le blittage. C'est là qu'arrive le problème :

                                            Image utilisateur


                                            Il n'y a plus de petits traits, c'est le côté positif :p . N'empêche que c'est pas génial (petite précision : moi ça me semble rien, mais lorsque j'ouvre la fenêtre, tout s'affiche correctement : c'est lorsque j'allonge où je rétrecis la barre que la partie du milieu disparaît...)


                                            Sinon, je me rends compte que j'ai dit une bêtise au début de ce post : les rectifications de lucky55 et de Skelletons sur mon code ont arrangé le problème :) (pour le menu, hein, je me suis pas fait ch**r à écrire tout ça pour dire que c'est arrangé à la fin :p ). Merci à tous pour cette première victoire !!!

                                            <edit>Tout bien réflechi, je pense que ce serta plus simple de voir ce qui cloche dans mon code si je vous le présente :p . Le voilà donc :

                                            void barre(SDL_Surface *ecran)
                                            {
                                                SDL_Surface *lignes[100] = {NULL};                                                       
                                                long pourcentage = 50;                                                                   
                                                SDL_Surface *debut = NULL, *fin = NULL;                                                 
                                                SDL_Rect positionDebut, positionMilieu, positionFin;                                     
                                                long i = 0, continuer = 1;                                                               
                                                SDL_Event evenement;                                                                     
                                               
                                               
                                                positionDebut.x = 0;
                                                positionDebut.y = 0;
                                                positionMilieu.x = 21;
                                                positionMilieu.y = 0;
                                                positionFin.x = pourcentage * 3 + 21;
                                                positionFin.y = 0;
                                               
                                                debut = IMG_Load("debut.png");
                                               
                                                while(i < 100)
                                                {
                                                                               lignes[i] = IMG_Load("milieu.png");
                                                                               i++;
                                                }
                                               
                                                fin = IMG_Load("fin.png");
                                               
                                                SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
                                                SDL_EnableKeyRepeat(10, 10);
                                                 
                                                i = 0
                                               
                                                while(continuer)
                                                   {     
                                                         
                                                        SDL_WaitEvent(&evenement);
                                                             

                                                                                         
                                                        rectifiePourcentage(&pourcentage);
                                                             
                                                             
                                                             
                                                        positionFin.x = pourcentage * 3 + 21;
                                                             
                                                             
                                                 
                                                       
                                                        if(evenement.type == SDL_KEYDOWN)
                                                        {
                                                                          if(evenement.key.keysym.sym == SDLK_RIGHT)
                                                                          {
                                                                               pourcentage++;
                                                                          }
                                                                         
                                                                          else if(evenement.key.keysym.sym == SDLK_LEFT)
                                                                          {
                                                                               pourcentage--;
                                                                          }
                                                                         
                                                                          else if(evenement.key.keysym.sym == SDLK_ESCAPE)
                                                                          {
                                                                               continuer = 0;
                                                                          }
                                                        }
                                                             
                                                        else if(evenement.type == SDL_QUIT)
                                                        {
                                                                          continuer = 0;
                                                        }     
                                                         
                                                       
                                                             
                                                        SDL_BlitSurface(debut, NULL, ecran, &positionDebut);
                                                   
                                                        while(positionMilieu.x < positionFin.x)
                                                        {
                                                                               SDL_BlitSurface(lignes[i], NULL, ecran, &positionMilieu);
                                                                               i++;
                                                                               positionMilieu.x += 3;
                                                        }
                                                       
                                                       
                                               
                                                        SDL_BlitSurface(fin, NULL, ecran, &positionFin);
                                                                         
                                                        SDL_Flip(ecran);                               
                                                    }

                                                SDL_EnableKeyRepeat(0, 0);


                                                for(i=0;1<100;i++)
                                                {
                                                    SDL_FreeSurface(lignes[i]);
                                                }
                                                SDL_FreeSurface(debut);
                                                SDL_FreeSurface(fin);
                                            }


                                            void rectifiePourcentage(long *pourcentage)
                                            {
                                                        if(*pourcentage < 0)
                                                        {
                                                                       *pourcentage = 0;
                                                        }
                                                       
                                                        if(*pourcentage > 100)
                                                        {
                                                                       *pourcentage = 100;
                                                        }
                                            }
                                            </edit>
                                            • Partager sur Facebook
                                            • Partager sur Twitter

                                            Problème pour l'effacement d'écran en SDL

                                            × 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