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

Auteur Sujet: [SFML 2.0] Chargement de sf::Texture  (Lu 11912 fois)

0 Membres et 1 Invité sur ce sujet

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #15 le: Avril 15, 2012, 08:10:35 pm »
Donc je dois mettre un mutex dans la boucle d'affichage précédé d'un setActive(false) pour bloquer quand je dessine dans un autre thread (ou met une image dans un sf::Texture).

Ce qui veut donc dire bloquer l'affichage pendant un temps non négligeable, j'ai peur qu'au fur et à mesure que les affichages deviendrons complexe, de perdre trop de fps.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #16 le: Avril 15, 2012, 08:24:04 pm »
Si tu dessines dans un thread autre que celui d'affichage, déjà il y a un problème. Parce que normalement, dessiner c'est de l'affichage :P

Ensuite pour charger une texture par exemple, tu n'as absolument pas besoin de la fenêtre sur laquelle tu es en train de dessiner dans un autre thread. Tu n'as en fait besoin de rien du tout, SFML gère en interne automatiquement la création / activation de contextes OpenGL quand il y en a besoin.

Quant au mutex, tu n'en as pas besoin non plus. Non pas que SFML soit thread-safe, loin de là, mais si tu ne fais pas de choses bizarres tu ne dois pas avoir besoin d'accéder à des ressources partagées.
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #17 le: Avril 15, 2012, 08:29:04 pm »
Sous Débian avec une carte graphique intel, je suis obligé d'activer le RenderWindow dans le thread quand je met une image dans un Texture sinon la texture est modifiée lors du draw(ma_texture) de la boucle d'affichage.

Or, si j'active le renderWindow dans deux thread, le programme plante.

Sinon, pour l'activation du renderWindow pour les draw, clear, display c'est juste pour les renderWindow? Je n'ai pas besoin de l'activé si je dessine sur un renderTexture?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #18 le: Avril 15, 2012, 08:35:16 pm »
Citer
Sous Débian avec une carte graphique intel, je suis obligé d'activer le RenderWindow dans le thread quand je met une image dans un Texture sinon la texture est modifiée lors du draw(ma_texture) de la boucle d'affichage.
Je veux bien un code complet minimal de ça, histoire de pouvoir creuser un peu.

Citer
Sinon, pour l'activation du renderWindow pour les draw, clear, display c'est juste pour les renderWindow? Je n'ai pas besoin de l'activé si je dessine sur un renderTexture?
Tu ne dois rien faire, ça fait tout seul ce que ça doit faire quand ça doit le faire :P
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #19 le: Avril 15, 2012, 08:41:39 pm »
.hpp
class Hevent
{
private:
bool Running;
sf::RenderWindow wind;
public:
void event();
void afficher();
Hevent();
~Hevent();
                Fenetre * mafenetre;
};
.cpp
void lance_afficher(void *data)
{

Hevent *hevent = static_cast<Hevent*>(data);
hevent->afficher();
}

Hevent::Hevent() : mafenetre(NULL), wind(500,500)
{
        wind.setActive(false);
sf::Thread Thread(&lance_afficher, this);
Thread.launch();
         Fenetre toto;//chargement de sf::Texture et autre
         mafenetre = &toto;
event();
Thread.wait();
}

Hevent::~Hevent()
{
}

void Hevent::event()
{
Running = true;
while (Running)
{
sf::Event Event;
while (wind.waitEvent(Event))
{
                              //traitement de l'évènement
}
}
}

void Hevent::afficher()
{
wind.setFramerateLimit(IMGPROSEC);
while(Running)
{
                 if(mafenetre != NULL)
                              wind.draw(mafenetre->getSprite());
//tous les wind.draw
wind.display();
}
}

Fenetre.hpp
class Fenetre
{
         sf::Texture text;
         public :
          Fenetre()
          {
                     text.loadFromFile("toto.png");
           }
           const sf::Sprite & getSprite(){ sf::Sprite toto(text); return toto;  };
}
« Modifié: Avril 15, 2012, 08:51:07 pm par Neckara »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #20 le: Avril 15, 2012, 10:06:28 pm »
J'insiste sur complet et minimal, c'est pas juste pour embêter les gens qu'on le demande ;)
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #21 le: Avril 16, 2012, 10:35:31 am »
#include <iostream>
#include <cstdlib>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>

//g++ toto.cpp -o exe -lsfml-graphics -lsfml-system

bool Running(true);
sf::Sprite * toto(NULL);
sf::RenderWindow app(sf::VideoMode(500, 500, 32), "titre", sf::Style::Titlebar | sf::Style::Close);

void lance_afficher(void *data)
{
       app.setActive(true);
        app.setFramerateLimit(60);

        while(Running)
        {
                app.clear();
                if(toto != NULL)
                            app.draw(*toto);
                app.display();
        }
}

