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

Auteur Sujet: [SFML 2] Surconsommation anormale du processeur  (Lu 2747 fois)

0 Membres et 1 Invité sur ce sujet

Nikogram

  • Newbie
  • *
  • Messages: 39
    • Voir le profil
    • E-mail
[SFML 2] Surconsommation anormale du processeur
« le: Mars 24, 2013, 04:06:53 pm »
Bonjour à tous.

Je viens encore vous voir car j'ai un petit souci de performance avec les sf::VertexArray.
Je tiens d'abord à préciser que j'utilise la SFML 2, et que le problème est présent quelque soit le PC.
Voici tout d'abord le code qui ne fonctionne pas :
for (int x = m_nombreBlocsCotes - 1; x >= 0; --x)
        for (int y = 0; y < m_nombreBlocsCotes; ++y)
                for (int z = 0; z < m_nombreBlocsHauteur; ++z)
                        if (x + y < m_nombreBlocsCotes && x + y >= 0 && !blocsAffiches[z][x][y + x])
                                m_blocsAffiches[z][x + y][y]->afficher(m_blocsAffiches, m_rendu, coordonneesPixelsBords);
for (int y = 0; y < m_nombreBlocsCotes; ++y)
        for (int x = 0; x < m_nombreBlocsCotes - y; ++x)
                for (int z = 0; z < m_nombreBlocsHauteur; ++z)
                        if (x + y < m_nombreBlocsCotes && x + y >= 0 && !blocsAffiches[z][x][y + x])
                                m_blocsAffiches[z][x][x + y]->afficher(m_blocsAffiches, m_rendu, coordonneesPixelsBords);
 

Après quelques tests j'ai trouvé que le problème venait des lignes "m_blocsAffiches[z][x + y]->afficher(m_blocsAffiches, m_rendu, coordonneesPixelsBords);" et "m_blocsAffiches[z][x + y][y]->afficher(m_blocsAffiches, m_rendu, coordonneesPixelsBords);", très souvent appelés. Si j'enlève ces lignes, plus de problème de performance.
Mais le plus étrange est que avec le code suivant, il n'y a pas de problème de performance alors que j'appelle la fonction afficher(m_blocsAffiches, m_rendu, coordonneesPixelsBords)  autant de fois que le code du dessus :
for (int z = 0; z < m_nombreBlocsHauteur; ++z)
      for (int x = 0; x < m_nombreBlocsCotes; ++x)
         for (int y = 0; y < m_nombreBlocsCotes; ++y)
            m_blocsAffiches[z][x][y]->afficher(m_blocsAffiches, m_rendu, coordonneesPixelsBords);

