Partage
  • Partager sur Facebook
  • Partager sur Twitter

Sauvegarder l'écran

en le copiant dans une autre surface[ SDL_CreateRGBSurfaceFrom...] peut-être

Sujet résolu
    3 juillet 2006 à 16:49:25

    Hello les amis!

    Je cherche la solution pour sauvegarder l'écran puis le recharger ensuite pour annuler les modifs qu'il y a eu entre-deux comme sur ce topic
    Sauf que la différence c'est que chez moi la fonction SDL_CreateRGBSurfaceFrom ne copie rien du tout mais elle ne renvoie pas NULL :euh:

    Voici donc la fonction de sauvegarde


    SDL_Surface* save(SDL_Surface* ecran)
    {
        SDL_Surface *copie_ecran=SDL_CreateRGBSurfaceFrom(//on copie l'écran
        ecran->pixels,
        ecran->w,
        ecran->h,
        ecran->format->BitsPerPixel,
        ecran->pitch,
        ecran->format->Rmask,
        ecran->format->Gmask,
        ecran->format->Bmask,
        ecran->format->Amask);
        if (copie_ecran==NULL)
            printf("NULL");
        printf("sauvegarde");//pour controler
        return copie_ecran;
    }

    Merci d'avance!!!
    PS:Cool le forum plusieur de mes problème ont déja pu être résolus grâce à votre aide merci les gars!
    • Partager sur Facebook
    • Partager sur Twitter
      3 juillet 2006 à 17:46:57

      Perso, j'utilise cette fonction :
      SDL_SaveBMP(SDL_Surface* ecran, const char* name);

      Pour sauvagarger l'ecran. Un exemple :
      SDL_SaveBMP(ecran, "sauvegarde.bmp");

      La fonction sauvegarde la surface ecran et l'enregistre sous le nom de sauvegarde.bmp. ;)

      Edit: Que de fautes !
      • Partager sur Facebook
      • Partager sur Twitter
        3 juillet 2006 à 19:37:21

        ok déso kubb j'y penserait
        • Partager sur Facebook
        • Partager sur Twitter
          3 juillet 2006 à 20:27:33

          Je ne sais pas si c'est SDL ou OpenGL mais :
          takeScreenshot("nom_de_nouvelle_image.bmp");

          Marche très bien sur mon code.
          • Partager sur Facebook
          • Partager sur Twitter
            5 juillet 2006 à 16:58:44

            je pensais à une solution qui permet de copier une surface dans une autre [SDL_CreateRGBSurfaceFrom...il me semble:)] dans la mémoire vive parce que c'est un peu lourd de créer plein de fichier BMP( et c'est pas lent?)

            Sinon je verrais avec les fichiers!!!
            • Partager sur Facebook
            • Partager sur Twitter
              5 juillet 2006 à 17:02:38

              takeScreenshot est une fonction codée par Kayl pour savegarder l'ecran en OpenGL.

              Heu.., au fait, pk tu fais pas ?
              SDL_Surface *ecran, *sauvegarde;

              sauvegarde = ecran;


              ^^
              • Partager sur Facebook
              • Partager sur Twitter
                5 juillet 2006 à 17:04:26

                mon prog n'est pas encore en OpenGL :p
                • Partager sur Facebook
                • Partager sur Twitter
                  5 juillet 2006 à 18:06:44

                  Apparement il veut simplement copier une SDL_Surface hein... rien à voir avec les fichiers (ou mal demandé ?).

                  Pour la copier, tu fais simplement un blit.
                  • Partager sur Facebook
                  • Partager sur Twitter
                    6 juillet 2006 à 12:52:09

                    Citation : Remram

                    Apparement il veut simplement copier une SDL_Surface hein


                    oui c'est ça :) mais blitter plusieurs fois la même image ne suffira pas parce que l'image en question aura changé et il me faudra blitter l'image( l'écran donc)comme elle était avant pour annuler les modifications donc je dois sauvegarder l'ancienne image...

                    PS:LE BUT C'EST DE POUVOIR ,DANS UN JEU, ECRIRE UN MESSAGE A L'ECRAN ET LE FAIRE DISPARAITRE UN MOMENT APRES ^^
                    • Partager sur Facebook
                    • Partager sur Twitter
                      6 juillet 2006 à 13:16:16

                      Ba tu créé une surface copie qui fait la meme taille que la surface d'origine et grace au tuto de Piwaï, tu copie chaque pixel de la surface d'origine dans la surface de destination.

                      (Vos tuto > C/C++ > modifier une image pixel par pixel) :p

                      Citation : Fradow

                      En théorie, je dirai qu'il suffit de créer une autre surface ayant les mêmes caractéristiques que l'écran, et que à l'instant que tu souhaites, tu blitte l'écran sur cette surface, je vois aucune raison pour que ça ne marche pas.


                      T'as essayé ? ^^
                      • Partager sur Facebook
                      • Partager sur Twitter
                        6 juillet 2006 à 14:59:42

                        guimers8 -> :) voilà chu en tr1 de faire une fonction de copie grace au tuto du Piwaï mais il me marque
                        Linking console executable: SDLapp.exe
                        .objs\main.o:main.c:(.text+0x3f6): undefined reference to `getPixel'
                        .objs\main.o:main.c:(.text+0x419): undefined reference to `setPixel'
                        collect2: ld returned 1 exit status
                        Process terminated with status 1 (0 minutes, 0 seconds)

                        et Piwaï dit que ses sources c'est du c++, pourtant c'est du c

                        Citation : piwaï dans son tuto

                        Je tiens à rappeller que ce code est du C++, il faut enregistrer les fichiers au format.cpp et utiliser un compilateur C++ (c'est le cas de gcc)

                        alors faut il vraiment mettre main.cpp?
                        • Partager sur Facebook
                        • Partager sur Twitter
                          7 juillet 2006 à 9:01:22

                          Ben en fait t'es pas onligé de faire ton prog en C++, il te faut juste utiliser ces deux fonctions :
                          Uint32 getPixel(SDL_Surface *surface, int x, int y)
                          {   
                              int bpp = surface->format->BytesPerPixel;
                               /* Ici p est l'adresse du pixel que l'on veut connaitre */
                               Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;


                               switch(bpp) {
                               case 1:
                                   return *p;

                               case 2:
                                   return *(Uint16 *)p;

                               case 3:
                                   if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
                                       return p[0] << 16 | p[1] << 8 | p[2];
                                   else
                                       return p[0] | p[1] << 8 | p[2] << 16;

                               case 4:
                                   return *(Uint32 *)p;

                               default:
                                   return 0; /* Ne devrait pas arriver, mais évite les erreurs */
                               }
                           }



                          void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
                          {
                              int bpp = surface->format->BytesPerPixel;
                               /* Ici p est l'adresse du pixel que l'on veut modifier */
                               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;
                               }
                           }

                          T'a juste a les copier dans ton programme. Ca marche très bien ;)
                          (par contre n'essai pas de comprendre la fonction, prend la telle quelle)
                          • Partager sur Facebook
                          • Partager sur Twitter
                            7 juillet 2006 à 10:57:05

                            ah! merci!Gni mais mtn mon prog plante ça peut-être à cause de ces fonctions?
                            • Partager sur Facebook
                            • Partager sur Twitter
                              7 juillet 2006 à 11:03:52

                              Peut etre que si tu fais voir ton code ? (Non, les fonction sont OK, elle marchent très bien :p)
                              • Partager sur Facebook
                              • Partager sur Twitter
                                7 juillet 2006 à 11:41:38

                                voilà c'est pour un bête compteur :p Mais j'ai l'intention d'd'utiliser cette technique pour écrire dans un jeu un message qui s'efface au bout d'un moment

                                #include <stdlib.h>
                                #include <stdio.h>
                                #include <SDL/SDL.h>
                                #include <SDL/SDL_getenv.h>
                                #include <SDL/SDL_ttf.h>
                                SDL_Surface* save(SDL_Surface* ecran);
                                void load(SDL_Surface *copie_ecran,SDL_Surface *ecran);
                                Uint32 getPixel(SDL_Surface *surface, int x, int y);
                                void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
                                int  main(int  argc, char *argv[])
                                {
                                    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1)
                                    {
                                        fprintf(stderr, "Erreur d'initialisation de la SDL");
                                        exit(EXIT_FAILURE);
                                    } // Initialisation de la SDL + test d'erreur
                                    if(TTF_Init() == -1)
                                    {
                                        fprintf(stderr, "Erreur d'initialisation de TTF_Init : %s\n",
                                        TTF_GetError());
                                        exit(EXIT_FAILURE);
                                    }
                                    //-----------------------------------------------------------------------------------------------------------------------------------
                                    putenv("SDL_VIDEO_WINDOW_POS=center"); //pour centrer la fenêtre
                                    int tempsActuel = 0, tempsPrecedent = 0, compteur = 0;
                                    char temps[5]="";
                                    SDL_Surface *texte=NULL, *fond=NULL;
                                    SDL_Surface* copie_ecran=NULL;
                                    SDL_Surface *ecran;
                                    TTF_Font *police = NULL; /* Stockera les informations de police */
                                    SDL_Color bleu={0,0,255};
                                    police = TTF_OpenFont("44v2.ttf", 50); /* Ouverture de la police au début */
                                    ecran = SDL_SetVideoMode(600, 480, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
                                    if (&ecran == NULL) // Si l'ouverture a échoué, on écrit l'erreur et on arrête
                                    {
                                        fprintf(stderr, "Impossible de charger le mode vidéo : %s\nq",
                                        SDL_GetError());
                                        exit(EXIT_FAILURE);
                                    }//test de l'ouverture
                                    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
                                    fond=SDL_LoadBMP("Sans Titre.bmp");
                                    SDL_Rect PosFond;
                                    PosFond.x=ecran->w/2 - fond->w/2;
                                    PosFond.y=ecran->h/2 - fond->h/2;
                                    SDL_BlitSurface(fond, NULL, ecran, &PosFond);
                                    SDL_WM_SetCaption("test", NULL);
                                    SDL_Rect PositionTexte;
                                    SDL_Flip(ecran);
                                    copie_ecran=save(ecran);/*on sauvegarde l'ecran quand rien n'est encore
                                    écrit*/

                                    while(compteur<3000)
                                    {
                                        tempsActuel=SDL_GetTicks();
                                        if(tempsActuel-tempsPrecedent>=100)
                                        {
                                            SDL_FreeSurface(texte);
                                            load(copie_ecran,ecran);/*il devrait charger l'écran que c'était
                                            quand il y avait rien écrit pour blitter la nouvelle surface mais
                                            rien*/

                                            compteur+=100;
                                            sprintf(temps, "%d",compteur);
                                            texte = TTF_RenderText_Blended(police, temps, bleu);
                                            PositionTexte.x = ecran->w / 2 -texte->w / 2;
                                            PositionTexte.y = ecran->h / 2 -texte->h / 2;
                                            tempsPrecedent = tempsActuel; /* On met à jour le tempsPrecedent */
                                            SDL_BlitSurface(texte, NULL, ecran, &PositionTexte);
                                            SDL_Flip(ecran);
                                        }
                                        else
                                            SDL_Delay(100-(tempsActuel-tempsPrecedent));
                                    }
                                    TTF_CloseFont(police); /* Fermeture de la police avant TTF_Quit */
                                    TTF_Quit(); /* Arrêt de SDL_ttf (peut être avant ou après SDL_Quit) */
                                    SDL_FreeSurface(copie_ecran);

                                    SDL_Quit();
                                    return EXIT_SUCCESS;
                                }
                                SDL_Surface* save(SDL_Surface* ecran)
                                {
                                    int x,y;
                                    SDL_Surface *copie_ecran=SDL_CreateRGBSurfaceFrom(//on copie l'écran
                                    ecran->pixels,
                                    ecran->w,
                                    ecran->h,
                                    ecran->format->BitsPerPixel,
                                    ecran->pitch,
                                    ecran->format->Rmask,
                                    ecran->format->Gmask,
                                    ecran->format->Bmask,
                                    ecran->format->Amask);
                                    Uint32 pixel;
                                    SDL_LockSurface(ecran); //On bloque la surface
                                    for(y=0; y<ecran->h; y++)
                                    {
                                        for(x=0;x<ecran->w;x++)
                                        {
                                            pixel=getPixel(ecran,x,y);//on prend le pixel de l'image d'origine
                                            setPixel(copie_ecran,x,y,pixel);//on le place dans la nouvelle image
                                        }
                                    }
                                    SDL_UnlockSurface(ecran); /*On libère la surface,
                                    elle peut être utilisée pour une autre tâche*/

                                    printf("sauvegarde");
                                    return copie_ecran;
                                }
                                void load(SDL_Surface *copie_ecran,SDL_Surface *ecran)
                                {
                                    SDL_BlitSurface( copie_ecran, NULL, ecran, NULL);
                                    SDL_Flip(ecran);
                                    printf("chargement");
                                }
                                Uint32 getPixel(SDL_Surface *surface, int x, int y)
                                {
                                    int bpp = surface->format->BytesPerPixel;
                                     /* Ici p est l'adresse du pixel que l'on veut connaitre */
                                     Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;


                                     switch(bpp) {
                                     case 1:
                                         return *p;

                                     case 2:
                                         return *(Uint16 *)p;

                                     case 3:
                                         if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
                                             return p[0] << 16 | p[1] << 8 | p[2];
                                         else
                                             return p[0] | p[1] << 8 | p[2] << 16;

                                     case 4:
                                         return *(Uint32 *)p;

                                     default:
                                         return 0; /* Ne devrait pas arriver, mais évite les erreurs */
                                     }
                                 }

                                void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
                                {
                                    int bpp = surface->format->BytesPerPixel;
                                     /* Ici p est l'adresse du pixel que l'on veut modifier */
                                     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;
                                     }
                                }


                                et save n'a pas l'air de sauvegarder
                                Merci d'avance!!!
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  7 juillet 2006 à 18:12:17

                                  Pour les fonctions, t'a pensé a mettre les prototypes?

                                  void setPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
                                  et
                                  Uint32 getPixel(SDL_Surface *surface, int x, int y);
                                  ?
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    7 juillet 2006 à 20:57:36

                                    oui en haut du code si tu regardes;)

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      8 juillet 2006 à 14:42:02

                                      personne? Qui est assez fou pour se lancer?
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        8 juillet 2006 à 14:44:11

                                        Citation : icepower3125

                                        PS:LE BUT C'EST DE POUVOIR ,DANS UN JEU, ECRIRE UN MESSAGE A L'ECRAN ET LE FAIRE DISPARAITRE UN MOMENT APRES ^^


                                        Logique à revoir, personne ne fait ça. Tu affiches le fond ou n'importe quoi, tu écris le message, et ensuite tu réaffiches le fond par dessus (et il n'y aura plus de message). C'est comme ça que je fais, c'est comme ça que tout le monde fait.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          8 juillet 2006 à 16:25:06

                                          remram44->Ouai je vais faire comme ça je pense ( cetainement plutôt ) MERCI QUAND MEME A TOUS!
                                          • Partager sur Facebook
                                          • Partager sur Twitter

                                          Sauvegarder l'écran

                                          × 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