int main()
{
    int i;
     /*
    app.setActive(true);
    sf::Texture img_toto;
    img_toto.loadFromFile("icone1.png");
    /**/

    app.setActive(false);
    void *data(NULL);
    sf::Thread Thread(&lance_afficher, data);
    Thread.launch();/**/
    sf::Texture img_toto;
    img_toto.loadFromFile("icone1.png");/**/
    sf::Sprite Stoto(img_toto);
    toto = &Stoto;
    std::cin >> i;
    Running = false;
    Thread.wait();
}
 

Voilà, je ne peux pas faire mieux
« Modifié: Avril 16, 2012, 10:38:21 am par Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #22 le: Avril 16, 2012, 11:25:08 am »
C'est impeccable, merci :)

Chez moi ça tourne impec, mais bon je suis sous Windows.

J'ai un peu retouché le code, voici la version que j'ai testée au cas où ça fasse une différence :
#include <SFML/Graphics.hpp>
#include <iostream>

bool running = true;
sf::Sprite sprite;

void lance_afficher(sf::RenderWindow* window)
{
    while (running)
    {
        window->clear();
        window->draw(sprite);
        window->display();
    }
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(500, 500, 32), "titre");
    window.setActive(false);

    sf::Thread Thread(&lance_afficher, &window);
    Thread.launch();

    sf::Image image;
    image.create(250, 250, sf::Color::Green);
    sf::Texture texture;
    texture.loadFromImage(image);
    sprite.setTexture(texture, true);

    while (running)
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                running = false;
        }
    }

    return 0;
}
 
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #23 le: Avril 16, 2012, 11:32:37 am »
Je ne sais pas si utiliser une sf::Image change vraiment quelque chose.

Mais il me semble avoir le même problème que sur le lien que vous m'aviez donné : https://github.com/SFML/SFML/issues/160

On rencontre ce problème sous Linux (ici Débian avec carte graphique intel)

Il y a une explication ici :
Citer
I tried to look for the problem a little bit further. Maybe you already know these things, but I'll post them in case you didn't.

The problem lies with the glBindTexture call in texture.Create.

This is only one part of the problem, something in window.Create makes this problem.
So I split up the Create function in two parts: one was executed before and one after the texture was loaded.

Window.Create contains this line: "myContext = priv::GlContext::New(settings, myImpl, mode.BitsPerPixel);".
If this line is executed after the texture has been created then it will not be drawn correctly.

Here the problem lies with the "context->Initialize();" function.
And the line were the problem lies is "SetActive(true);"

So window.myContext has to be active before the texture gets created.
This would mean that the problem lies with currentContext.
Je n'ai pas tout à fait tout compris, mais j'ai retenu qu'il faut charger l'image dans le sf::Texture quand le renderWindow est activé
« Modifié: Avril 16, 2012, 11:36:27 am par Neckara »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #24 le: Avril 16, 2012, 11:37:49 am »
Citer
Je ne sais pas si utiliser une sf::Image change vraiment quelque chose.
Oui on s'en fiche, c'était juste pour rendre le code indépendant de ressources externes. Comme ça n'importe qui peut le copier-coller et le tester directement.

Citer
Mais il me semble avoir le même problème que sur le lien que vous m'aviez donné : https://github.com/SFML/SFML/issues/160
Oui c'est fort possible, quoique là on aurait une nouvelle variante.

Citer
Je n'ai pas tout à fait tout compris, mais j'ai retenu qu'il faut charger l'image dans le sf::Texture quand le renderWindow est activé
Oui, et c'est là qu'est le bug : normalement SFML fait en sorte qu'il n'y ait pas besoin de faire ça.
Laurent Gomila - SFML developer

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #25 le: Avril 16, 2012, 11:39:13 am »
Est-ce que le fait d'ajouter cette ligne juste avant de charger la texture
sf::Context context;
y change quelque chose ?
Laurent Gomila - SFML developer

Neckara

  • Jr. Member
  • **
  • Messages: 77
    • Voir le profil
Re : [SFML 2.0] Chargement de sf::Texture
« Réponse #26 le: Avril 16, 2012, 11:52:30 am »
en mettant
sf::Context context;


Juste avant la création du sf::Texture, environ 1 coup sur 5 j'aurais l'image qui s'affiche correctement à part une petite bande noir en haut.
Sinon 4 fois sur 5, ça fait pareil qui si je mettait ce code juste avant le chargement de l'image : je vois des petits bout de mon écran par exemple, j'ai des bouts de ma "barre du bas", la barre de titre de ma fenêtre qui apparaissent dans ma fenetre.

C'est plus joli qu'avant (pixel aléatoire affiché) mais le problème persiste.