Voici le code de la fonction afficher() :
void Bloc::afficher(const std::vector<std::vector<std::vector<Bloc*>>>& blocs, sf::VertexArray& rendu, float coordonneesPixelsBords[4])
{
        // tests pour savoir si il faut afficher le bloc
        int nombreBlocsCotes = blocs[0].size();
        if (m_identifiant < 1 || m_coordonneesPixels.x <= coordonneesPixelsBords[0] || m_coordonneesPixels.x >= coordonneesPixelsBords[1] || m_coordonneesPixels.y <= coordonneesPixelsBords[2] || m_coordonneesPixels.y >= coordonneesPixelsBords[3])
                return;
        else
        {
                int coordonnneesOrigine[2] = {blocs[0][0][0]->m_coordonnees.x, blocs[0][0][0]->m_coordonnees.y};

                int nombreBlocsHauteur = blocs.size();
                bool blocsAffichesDevant[7];
                blocsAffichesDevant[0] = m_coordonnees.x != coordonnneesOrigine[0] && blocs[m_coordonnees.z][m_coordonnees.x - coordonnneesOrigine[0] - 1][m_coordonnees.y - coordonnneesOrigine[1]]->m_identifiant != 0;       // entité gauche (couche de l'entité)
                blocsAffichesDevant[1] = m_coordonnees.x != coordonnneesOrigine[0] && m_coordonnees.y != nombreBlocsCotes + coordonnneesOrigine[1] - 1 && blocs[m_coordonnees.z][m_coordonnees.x - coordonnneesOrigine[0] - 1][m_coordonnees.y - coordonnneesOrigine[1] + 1]->m_identifiant != 0;       // entité devant (couche de l'entité)
                blocsAffichesDevant[2] = m_coordonnees.y != nombreBlocsCotes + coordonnneesOrigine[1] - 1 && blocs[m_coordonnees.z][m_coordonnees.x - coordonnneesOrigine[0]][m_coordonnees.y - coordonnneesOrigine[1] + 1]->m_identifiant != 0;        // entité droite (couche de l'entité)
                blocsAffichesDevant[3] = m_coordonnees.z < nombreBlocsHauteur - 1 && m_coordonnees.x != coordonnneesOrigine[0] && blocs[m_coordonnees.z + 1][m_coordonnees.x - coordonnneesOrigine[0] - 1][m_coordonnees.y - coordonnneesOrigine[1]]->m_identifiant != 0;       // entité gauche (couche au dessus de l'entité)
                blocsAffichesDevant[4] = m_coordonnees.z < nombreBlocsHauteur - 1 && m_coordonnees.y != nombreBlocsCotes + coordonnneesOrigine[1] - 1 && blocs[m_coordonnees.z + 1][m_coordonnees.x - coordonnneesOrigine[0]][m_coordonnees.y - coordonnneesOrigine[1] + 1]->m_identifiant != 0;        // entité droite (couche au dessus de l'entité)
                blocsAffichesDevant[5] = m_coordonnees.z < nombreBlocsHauteur - 1 && blocs[m_coordonnees.z + 1][m_coordonnees.x - coordonnneesOrigine[0]][m_coordonnees.y - coordonnneesOrigine[1]]->m_identifiant != 0;        // entité dessus (couche au dessus de l'entité)
                blocsAffichesDevant[6] = m_coordonnees.z < nombreBlocsHauteur - 2 && blocs[m_coordonnees.z + 2][m_coordonnees.x - coordonnneesOrigine[0]][m_coordonnees.y - coordonnneesOrigine[1]]->m_identifiant != 0;        // entité dessus (couche encore au dessus de l'entité)
                if (((blocsAffichesDevant[0] && blocsAffichesDevant[2]) || blocsAffichesDevant[1]) && blocsAffichesDevant[3] && blocsAffichesDevant[4] && (blocsAffichesDevant[5] || blocsAffichesDevant[6]))
                        return;
        }

        // affichage du bloc
        for (int i = 0; i < 4; i++)
                rendu.append(m_textures.sommetTextureBloc(m_identifiant, i, m_coordonneesPixels));

        //affichage des lignes de séparation de blocs
        int coordonnneesOrigine[2] = {blocs[0][0][0]->m_coordonnees.x, blocs[0][0][0]->m_coordonnees.y};
        int nombreBlocsHauteur = blocs.size();
        bool blocsAfficheesACote[9];
        blocsAfficheesACote[0] = m_coordonnees.y == coordonnneesOrigine[1] || blocs[m_coordonnees.z][m_coordonnees.x - coordonnneesOrigine[0]][m_coordonnees.y - coordonnneesOrigine[1] - 1]->m_identifiant != 0;       // bloc à gauche (derrière)
        blocsAfficheesACote[1] = m_coordonnees.x == nombreBlocsCotes + coordonnneesOrigine[0] - 1 || blocs[m_coordonnees.z][m_coordonnees.x - coordonnneesOrigine[0] + 1][m_coordonnees.y - coordonnneesOrigine[1]]->m_identifiant != 0;        // bloc à droite (derrière)
        blocsAfficheesACote[2] = m_coordonnees.z > 0 && blocs[m_coordonnees.z - 1][m_coordonnees.x - coordonnneesOrigine[0]][m_coordonnees.y - coordonnneesOrigine[1]]->m_identifiant != 0;     // bloc en bas
        blocsAfficheesACote[3] = m_coordonnees.z > 0 && m_coordonnees.x != coordonnneesOrigine[0] && blocs[m_coordonnees.z - 1][m_coordonnees.x - coordonnneesOrigine[0] - 1][m_coordonnees.y - coordonnneesOrigine[1]]->m_identifiant != 0;    // bloc en bas à gauche
        blocsAfficheesACote[4] = m_coordonnees.z > 0 && m_coordonnees.y != nombreBlocsCotes + coordonnneesOrigine[1] - 1 && blocs[m_coordonnees.z - 1][m_coordonnees.x - coordonnneesOrigine[0]][m_coordonnees.y - coordonnneesOrigine[1] + 1]->m_identifiant != 0;     // bloc en bas à droite
        blocsAfficheesACote[5] = m_coordonnees.x == coordonnneesOrigine[0] || m_coordonnees.y == coordonnneesOrigine[1] || blocs[m_coordonnees.z][m_coordonnees.x - coordonnneesOrigine[0] - 1][m_coordonnees.y - coordonnneesOrigine[1] - 1]->m_identifiant != 0;      // bloc à gauche
        blocsAfficheesACote[6] = m_coordonnees.x == nombreBlocsCotes + coordonnneesOrigine[0] - 1 || m_coordonnees.y == nombreBlocsCotes + coordonnneesOrigine[1] - 1 || blocs[m_coordonnees.z][m_coordonnees.x - coordonnneesOrigine[0] + 1][m_coordonnees.y - coordonnneesOrigine[1] + 1]->m_identifiant != 0;        // bloc à droite
        blocsAfficheesACote[7] = m_coordonnees.z < nombreBlocsHauteur - 1 && m_coordonnees.y != coordonnneesOrigine[1] && blocs[m_coordonnees.z + 1][m_coordonnees.x - coordonnneesOrigine[0]][m_coordonnees.y - coordonnneesOrigine[1] - 1]->m_identifiant != 0;       // bloc en bas à gauche
        blocsAfficheesACote[8] = m_coordonnees.z < nombreBlocsHauteur - 1 && m_coordonnees.x != nombreBlocsCotes + coordonnneesOrigine[0] - 1 && blocs[m_coordonnees.z + 1][m_coordonnees.x - coordonnneesOrigine[0] + 1][m_coordonnees.y - coordonnneesOrigine[1]]->m_identifiant != 0;        // bloc en bas à droite
        bool afficherLigne[6] = {!blocsAfficheesACote[0] && !blocsAfficheesACote[7], !blocsAfficheesACote[1] && !blocsAfficheesACote[8], !blocsAfficheesACote[0] && !blocsAfficheesACote[5], !blocsAfficheesACote[1] && !blocsAfficheesACote[6], !blocsAfficheesACote[2] && !blocsAfficheesACote[3], !blocsAfficheesACote[2] && !blocsAfficheesACote[4]};

        if (afficherLigne[0] || afficherLigne[1] || afficherLigne[2] || afficherLigne[3] || afficherLigne[4] || afficherLigne[5])
                for (int i = 0; i < 6; i++)
                        if (afficherLigne[i])
                                for (int j = 0; j < (i == 2 || i == 3 ? 4 : 12); ++j)
                                        rendu.append(m_textures.sommetTextureLimitesBloc(m_identifiant, i, j, m_coordonneesPixels));
}

