Partage
  • Partager sur Facebook
  • Partager sur Twitter

ou est le probleme ?

Sujet résolu
    25 mai 2008 à 21:23:48

    Suite a une idée simple (POOiser SDL), mais pas forcement bonne, j'ai pondu ce code.
    Il compile, et plante... ce qui rend le probleme inabordable(pour moi), c'est que le code marche une fois, mais ne blit pas l'image a la 2eme itération.
    Si je met deux "ecran.blit(bmp);" a la suite, le code plante aprés compilation (Segmentation fault)

    Fenetre.hpp
    #ifndef FENETRE_HPP_INCLUDED
    #define FENETRE_HPP_INCLUDED
    
    #include <iostream>
    #include <SDL/SDL.h>
    #include "Fenetre.hpp"
    #include "Image.hpp"
    
    
    class Fenetre
    {
        public:
            Fenetre( int x = 640 , int y = 480 , int bpp = 32 );
            ~Fenetre();
    
            void flip();
            void clear();
            void blit(Image image);
    
        private:
            SDL_Surface* screen;
    };
    
    #endif // FENETRE_HPP_INCLUDED
    


    Fenetre.cpp
    #include <iostream>
    #include <SDL/SDL.h>
    #include "Fenetre.hpp"
    #include "Image.hpp"
    
    
    using namespace std;
    
    Fenetre::Fenetre( int x , int y , int bpp )
    {
        if ( SDL_Init ( SDL_INIT_VIDEO ) < 0 )
            {
                cerr << "Erreur lors de l'initialisation de la SDL : " << SDL_GetError() << endl;
                exit(1);
            }
    
        screen = SDL_SetVideoMode(x, y, bpp, SDL_HWSURFACE | SDL_DOUBLEBUF);
    
        if ( !screen )
        {
            cerr << "Erreur lors de la création de la fenêtre : " << SDL_GetError() << endl;
            exit(1);
        }
    }
    
    Fenetre::~Fenetre()
    {
        SDL_Quit();
    }
    
    void Fenetre::flip()
    {
        SDL_Flip(screen);
    }
    
    void Fenetre::clear()
    {
        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 255, 255, 255));
    }
    
    void Fenetre::blit(Image image)
    {
        SDL_Rect posImage = image.getPosition();
    
        SDL_BlitSurface(image.getSurface(), 0, screen, &posImage);
    }
    


    Image.hpp
    #ifndef IMAGE_HPP_INCLUDED
    #define IMAGE_HPP_INCLUDED
    
    #include <iostream>
    #include <SDL/SDL.h>
    #include "Fenetre.hpp"
    #include "Image.hpp"
    
    
    class Image
    {
        public:
            Image();
            Image(const char* path, int x=0, int y=0);
            ~Image();
    
            SDL_Rect getPosition() const;
            SDL_Surface* getSurface() const;
    
        private:
            SDL_Surface *image;
            SDL_Rect position;
    };
    
    #endif // IMAGE_HPP_INCLUDED
    


    Image.cpp
    #include <iostream>
    #include <SDL/SDL.h>
    #include "Fenetre.hpp"
    #include "Image.hpp"
    
    
    using namespace std;
    
    Image::Image()
    {
        image = NULL;
        position.x = 0;
        position.y = 0;
    }
    
    Image::Image(const char* path, int x, int y)
    {
        image = SDL_LoadBMP(path);
        if (!image)
        {
            cerr << "Erreur lors du chargement de l'image : " << SDL_GetError() << endl;
            exit(1);
        }
        position.x = x;
        position.y = y;
    }
    
    Image::~Image()
    {
        SDL_FreeSurface(image);
    }
    
    SDL_Rect Image::getPosition() const
    {
        return position;
    }
    
    SDL_Surface* Image::getSurface() const
    {
        return image;
    }
    


    main.cpp
    #include <iostream>
    #include <SDL/SDL.h>
    #include "Fenetre.hpp"
    #include "Image.hpp"
    
    int main ( int argc, char** argv )
    {
        Fenetre ecran( 640 , 480 , 32 );
    
        Image bmp("cb.bmp", 200, 100);
    
    
        bool done = false;
        while (!done)
        {
    
            SDL_Event event;
            while (SDL_PollEvent(&event))
            {
                switch (event.type)
                {
                case SDL_QUIT:
                    done = true;
                    break;
    
                case SDL_KEYDOWN:
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                }
    
            }
        ecran.clear();
    
        ecran.blit(bmp);
    
        ecran.flip();
        }
    
    
        return 0;
    }
    


    Merci d'avance.
    • Partager sur Facebook
    • Partager sur Twitter
      26 mai 2008 à 14:50:26

      bonjour: voila les erreurs que je voie

      Je ne suis pas sur d'avoir tout trouvé, tu devrais lancer ton code dans un debugger.


      1) SDL_Surface* screen; n'est pas détruite par le destructeur de Fenetre

      2)void Fenetre::blit(Image image) il faut passer image apr référence : la tu va en faire implicitement une copie alors que image ne permet pas ca, du coup soit ca plante soit ca rame, soit ca pourie la mémoire.

      le bon code :
      void Fenetre::blit(Image const & image);

      3) Image ne se copie pas, et le constructeur par défaut n'a pas de sens : il te faut le retirer et interdire la copie, comme ca les erreurs de copie planteront la compilation.
      • Partager sur Facebook
      • Partager sur Twitter
        26 mai 2008 à 17:11:01

        Merci, le code tourne

        Je ne sais pas interdire la copie d'une classe par contre, même si c'est pas vital.
        • Partager sur Facebook
        • Partager sur Twitter
          26 mai 2008 à 17:15:44

          Dans ton cas, je pense que pour interdire la copie, il te suffit de retirer le constructeur sans paramètres ou de le mettre en private ou protected.

          Je te conseille de vérifier la mémoire consommée par ton code, elle ne doit pas augmenter au fil du temps. C'est juste une vérification basique, mais ca t'évitera des erreurs futures.

          Quand tu as de la mémoire a gérer (comme ici avec les SDL_surface*) tu dois utiliser explicitement une stratégie pour savoir systématiquement qui est chargé de libérer les ressources que tu alloue.

          Utiliser des pointeurs intelligents avec comptage de référence, ou mettre systématiquement des delete dans le destructeur et interdire la copie.

          Si tu code en C++ SFML t'évite ce genre de soucis, mais si tu préfaires SDL, à toi de voir.


          • Partager sur Facebook
          • Partager sur Twitter
            26 mai 2008 à 17:48:03

            je vais essayer SFML, j'en avait jamais entendu parler. Ca a l'air pas mal
            Merci encore
            • Partager sur Facebook
            • Partager sur Twitter

            ou est le probleme ?

            × 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