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

Auteur Sujet: [Résolu] Optimisation d'affichage d'un sf::Text et Tableau de vertex  (Lu 2139 fois)

0 Membres et 1 Invité sur ce sujet

Skima

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Bonjour à tous,

Je suis entrain de créer une interface qui consiste à afficher des lettres et à changer leur couleur régulièrement (disons toutes les 120ms en moyenne).

J'avais tout d'abord réalisé mon interface en affichant un sf::RectangleShape et en ajoutant par dessus un sf::Text.

J'ai vite été limitée par ma carte graphique et mes changements de couleurs, qui étaient sensés être réguliers, devenaient aléatoires.

En me renseignant un peu plus, j'ai utilisé les tableaux de vertex (sf::VertexArray) pour dessiner mes rectangles de fond. Le problème a été réglé instantanément.
Par contre dès que j'essaye de remettre mon sf::Text par dessus, les bug reprennent.

J'ai cherché un moyen d'utiliser les vertex pour afficher des lettres, mais en vain.

Auriez-vous une idée de solution à ce problème ?

Merci d'avance :)
« Modifié: Mai 28, 2014, 02:00:48 pm par Skima »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Optimisation d'affichage d'un sf::Text et Tableau de vertex
« Réponse #1 le: Mai 12, 2014, 11:49:05 am »
Je te laisse potasser ceci, et notamment la fin ;)
Laurent Gomila - SFML developer

Skima

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Re : Optimisation d'affichage d'un sf::Text et Tableau de vertex
« Réponse #2 le: Mai 12, 2014, 12:00:55 pm »
Mmh, je ne vois pas ce que je peux ajouter, à part que j'utilise la version 2.1 de SFML sous windows.

Sinon, je n'ai pas de message d'erreur et si vous tenez à avoir un bout de code, voilà comment j'utilise les vertexarray :

void Key::print()
{

    sf::Color darkGrey(60, 60, 60);
    sf::Color grey(120, 120, 120);
    sf::Color silver(200, 200, 200);

    int shadowMove = 3;
    sf::VertexArray shadow(sf::Quads, 4);
    shadow[0].position = sf::Vector2f(x+shadowMove, y+shadowMove);
    shadow[1].position = sf::Vector2f(x+width+shadowMove, y+shadowMove);
    shadow[2].position = sf::Vector2f(x+width+shadowMove, y+height+shadowMove);
    shadow[3].position = sf::Vector2f(x+shadowMove, y+height+shadowMove);
    shadow[0].color = sf::Color::Black;
    shadow[1].color = darkGrey;
    shadow[2].color = darkGrey;
    shadow[3].color = darkGrey;

    keyboard->getWindow()->draw(shadow);

    sf::VertexArray border(sf::Quads, 4);
    border[0].position = sf::Vector2f(x, y);
    border[1].position = sf::Vector2f(x+width, y);
    border[2].position = sf::Vector2f(x+width, y+height);
    border[3].position = sf::Vector2f(x, y+height);
    border[0].color = grey;
    border[1].color = grey;
    border[2].color = grey;
    border[3].color = grey;

    keyboard->getWindow()->draw(border);

    sf::VertexArray rectangle(sf::Quads, 4);
    rectangle[0].position = sf::Vector2f(x+borderSize, y+borderSize);
    rectangle[1].position = sf::Vector2f(x+width-borderSize, y+borderSize);
    rectangle[2].position = sf::Vector2f(x+width-borderSize, y+height-borderSize);
    rectangle[3].position = sf::Vector2f(x+borderSize, y+height-borderSize);
    rectangle[0].color = silver;
    rectangle[1].color = silver;
    rectangle[2].color = silver;
    rectangle[3].color = silver;

    keyboard->getWindow()->draw(rectangle);
}
 

Et comment je faisais avant (avec le Text en plus) :
sf::RectangleShape rectangle;

    rectangle.setSize(sf::Vector2f(width-borderSize, height-borderSize));
    rectangle.setOutlineColor(grey);
    rectangle.setFillColor(silver);
    rectangle.setOutlineThickness(borderSize);
    rectangle.setPosition(x, y);

    keyboard->getWindow()->draw(rectangle);

    sf::Text text;

    sf::Font font;
    font.loadFromFile("arial.TTF");

    text.setFont(font);
    text.setString(value);
    text.setCharacterSize(fontSize);
    //text.setStyle(sf::Text::Bold);
    text.setColor(sf::Color::White);
    text.setPosition(x, y);
    text.move(15, 5);

    keyboard->getWindow()->draw(text);
 

Je ne vois pas ce que je peux ajouter de plus :/
Je suis désolée si mon poste ne convient pas, mais dans ce cas, dites-moi précisément ce que vous attendez ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32504
    • Voir le profil
    • SFML's website
    • E-mail