Après quelques tests j'ai vu que le problème venait de la fonction rendu.append() appelée deux fois dans cette fonction. Le problème ne semble pas venir des fonctions sommetTextureLimitesBloc et sommetTextureBloc car j'ai envoyé un sf::VErtex vide à la place et y a toujours le même souci de performance.

Voyez-vous d'où pourrait venir ce problème assez étrange ?
Merci d'avance.
« Modifié: Mars 30, 2013, 08:46:59 pm par Laurent »

Nikogram

  • Newbie
  • *
  • Messages: 39
    • Voir le profil
    • E-mail
Re : [SFML 2] Surconsommation anormale du processeur
« Réponse #1 le: Mars 30, 2013, 08:31:48 pm »
Si jamais vous voulez plus d'information sur quoi que ce soit, demandez.

Autrement si vous ne voyez pas d'où vient le problème, pourriez vous me dire comment gérer au mieux un VertexArray contenant beaucoup de Vertex ?
Pour le moment, ce que je fais c'est, à chaque tour de boucle, de vider le VertexArray, puis de recréer tous les Vertex à afficher. Je fais ça car il y a très souvent des changements dans l'affichage. Par exemple des éléments sont à placer avant d'autres dans certains cas, des objets (des personnages pour mon jeu) peuvent arriver à tout moment, et être placer entre certaines autres textures en fonction de leur position.

Donc recréer tout à chaque fois puis effacer, ça doit surement demander beaucoup. Y aurait-il donc un moyen plus efficace pour gérer l'affichage de mes sprites ?

Merci d'avance.

Koryushin

  • Jr. Member
  • **
  • Messages: 93
    • Voir le profil
Re : [SFML 2] Surconsommation anormale du processeur
« Réponse #2 le: Mars 30, 2013, 11:39:32 pm »
Juste par curiosité as tu pensé à mettre un limiteur de FPS. J'entends par la qu'il ne sert a rien d'utiliser toute la charge UC pour juste afficher un sprite. Un mécanisme qui permet de mettre ton programme en pause en fonction du FPS désiré. Ca sert a rien d'avoir 1200 fps pour juste afficher quelques sprites ou autre. (l’œil humain ne fait pas la différence au delà d'un certain nombre de FPS. Pour ma part en dessous de 30 fps je ressent la différence)

En gros dans la boucle de rendu faire un pause en fonction du fps désiré. ça consiste à :
- Mesurer le temps écoulé dans la boucle de rendu.
- Si le temps écoulé est inférieur à 1/(FPS désiré) : faire une pause
                                                                          sinon on affiche le rendu

Y a un sujet intéressant sur le forum même s'il ne traite pas du même problème. Ca peut etre une piste pour toi http://fr.sfml-dev.org/forums/index.php?topic=10989.msg76028#new.

En espérant t'avoir aidé un peu.

Nikogram

  • Newbie
  • *
  • Messages: 39
    • Voir le profil
    • E-mail
Re : [SFML 2] Surconsommation anormale du processeur
« Réponse #3 le: Mars 31, 2013, 11:53:18 am »
D'abord merci pour ta réponse.
J'ai oublié de le préciser, mais en effet je limite les FPS de mon jeu, avec setFramerateLimit(60).