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

Auteur Sujet: [Résolu] Warning manipulation graphique dans un thread  (Lu 1549 fois)

0 Membres et 1 Invité sur ce sujet

Cerous

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
[Résolu] Warning manipulation graphique dans un thread
« le: Mai 22, 2014, 09:33:50 pm »
Bonjour ,
Je viens vous faire part de mon problème , j'ai voulu réaliser mon interface graphique , je n'ai pas eu de problèmes pour les boutons , je suis donc passer au champ de texte , j'ai donc décidé de réaliser le traitement de l'écriture dans un thread afin de ne pas ralentir le programme lorsque l'on doit écrire mais j'ai eu ce warning : "An internal OpenGL call failed in Font.cpp (486) : GL_INVALID_OPERATION , the specified operation is not allowed in the current state" malgré cette avertissement , cela fonctionne correctement , mais je prefere me debarasser du warning. J'ai donc fais des recherches sur google , et j'ai appris que cela venais du fais que je devais déclarer sf::Context pour faire une opération graphique dans un Thread. Malheureusement suite à ce rajout j'ai d'autre warning : "Failed to set pixel format for device context -- cannot create OpenGL context"
et "Failed to create an OpenGL context for this window"
Hélas je n'ai pas trouvé de solutions à ce probleme via google.

Voici le code de ma classe :

#include "Textfield.h"
namespace GUI{
Textfield::Textfield() : writeThread(&Textfield::keyListener,this)
{
    //ctor
    sf::Vector2f sizeBox(200.F,50.F);
    box = sf::RectangleShape(sizeBox);
    box.setPosition(100,0);
    box.setOrigin(0,0);
    cursor = sf::RectangleShape(sf::Vector2f(1,25));
    cursor.setOrigin(box.getOrigin());
    cursor.setPosition(box.getPosition().x+8,box.getPosition().y+12);
    cursor.setFillColor(sf::Color::White);
    initPosCursor = cursor.getPosition();
    if (!font.loadFromFile("arial.ttf"))
    {
        // erreur...
    }
    textDisplayed = sf::Text(this->text,font,20);
    textDisplayed.setOrigin(cursor.getOrigin());
    textDisplayed.setPosition(cursor.getPosition());
    texture.loadFromFile("data/images/gui/button2.png");
    texture.setSmooth(true);
    box.setTexture(&texture);
    focused = false;
    indexCursor = 0;
}

Textfield::~Textfield()
{
    //dtor
}

void Textfield::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
    target.draw(box,states);

    target.draw(textDisplayed,states);
    if(this->focused){
        target.draw(cursor,states);
        writeThread.launch();
    }
}

bool Textfield::isFocused(sf::Vector2i mousepos)
{
    if(sf::Mouse::isButtonPressed(sf::Mouse::Left) && box.getGlobalBounds().contains(mousepos.x,mousepos.y)){

        return focused = true;
    }
    else if(sf::Mouse::isButtonPressed(sf::Mouse::Left) && !box.getGlobalBounds().contains(mousepos.x,mousepos.y)){
        writeThread.terminate();
        return focused = false;
    }
}

void Textfield::keyListener()
{
    sf::Context context;
    int indexCursorOld = indexCursor;
        if(GUI::event.type == sf::Event::TextEntered){
            if(GUI::event.text.unicode == '\b'){
                if(text.getSize() > 0 && indexCursor != 0){
                    text.erase(indexCursor-1,1);
                    textDisplayed = sf::Text(this->text,font,20);
                    indexCursor--;
                }
                else if(text.getSize() > 0 && indexCursor == 0){
                    text.erase(0,1);
                    textDisplayed = sf::Text(this->text,font,20);
                }
            }
            else if(GUI::event.text.unicode == '\r'){

            }
            else if (GUI::event.text.unicode < 128){
                if(textDisplayed.getGlobalBounds().width < box.getGlobalBounds().width - 20){
                    text.insert(indexCursor,GUI::event.text.unicode);
                    textDisplayed = sf::Text(this->text,font,20);
                    indexCursor++;
                }
            }


                if(indexCursorOld != indexCursor){
                        sf::String temp = "";
                        for(int i = 0; i < indexCursor; i++){
                            temp += text[i];
                        }
                        sf::Text caractere = sf::Text(temp,font,20);
                    cursor.setPosition(initPosCursor.x+caractere.getGlobalBounds().width,initPosCursor.y);
                }


        }
        else if(GUI::event.type == sf::Event::KeyPressed ){
                sf::Text caractere;
            if(GUI::event.text.unicode == sf::Keyboard::Left && indexCursor > 0){
                indexCursor--;
                caractere = sf::Text(text[indexCursor],font,20);

            }
            else if(GUI::event.text.unicode == sf::Keyboard::Right && indexCursor < text.getSize()){
                caractere = sf::Text(text[indexCursor],font,20);
                indexCursor++;
            }
                int taille = caractere.getGlobalBounds().width;

                if(indexCursorOld < indexCursor){
                    cursor.move(taille,0);
                }
                else if(indexCursorOld > indexCursor){
                     cursor.move(-taille,0);
                }


        }


        textDisplayed.setPosition(initPosCursor.x,initPosCursor.y);
           // cursor.setPosition(initPosCursor.x+textDisplayed.getGlobalBounds().width,initPosCursor.y);


      // std::cout << text.toAnsiString()<< " " << indexCursor << std::endl;

}

sf::String Textfield::getText()
{
    return text;
}
}

 

#ifndef TEXTFIELD_H
#define TEXTFIELD_H
#include <SFML/Graphics.hpp>
#include <iostream>
#include "GUI.h"
#include <thread>
namespace GUI{
class Textfield : public sf::Drawable
{
    public:
        Textfield();
        virtual ~Textfield();
        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
        bool isFocused(sf::Vector2i mousepos);
        sf::String getText();
        void keyListener();
    protected:
    private:
    sf::String text;
    mutable sf::Font font;
    mutable sf::Text textDisplayed;
    sf::RectangleShape box;
    sf::Texture texture;
    sf::RectangleShape cursor;
    sf::Vector2f cursorPos;
    mutable sf::Thread writeThread;
    bool focused;
    sf::Vector2f initPosCursor;
    int indexCursor;

};
}
#endif // TEXTFIELD_H
 

Voilà je vous remercie d'avoir lu ce post.
« Modifié: Mai 22, 2014, 11:09:54 pm par Cerous »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Warning manipulation graphique dans un thread
« Réponse #1 le: Mai 22, 2014, 10:21:30 pm »
Désolé mais... quelle horreur !

N'utilise pas de thread comme ça, tu fonces droit dans le mur. Heureusement tu n'en as pas besoin ; qu'est-ce qui te fait croire que la fonction keyListener va prendre du temps ?
Laurent Gomila - SFML developer

Cerous

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
Re : Warning manipulation graphique dans un thread
« Réponse #2 le: Mai 22, 2014, 11:01:09 pm »
Merci de la réponse, c'est vrai qu'en y réflechissant les events ne sont pas bloquants comme par exemple la fonction std::cin qui attend la saisie de l'utilisateur , je sais pas ce qu'il m'est arrivé je me suis confus . En tout cas merci !
« Modifié: Mai 22, 2014, 11:14:50 pm par Cerous »