Re : Optimisation d'affichage d'un sf::Text et Tableau de vertex
« Réponse #3 le: Mai 12, 2014, 12:59:18 pm »
Citer
dites-moi précisément ce que vous attendez
Un code complet et minimal qui reproduit le problème. Le pourquoi et le comment sont suffisamment bien expliqués dans les règles ;)
Laurent Gomila - SFML developer

Skima

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Re : Optimisation d'affichage d'un sf::Text et Tableau de vertex
« Réponse #4 le: Mai 12, 2014, 01:39:54 pm »
Le problème est justement que je ne sais pas quoi utiliser comme objet, c'est pour cela que je n'avais pas mit de code.

Si besoin, voilà ma boucle d'affichage de la fenêtre :
while(window.isOpen())
        {
            //cout << "clock : " << clock.getElapsedTime().asMilliseconds() <<endl;
        window.clear(windowColor);

        // on inspecte tous les évènements de la fenêtre qui ont été émis depuis la précédente itération
        sf::Event event;
        while (window.pollEvent(event))
        {
            // évènement "fermeture demandée" : on ferme la fenêtre
            if (event.type == sf::Event::Closed)
                window.close();
        }
               
                // [...] D'autres traitement qui n'utilisent pas SFML
               
                //on verifie a chaque fois qu'il existe un prochain groupe a flasher
                if(numGroupEnCour < nbGroupSequence)
                {
            if(flagSequence == 0)//premier passage
                        {
                            //cout << "init premier passage" << endl;
                                flagSequence = 1;//On assure qu'on ne repasse pas a l'initialisation

                                //on initialise les variables de temps (allumer et eteind) pour la période du groupe, en cour de flash
                                time_on = lapsTime_on;
                                time_off = lapsTime_on + lapsTime_off;

                                //on récupère le premier groupe de lettre et on le met a l'état on
                                g = groupList[numGroupEnCour];

                                //Activation du flashage juste après
                                g->onGroup();

                                lastFlash = 1;
                        }
                        else if(clock.getElapsedTime().asMilliseconds() > time_on && lastFlash == 1)//si le chrono a dépassé le temps a "on" des lettres on les passes a off
                        {
                //cout << "passage Groupe a off" <<endl;
                                g->offGroup();

                                lastFlash = 0;
                        }
                        else if(clock.getElapsedTime().asMilliseconds() > time_off && lastFlash == 0)// si le chrono a dépassé le temps des lettres a off
                        {
                                //on initialise les prochains time a dépassé
                                time_on += lapsTime_off + lapsTime_on;
                                time_off += lapsTime_on + lapsTime_off;
                                g = groupList[numGroupEnCour];//On recupère le prochain group
                                numGroupEnCour++;//IMPORTANT : On incrémente en premier !

                                //Activation du flashage juste après
                                g->onGroup();

                                lastFlash = 1;
                        }
                        else if (lastFlash==1) {
                g->onGroup();
                        }
                        else if (lastFlash==0) {
                g->offGroup();
                        }

                }
                else// Si plus de group a flasher on réouvre la condition d'initialisation d'une nouvelle sequence et on restart le chrono qui défilera jusqu'a ce que le délai entre 2 flash sequence soit écoulé pour réouvrir la condition d'initialisation
                {
                    //cout << "reinit nouvelle sequence" <<endl;
            flagSequence = 0;
            delay = 1;
                        clock.restart();
                }

        // fin de la frame courante, affichage de tout ce qu'on a dessiné
        window.display();
        }

Les méthodes onGroup() et offGroup() appellent plusieurs fois (pour chaque lettre du groupe) la méthode print() décrite au post précédent.

Skima

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Re : Optimisation d'affichage d'un sf::Text et Tableau de vertex
« Réponse #5 le: Mai 13, 2014, 08:38:56 am »
Du coup, quelqu'un aurait-il une solution à mon problème ?
Comment puis-je afficher du texte, sans dépasser les capacité de la carte graphique et donc ralentir l’exécution ?

Skima

  • Newbie
  • *
  • Messages: 10
    • Voir le profil
Re : Optimisation d'affichage d'un sf::Text et Tableau de vertex
« Réponse #6 le: Mai 28, 2014, 01:59:57 pm »
Bon, j'ai finalement trouvé la solution à mon problème. Je la met ici, au cas où ça intéresserai quelqu'un :

Le problème d'affichage du texte vient du fait qu'on recrée l'objet sf::Text à chaque appel de la méthode "print()" (qui affiche les lettres).
La création de l'objet ralentit alors énormément l’exécution du script.

J'ai donc stocké l'objet sf::Text dans un attribut de ma classe pour uniquement ré indiquer sa couleur, sa taille et sa valeur.
L'affichage marche maintenant nickel ;)

Voilà, j'espère que ça pourra éviter à quelqu'un de chercher comme moi pendant plus d'une semaine ... :)