IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Problème avec le CSFML


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Par défaut Problème avec le CSFML
    Bonjour à tous, ceci est mon premier message sur ce forum car il m'a souvent aidé dans la programmation

    Alors voilà mon petit problème, je suis étudiant et actuellement je fais du C. Dans le cadre de mes études, j'utilise la librairie graphique SFML mais version C (CSFML).
    Je n'ai jamais fais de programmation avec des librairies graphiques. Je tente d'afficher un ou plusieurs pixels pour le début en tout cas !

    Pour se faire je créer une fenêtre, ainsi qu'un buffer. Je créer la texture, et utilise la fonction sfTexture_updateFromPixels
    Mais cette dernière me fais segfault et je ne vois pas pourquoi. Peut etre que quelqu'un pourra m'aider. Je vous met le code, ce dernier n'est pas complet, il manque le sprite etc ... Mais j'ai réduis le code pour le forum car après plusieurs tests c'est bien la fonction citée plus tot qui me fait segfault.

    Je ne souhaite pas forcément la réponse Mais un indice, ou qu'on m'explique si mon raisonnement n'est pas bon

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
     
    int                                main(int argc, char **argv)                      
     {                                                                        
        sfVideoMode           mode;                                            
        sfRenderWindow*   window;                                          
        t_my_framebuffer*   framebuffer;                                     
        sfTexture*                texture;                                         
        sfSprite                    *sprite;                                  
     
        mode.width = 1000;                                                     
        mode.height = 1000;                                                    
        window = sfRenderWindow_create(mode, "SFML window", sfResize | sfClose, NULL);                                                                 
        if (window == NULL)                                                    
           return (1);                                                          
        framebuffer = my_framebuffer_create(1000,1000);                        
        texture = sfTexture_create(1000, 1000);                                
        sfTexture_updateFromPixels(texture, framebuffer->pixels, framebuffer->width, framebuffer->height, 0, 0);                                       
        while(42)                                                              
        {                                                                     
           sfRenderWindow_display(window);                                     
        }                                                                     
        sfRenderWindow_destroy(window);                                        
        return (0);                                                            
     }
    Je vous remercie à tous d'avoir pris le temps de me lire, et merci d'avance à ceux qui ont le courage de m'aider.

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Tu ne vérifies pas le retour de tes fonctions d'allocation. Les variables que tu utilises pointent-elles vers des objets valides ?

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Par défaut
    Bonjour et merci de ton aide. Il est vrai que je ne vérifie pas mes malloc, c'est un réflexe qu'il faut que je prenne. En revanche, je ne pense pas que mon segfault vienne de là.

    Qu'entend tu par "pointer sur des objets valides" ? Si tu as un exemple dans mon code, je pourrais mieux te répondre. Si tu parles des structures comme framebuffer, oui je les ai déclarés et ils existent.

  4. #4
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Citation Envoyé par Badfly Voir le message
    je ne pense pas que mon segfault vienne de là.
    Base-toi sur des faits pour traquer un bug, pas sur des suppositions. Tu n'es à l'abri ni de tes propres défaillances d'analyse, ni d'un bug de l'implémentation de la bibliothèque que tu utilises, de ton compilateur, voire même de ton processeur (dans un ordre de plausibilité décroissant).

    En l'occurrence, tu ne vérifies la validité ni de framebuffer, ni de texture avant de les utiliser. Rien ne permet donc d'affirmer que les objets vers lesquels ces variables pointent ont été créés et initialisés avec succès. Sans plus de détail concernant les fonctions *_create, j'imagine qu'elles retournent NULL en cas d'erreur ? Vérifies déjà cela, c'est fait en quinze secondes.

  5. #5
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Base-toi sur des faits pour traquer un bug, pas sur des suppositions. Tu n'es à l'abri ni de tes propres défaillances d'analyse, ni d'un bug de l'implémentation de la bibliothèque que tu utilises, de ton compilateur, voire même de ton processeur (dans un ordre de plausibilité décroissant).

    En l'occurrence, tu ne vérifies la validité ni de framebuffer, ni de texture avant de les utiliser. Rien ne permet donc d'affirmer que les objets vers lesquels ces variables pointent ont été créés et initialisés avec succès. Sans plus de détail concernant les fonctions *_create, j'imagine qu'elles retournent NULL en cas d'erreur ? Vérifies déjà cela, c'est fait en quinze secondes.
    +1 sur la réponse de Matt_Houston:

    1) Ajoute les tests sur le retour de toutes les fonctions, c'est rapidement fait et cela enlévera beaucoup de questions

    Tu dis que ceci est la source de l'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        sfTexture_updateFromPixels(texture, framebuffer->pixels, framebuffer->width, framebuffer->height, 0, 0);
    Tu as donc quatre catégories d'erreurs pour ici:
    a) texture est NULL
    b) framebuffer est NULL
    c) texture ou framebuffer doivent être initialisées, préparées, etc. avant l'appel (donc tu manques un appel ou deux pour texture / framebuffer) -> cherche d'autres exemples d'utilisation de la fonction
    d) SFML a besoin d'autres appels pour s'initialiser (différent que (c) puisque c'est la librairie qui requiert plus d'appels et pas juste à propos de texture/framebuffer)

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Par défaut
    Pour commencer, merci à tous de vos réponses

    Alors pour en revenir au programme : j'ai vérifié mes appels des fonctions. Je vous remet donc mon code, avec les modifications apportés.
    De plus, je vous rajoute la fonction que j'utilise pour initialiser mon buffer, et la structure de ce dernier.

    Pour les fonctions qui pourraient manquer, au stade où j'en suis je ne vois pas ce que j'ai oublié

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
     
    typedef struct         s_my_framebuffer                                                      
    {                                                                                             
                 sfUint8      *pixels;                                                               
                 int             width;                                                                
                 int             height;                                                               
    }                             t_my_framebuffer;                                                     
     
     
    t_my_framebuffer*       my_framebuffer_create(int width, int height)                          
    {                                                                                             
      t_my_framebuffer      *framebuffer;                                                         
     
      if ((framebuffer = malloc(sizeof(t_my_framebuffer))) == NULL)                               
         return (NULL);                                                                            
      if ((framebuffer->pixels = malloc((sizeof(sfUint8)) * (width * height))) == NULL)           
         return (NULL);                                                                            
      framebuffer->width = width;                                                                 
      framebuffer->height = height;                                                               
      return (framebuffer);                                                                       
    }                   
     
    int                     main(int argc, char **argv)                                           
    {                                                                                             
      sfVideoMode           mode;                                                                 
      sfRenderWindow*       window;                                                               
      t_my_framebuffer*     framebuffer;                                                          
      sfTexture*            texture;                                                              
      sfColor               color;                                                         
     
      mode.width = 1000;                                                                          
      mode.height = 1000;                                                                         
      window = sfRenderWindow_create(mode, "SFML window", sfResize | sfClose, NULL);              
      if (window == NULL)                                                                         
      return (-1);                                                                              
      if ((framebuffer = my_framebuffer_create(1000,1000)) == NULL)                               
        return (-1);                                                                              
      if ((texture = sfTexture_create(1000, 1000)) == NULL)                                       
        return (-1);                                                                              
      sfTexture_updateFromPixels(texture, framebuffer->pixels, framebuffer->width, framebuffer->height, 0, 0);                                                                                 
      while(42)                                                                                   
        {
          sfRenderWindow_display(window);                                                          
        }                                                                                          
     sfRenderWindow_destroy(window);                                                             
     return (0);                                                                                 
    }

  7. #7
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Ton framebuffer n'est-il pas trop petit ? Tel que tu l'alloues ici, tu ne réserves que 8 bits par pixel. C'est, comment dire.. peu. Il y a de fortes chances que cela ne corresponde pas au format de pixel attendu par la fonction en cause. Lis-bien la documentation associée.

    Accessoirement, ligne 18 tu renvoies NULL lorsque la seconde allocation échoue. C'est bien, mais vu que la première allocation a réussi tu as une fuite mémoire dans ce cas. Même dans les cas d'erreur il convient de terminer proprement : pense à faire un free sur la structure.

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Ton framebuffer n'est-il pas trop petit ? Tel que tu l'alloues ici, tu ne réserves que 8 bits par pixel. C'est, comment dire.. peu. Il y a de fortes chances que cela ne corresponde pas au format de pixel attendu par la fonction en cause. Lis-bien la documentation associée.
    Tu pourrais m'expliquer comment tu arrives à calculer que c'est 8 bits par pixel ? J'avoue que je comprend pas trop. Je ne vois pas comment malloc autrement pour être franc. Et par conséquent comment allouer plus ou moins ? Car j'ai prix les dimension du tableau, j'ai pas réfléchis aux nombres de bits par pixels :'(

  9. #9
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Certainement, je développe : tu alloues width * height * sizeof(sfUint8) octets (ou bytes). width * height étant le nombre de pixels de l'image, il te reste donc sizeof(sfUint8) octets pour stocker les informations de couleur associées à chaque pixel. Or, à moins d'une nomenclature particulièrement vicelarde, sfUint8 est plus que probablement un typedef sur un entier non signé codé sur 8 bits.

    Il est également très peu probable que la bibliothèque alloue un format de pixel exotique du style RRGGGBBA sur 8 bits par défaut pour les textures. Ce doit être du RGBA 32 bits ou du RGB 24 bits, à voir ce qui est précisé dans la doc (il doit y avoir un champ qui précise le format dans la structure de texture).

    Ton buffer source est donc trois à quatre fois trop petit.

  10. #10
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Et normalement, il y a une fonction dédiée dans la SFML. J'en déduis qu'il y en a une dans la CSFML.

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2016
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2016
    Messages : 5
    Par défaut
    Merci Matt je comprend le raisonnement. J'ai mallocs le tableaux de pixels avec sizeof(sfUint8), car c'est le type du tableau. J'ai regarder la doc que j'ai sur les Textures et il n'y a pas de référecence à la taille d'un pixel.

    En revanche en relisant attentivement, j'ai peu etre trouvé quelque chose en rapport. sfVideoMode il y'a dans cette structure un champs bitsPerPixels que je ne remplis pas. J'ai donc modifié ça et ai ajouté mode.bitsPerPixels = 32;
    (Sur la doc de mon école, il est bien indiquer 32, je suppose donc qu'il faut plus que 8 bits par pixels, et donc augmenter la taille de mon buffer à 32. Le raisonnement est juste ?

    Du coup j'ai essayé, et j'ai modifié ma fonction de malloc, et faisant un malloc sur (sizeof(32)) * (width * height)
    Et bah ça marche Mais je suppose qu'il y a sans doute un moyen de faire autrement qu'en mettant ' 32 ' en dur ?

    Sinon merci à tous pour vos réponses, ça m'a aidé à trouver le problème. Merci à tous !

  12. #12
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Attention à la confusion entre bit et byte (octet, en anglais). Un format de pixel est le plus souvent exprimé en nombre de bits par pixels, mais malloc attend un nombre de.. bytes.

    D'autre part attention aux erreurs dûes à une méconnaissance des structures du langage. sizeof(32) revient à évaluer la taille du type de l'expression 32, soit int. Bon, il se trouve que c'est ici équivalent puisqu'un int est la plupart du temps codé sur 32 bits mais c'est un vieux coup de bol. En C tu ne peux pas t'en sortir en essayant des trucs, ça aura peut-être l'air de fonctionner mais le langage finira te punir comme un malpropre.

    La solution robuste est de stocker le bpp (bits per pixel, la taille du format de pixel) dans ta structure d'image comme le fait SFML et de le faire correspondre à celui de l'objet de destination : tu rencontreras les mêmes soucis si pour une raison quelconque le format de texture change (image sans canal alpha, par exemple).

Discussions similaires

  1. VC++ Direct3D8, problème avec LPD3DXFONT et LPD3DTEXTURE8
    Par Magus (Dave) dans le forum DirectX
    Réponses: 3
    Dernier message: 03/08/2002, 11h10
  2. Problème avec [b]struct[/b]
    Par Bouziane Abderraouf dans le forum CORBA
    Réponses: 2
    Dernier message: 17/07/2002, 10h25
  3. Problème avec le type 'Corba::Any_out'
    Par Steven dans le forum CORBA
    Réponses: 2
    Dernier message: 14/07/2002, 18h48
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo