Précédent   Forum du club des développeurs et IT Pro > Applications > Développement 2D, 3D et Jeux > API graphiques > SFML
SFML Forum d'entraide sur l'API SFML
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 18/10/2012, 14h28   #1
DakM
Membre du Club
 
Homme nico
Second de cuisine
Inscription : avril 2005
Messages : 143
Détails du profil
Informations personnelles :
Nom : Homme nico
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Second de cuisine
Secteur : Alimentation

Informations forums :
Inscription : avril 2005
Messages : 143
Points : 42
Points : 42
Envoyer un message via MSN à DakM Envoyer un message via Skype™ à DakM
Par défaut ecran blanc & loadFromMemory

Bonjour,

j'essaye de precharger des textures en memoire, pour un chargement plus dynamique.
Voici ma classe qui va garder tout en memoire...
Code cpp :
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 
class Memory
{
	public:
		Memory() {};
		~Memory()
		{
		    std::cout << "Call ~Memory() " << std::endl;
		}
 
        /// Pas important.
		void preload(const std::string& pack)
		{
		    Reader* own_reader = new Reader();
		    Node* child = own_reader->Read(pack);
 
		    m_nodes.insert(std::make_pair(Filesystem::extractFilename(pack),
                                    std::make_pair(own_reader, child)));
		}
 
        /// Ceci, marche a merveille ! Aucune exception levée
		void loadGFX(const std::string& pack, const long id)
		{
		    try
		    {
		        Node& node(m_nodes[pack].second->find(id));
		        MemoryRessource<sf::Texture>* res = new MemoryRessource<sf::Texture>(node.get(m_nodes[pack].first->stream()));
                m_loaded_gfx.insert(std::make_pair(MemoryKey(node.getId(), node.getOffset()), res));
		    }
		    catch(...)
		    {
		        throw false;
		    }
		}
 
 
		Node& operator [] (const std::string& key) { return *(m_nodes[key].second); }
        Node& operator [] (const char* key) { return *(m_nodes[std::string(key)].second); }
 
		inline bool isLoaded(const MemoryKey& key) { return m_loaded_gfx.find(key) != m_loaded_gfx.end(); }
 
        template<class S>
		static inline S& getGFX(const long id) /// longer to perform ...!
		{
		    std::for_each(std::begin(m_loaded_gfx), std::end(m_loaded_gfx), [&](std::pair<MemoryKey, MemoryRessource<sf::Texture>*> res)
            {
                if(res.first.first == id) { return res.second->get(); }
            });
		}
 
        /// Retournera un sf::Texture
        template<class S>
		static inline S& getGFX(const MemoryKey& key)
		{
		    return m_loaded_gfx[key]->get();
		}
 
	private:
 
		static std::map<std::string, std::pair<Reader*, Node*>> m_nodes;
 
		static std::map<MemoryKey, MemoryRessource<sf::Texture>*> m_loaded_gfx;
};

En premier, je fais un void preload(), pas important, cela va remplir le membre m_nodes.
Ensuite, je vais faire loadGFX() avec un identifiant. Cela va charger une sf::Texture dans m_loaded_gfx.
Voici la classe MemoryRessource:

Code cpp :
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
 
template<class S>
class MemoryRessource
{
public:
    MemoryRessource() {}
    MemoryRessource(const std::vector<char>& bytes) :
        m_buffer()
        {
            if(!m_buffer.loadFromMemory(&bytes[0], bytes.size()))
            {
                std::cout << "Failed to load from memory ! " << std::endl;
                throw false;
            }
            else
            {
                std::cout << "Loaded " << bytes.size() << std::endl;
            }
        }
    ~MemoryRessource()
    {
        std::cout << "Destroying !"<<std::endl;
    }
 
    inline const S& get() const { return m_buffer; }
private:
    S m_buffer;
};

On remarquera que si le loadFromMemory est mauvais, une exception est levée, et attrapée dans loadGFX.
Jusqu'ici , tout va bien.
Voici maintenant le main :

Code cpp :
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
short SplashScreen::Run()
{
 
 
    /// Preloading archives
    std::for_each(std::begin(Config::ARCHIVES), std::end(Config::ARCHIVES), [&](const std::string& pack)
    {
        std::string full_name = pack;
        full_name += Config::EXT;
        m_game.getMemory().preload(full_name); // Tout va bien ...
    });
 
    Memory mem;
 
    Node& gfx(mem["Graphics"]);
 
    std::vector<long> ids_to_load = {2, 5};
 
    std::for_each(std::begin(ids_to_load), std::end(ids_to_load), [&](long id)
    {
        try
        {
            mem.loadGFX("Graphics", id);
        }
        catch(...)
        {
            std::cout << "Could not load: " << "Graphics:" << id << std::endl;
        }
    });
/// Aucune exception levée, nous avons donc nos sf::Texture chargés en mémoire
 
    std::cout << "loading texture into sprite ......."<<std::endl;
    sf::Sprite s_sprite(mem.getGFX<sf::Texture>(static_cast<long>(2)));
    std::cout << "OK loaded"<<std::endl;
 
 
    /// Rendering loop
    while(m_game.getRenderer().getApp().isOpen() && m_game.isRunning())
    {
        /// Clearing the window
        m_game.getRenderer().getApp().clear();
        sf::Event event;
 
        while(m_game.getRenderer().getApp().pollEvent(event))
        {
            /// Event handling
 
                /// SFML
            if(event.type == sf::Event::Closed)
            {
                /// This will automatically terminate the networker thread & nicely exit the game
                m_game.crash();
            }
        }
 
        /// Drawings (SFML)
            /// The sprite (background)
        m_game.getRenderer().getApp().draw(s_sprite);
 
        /// Displayings
        m_game.getRenderer().getApp().display();
 
    }
 
    return -1;
}

Bref, aucune erreur d'affichée malgrès les nombreuses conditions et try{}, pourtant: écran blanc

Une idée quelqu'un ?

Merci d'avance, nico
DakM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 18/10/2012, 23h57   #2
DakM
Membre du Club
 
Homme nico
Second de cuisine
Inscription : avril 2005
Messages : 143
Détails du profil
Informations personnelles :
Nom : Homme nico
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Second de cuisine
Secteur : Alimentation

Informations forums :
Inscription : avril 2005
Messages : 143
Points : 42
Points : 42
Envoyer un message via MSN à DakM Envoyer un message via Skype™ à DakM
Le probleme vient de std::for_each() dans la fonction find(long id)

cet algorithme ne prend pas en compte "return" (ligne 45), du coup, la fonction retournait une texture vide !
DakM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/10/2012, 15h47   #3
DakM
Membre du Club
 
Homme nico
Second de cuisine
Inscription : avril 2005
Messages : 143
Détails du profil
Informations personnelles :
Nom : Homme nico
Localisation : France, Paris (Île de France)

Informations professionnelles :
Activité : Second de cuisine
Secteur : Alimentation

Informations forums :
Inscription : avril 2005
Messages : 143
Points : 42
Points : 42
Envoyer un message via MSN à DakM Envoyer un message via Skype™ à DakM
Petit changement.... Maintenant j'ai un écran noir :/

Voici, la boucle principale:

Code cpp :
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
short SplashScreen::Run()
{
 
    sf::Sprite splash_screen;
 
    bool connect_attempt = false, splash_load = false;
 
    /// Running loading thread
    m_game.runPreloader();
 
    /// Rendering loop
    while(m_game.getRenderer().getApp().isOpen() && m_game.isRunning())
    {
        /// Clearing the window
        m_game.getRenderer().getApp().clear();
        sf::Event event;
 
        while(m_game.getRenderer().getApp().pollEvent(event))
        {
            /// Event handling
                /// SFGUI
            m_desktop.HandleEvent(event);
                /// SFML
            if(event.type == sf::Event::Closed)
            {
                /// This will automatically terminate the networker thread & nicely exit the game
                m_game.crash();
            }
        }
 
        if(!splash_load)
        {
            try
            {
                Memory& memory(m_game.getMemory());
                splash_screen.setTexture(memory.getTexture(static_cast<long>(5)));
                splash_load = true;
 
                std::cout << "Set Texture!"<<std::endl;
            }
            catch(bool)
            {
                std::cout << "Failed to set texture"<<std::endl;
            }
 
        }
 
        /// Drawings (SFML)
            /// The sprite (background)
        if(splash_load)
        {
            m_game.getRenderer().getApp().draw(splash_screen);
        }
        m_game.getRenderer().getApp().resetGLStates();
 
        /// Displayings
        m_desktop.Update(0.f);
        m_game.getRenderer().display(m_game.getRenderer().getApp());
        m_game.getRenderer().getApp().display();
    }
 
    return -1;
}

