Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Problème de carré blanc N°526368252  (Lu 956 fois)

0 Membres et 1 Invité sur ce sujet

LeFanDOst

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
    • E-mail
Problème de carré blanc N°526368252
« le: Juin 12, 2021, 01:36:32 pm »
Bonjour,
        je suis actuellement en train de développer un RPG. Afin de faciliter une partie de ma conception, j'ai pris le parti de créer une classe "Image" et, bien que celle-ci ne soit pas optimale, surtout au vu de ce que j'ai pu lire en parcourant le forum, elle correspond pour le moment à mes besoins. Elle sera probablement repensée plus tard, par souci d'économie de ressources et de temps de calcul.

        Pour cette classe, je m'occupe de l'affichage dans une méthode appelée "dessiner", prenant en paramètre une référence sur une sf::RenderWindow. Une texture et un sprite sont localement créés et dessinés sur la fenêtre. Et, dans l'un des constructeurs, je souhaite récupérer la taille en pixel de l'image source. Lorsque j'essaie cela avec une texture locale au constructeur, j'ai un carré blanc. Lorsque j'essaie cela avec une texture qui est un attribut de la classe, j'ai également un carré blanc. J'ai besoin de la longueur et de la largeur de l'image affichée à l'écran pour certains calculs, que ce soit la taille de l'image source ou la taille spécifiée à la main.

        Je vous met un code minimal de cette classe ; imaginez-la avec tous les accesseurs liés à chaque attribut, getter comme setter, ainsi qu'un opérateur d'affectation. Cette version de la classe est dénuée de bugs.

Fichier d'en-tête, "Image.hpp" :

#ifndef DEF_IMAGE
#define DEF_IMAGE

#include "RichExcept.hpp"
#include <ostream>
#include <sstream>
#include <string>
#include <SFML/Graphics.hpp>

typedef unsigned int uint;

class Image
{
        public:
                Image(std::string cheminImage, int x, int y);
                Image(std::string cheminImage, int x, int y, uint longueur, uint largeur);
                Image(Image const& src);
                ~Image();

                void dessiner(sf::RenderWindow& fenetre) const;
               
                friend std::ostream& operator<<(std::ostream& os, Image const& src);
       
        private:
                std::string m_chemin;
                int m_x;
                int m_y;
                uint m_longueur;
                uint m_largeur;
       
        protected:
                void ecrire(std::ostream& os) const;
};

#endif // DEF_IMAGE
 

Fichier source, "Image.cpp" :
#include "../include/Image.hpp"

Image::Image(std::string cheminImage, int x, int y) : m_chemin(cheminImage), m_x(x), m_y(y), m_longueur(0), m_largeur(0) {}

Image::Image(std::string cheminImage, int x, int y, uint longueur, uint largeur) : m_chemin(cheminImage), m_x(x), m_y(y), m_longueur(longueur), m_largeur(largeur) {}

Image::Image(Image const& src) : Image(src.m_chemin, src.m_x, src.m_y, src.m_longueur, src.m_largeur) {}

Image::~Image() {}


void Image::dessiner(sf::RenderWindow& fenetre) const
{
        sf::Texture texture;
       
        if(!texture.loadFromFile(m_chemin, sf::IntRect(m_x, m_y, m_largeur, m_longueur)))
        {
                std::ostringstream ossErr;
               
                ossErr << "L'image dont le chemin est \"" << m_chemin << "\" n'a pas " << eAccAigu << "t" << eAccAigu << " trouv" << eAccAigu << "e.";
               
                throw _RichExcept(ossErr.str().c_str());
        }
       
        sf::Sprite sprite;
       
        sprite.setTexture(texture);
        sprite.setPosition(m_x, m_y);
       
        fenetre.draw(sprite);
}


std::ostream& operator<<(std::ostream& os, Image const& src)
{
        src.ecrire(os);
       
        return os;
}


void Image::ecrire(std::ostream& os) const
{
        os << m_chemin << " " << m_x << " " << m_y << " " << m_longueur << " " << m_largeur;
}
 

        Et voici l'une des versions du premier constructeur de la classe que j'ai écrite pour récupérer la longueur et la largeur de l'image et qui cause une erreur de carré blanc :

Image::Image(std::string cheminImage, int x, int y) : m_chemin(cheminImage), m_x(x), m_y(y), m_longueur(0), m_largeur(0)
{
        sf::Texture texture;
       
        if(!texture.loadFromFile(m_chemin, sf::IntRect(m_x, m_y, m_largeur, m_longueur)))
        {
                std::ostringstream ossErr;
               
                ossErr << "L'image dont le chemin est \"" << m_chemin << "\" n'a pas " << eAccAigu << "t" << eAccAigu << " trouv" << eAccAigu << "e.";
               
                throw _RichExcept(ossErr.str().c_str());
        }
       
        sf::Vector2u tailleImage = texture.getSize();
       
        m_longueur = tailleImage.x;
        m_largeur = tailleImage.y;
}
 

        J'imagine que l'erreur doit être très bête ou très basique, mais auriez-vous une piste à me proposer ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re: Problème de carré blanc N°526368252
« Réponse #1 le: Juin 13, 2021, 08:45:03 am »
OpenGL ne dessine pas tout de suite ce que tu envoies à fenetre.draw(...). Or tu détruis la texture immédiatement, donc elle ne sera plus disponible lorsqu'OpenGL en aura besoin.

Quelle idée saugrenue, de charger encore et encore la texture depuis le disque dur à chaque fois que tu en as besoin. Fais le une bonne fois pour toute et met-la de côté.
Laurent Gomila - SFML developer

LeFanDOst

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
    • E-mail
Re: Problème de carré blanc N°526368252
« Réponse #2 le: Juin 13, 2021, 02:03:34 pm »
        En effet, après modification du code source, il s'avère que cette solution est moins bien coûteuse en ressources. Également, après coup, je me suis rendu compte qu'il existait deux autres sources d'erreurs pour le même bug, que j'ai corrigé.

        Néanmoins, je vous remercie pour votre réponse.