La fonction m_game.runPreloader(); va precharger les images dans l'instance de m_game.getMemory().

Ensuite, voici le header de la classe Memory:
Code cpp :
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
typedef std::pair<long, long> MemoryKey;
                // ID, Offset
template<class S>
class MemoryRessource
{
public:
    MemoryRessource() {}
    MemoryRessource(const std::vector<char>& bytes) :
        m_buffer()
        {
            if(!m_buffer.loadFromMemory(&bytes[0], bytes.size()))
            {
                std::cout << "Failed to load from memory ! " << std::endl;
                throw false;
            }
            else
            {
                std::cout << "loadFromMemory: OK. @ address: " << &m_buffer << std::endl;
            }
        }
    ~MemoryRessource()
    {
        std::cout << "Destroying !"<<std::endl;
    }
 
    inline S& get() {
        std::cout << "Get texture (width=" << m_buffer.getSize().x << "; height=" << m_buffer.getSize().y << ")" << std::endl;
        return m_buffer;
        }
private:
    S m_buffer;
};
 
class Memory
{
	public:
		Memory() :
		    m_nodes(),
		    m_loaded_gfx(),
		    m_mtx_loader(PTHREAD_MUTEX_INITIALIZER),
		    m_percent(0)
            {}
		~Memory()
		{
		    std::cout << "Call ~Memory() " << std::endl;
		}
 
		void loadPackage(const std::string& pack)
		{
		    Reader* own_reader = new Reader();
		    Node* child = own_reader->Read(pack);
 
		    m_nodes.insert(std::make_pair(Filesystem::extractFilename(pack),
                                    std::make_pair(own_reader, child)));
		}
 
		void loadGraphic(const long id)
		{
            try
            {
                Node& node(m_nodes[m_graphicPackage].second->find(id));
                MemoryRessource<sf::Texture>* res = new MemoryRessource<sf::Texture>(node.get(m_nodes[m_graphicPackage].first->stream()));
                m_loaded_gfx.insert(std::make_pair(MemoryKey(node.getId(), node.getOffset()), res));
            }
            catch(bool)
            {
                throw false;
            }
        }
 
        Node& operator[] (const std::string& key) { return *(m_nodes[key].second); }
 
        inline sf::Texture& getTexture(const MemoryKey& key) { return m_loaded_gfx[key]->get(); }
        inline sf::Texture& getTexture(const long key)
        {
            for(auto& res : m_loaded_gfx)
            {
                if(res.first.first == key)
                {
                    return res.second->get();
                }
            }
            /// In case we didn't found id... !
            throw false;
        }
 
 
 
		inline bool isLoaded(const MemoryKey& key) { return m_loaded_gfx.find(key) != m_loaded_gfx.end(); }
		inline pthread_mutex_t* getMutex() { return &m_mtx_loader; }
		inline long& getPercent() { return m_percent; }
 
	private:
 
		std::map<std::string, std::pair<Reader*, Node*>> m_nodes;
 
		std::map<MemoryKey, MemoryRessource<sf::Texture>*> m_loaded_gfx;
 
		pthread_mutex_t m_mtx_loader;
		long m_percent;
		const std::string m_graphicPackage = "Graphics";
};


Le chargement se passe bien.

En tout cas, voici le debug...:


Le truc vraiment etrange, c'est que c'est la meme adresse apres chargement, et quand je tente d'y acceder.
De plus, la taille affichée sur la console est la bonne.


De plus:

Dans le getter de MemoryRessource,
j'ai ajotué:
m_buffer.copyToImage().saveToFile("test.jpg");
-> Image noire..... Problème !!

Ensuite j'ai remonté un peu, j'ai mis la meme chose dans le constructeur !
-> Bonne image, et en plus, l'image s'affiche à l'écran !

Je comprend plus rien maintenant


Une idée d'où vient le probleme ?

merci, nico
DakM est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 10h26.


 
 
 
 
Partenaires

Hébergement Web