Bienvenue, Invité. Merci de vous connecter ou de vous inscrire. Avez-vous oublié d'activer ?

Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Messages - Suskive

Pages: [1]
1
Tu veux dire que normalement le FBO retourne la texture et que le display() permet de la remettre dans le bon sens?

Je vais regarder ça.

2
Ah, ça explique pas mal de chose, merci beaucoup j'ai l'impression de mieux cerner ce qui se passe.

Par contre pour sf::RenderTexture, ça ne bug pas pour moi. Au contraire!!! Je comprends le retournement de l'image lorsqu'on passe par un FBO. Mais si je ne fais pas appel à la fonction display(), l'image n'est pas retournée, moins de temps de calcul (la fonction sf::RenderTexture::display() coute un peu et je n'ai pas vu de différence dans le display() final) et surtout elle contient exactement ce que je voulais dessiner \o/
Donc je serais tenté de ne pas l'appeler, c'est pour ça que ta réponse sur les sf::RenderTexture ne me fait pas sentir son utilité.

3
Finalement je pense que c'est parce que je ne comprends pas exactement ce que fait la fonction display() que je n'arrive pas à optimiser mon code.

Si j'ai bien compris, quand j'effectue un window.display(), j'affiche à l'écran ce qui a été dessiné? Donc à priori la fonction window.display() devrait être constante par rapport au nombre de pixel à dessiner (correspondant à la taille de la fenêtre). Or son temps varie lorsque je fais un grand nombre de dessins (ils peuvent se superposer car il arrive que  je fasse plusieurs passe pour un rendu particulier).
Donc finalement la fonction draw met en mémoire les formes et la fonction display dessine tout? J'ai lu dans les forums qu'elle contenait la fonction glFLush() d'openGL. J'ai donc testé de mettre un glFlush() après un dessin, mais aucun changement (mauvaise configuration de ma part peut être).
Bref que fait la fonction display et comment dessiner pour être optimal?

J'ai aussi voulu tester les sf::RenderTexture car j'ai vu qu'il y avait la fonction sf::renderTexture::display(). Mais cette fonction semble n'avoir aucune incidence sur le window.display final. Et en plus l'image est retournée. Dans le code SFML j'ai pu lire que cette fonction devait être appelée pour éviter de laisser la texture dans un état indéfinie. Cela signifie quoi? cette fonction est elle vraiment indispensable? Y a t il des conséquences (performances / plantages) à ne pas l'utiliser?

ugo

4
Voilà j'ai installé à la maison Fraps et j'ai pu faire quelques tests.
Mon affichage du FPS donne les mêmes valeurs (à vu d'oeil) que Fraps.

Par contre je n'ai pas la même carte graphique qu'au boulot, c'est une AMD Radeon HD 6800.
Elle est plus puissante et le cas de cet après midi qui tournait autour de 30 FPS au boulot, se retrouve à 60 FPS chez moi. Puis au bout d'un moment la fonction display() n'est plus aussi gourmande et ça file à 145 FPS.

Comme tu me l'as demandé, j'ai fait un code minimal où je dessine un simple sf::CircleShape. J'y ai mi ma façon de calculer le FPS, ainsi que le temps moyen des parties dessin et display.
Chez moi, avec ma carte AMD, je tourne à 200FPS pendant un moment puis tout s'emballe et j'arrive à 2000+ FPS. En regardant le benchmark sous Fraps cela arrive après une vingtaine de secondes. Sur mon affichage console j'observe que le temps nécessaire pour la fonction display est de 4.5 msec, puis il tombe à 0.45 msec ce qui entraîne le pique de FPS.

ugo

#include <SFML/Graphics.hpp>
#include <iostream>

using namespace std;

int main()
{
    sf::RenderWindow window(sf::VideoMode(124*8, 124*8), "My window");


    // Création d'un cercle de rayon 500 pixel
    sf::CircleShape circle;
    circle.setRadius(500.0f);

    // Timers
    sf::Clock clock;
    float timerGlobal = 0.0f;   // Pour mesurer le temps d'une frame
    float timerDraw = 0.0f;     // Mesure du temps passé à dessiner
    float timerDisplay = 0.0f;  // Mesure du temps pour window.display()
    float t1,t2,t3,t4;          // Pour stocker le temps facilement
    unsigned nbFps = 0;         // Pour compter le nombre d'image par seconde

    ///////////////////////////////////////////////////////////////////////////////////////
    while (window.isOpen())
    {
            t1 = clock.getElapsedTime().asMilliseconds();   // on prend le temps en début de frame

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


            t2 = clock.getElapsedTime().asMilliseconds();

            ///////////////////////////////////////////////////////////////////
            // DESSIN
            window.clear();

            window.draw(circle);

            t3 = clock.getElapsedTime().asMilliseconds();
            timerDraw += t3 - t2;
            ///////////////////////////////////////////////////////////////////

            ///////////////////////////////////////////////////////////////////
            // DISPLAY
            window.display();

            t4 = clock.getElapsedTime().asMilliseconds() ;
            timerDisplay += t4 - t3;
            ///////////////////////////////////////////////////////////////////


            timerGlobal  += t4 - t1;    // ajout du temps de la frame (

            nbFps++;
            if(timerGlobal>1000.0f) // toutes les secondes on fait les comptes et on affiche les temps
            {
                cout << "FPS " << nbFps << '\n';
                cout << "draw " << timerDraw/static_cast<float>(nbFps) << '\n';
                cout << "display " << timerDisplay/static_cast<float>(nbFps) << "\n\n";

                nbFps = 0;          // reset des timers
                timerDraw = 0.0f;
                timerDisplay = 0.0f;

                timerGlobal -= 1000.0f ; // on garde ce qui dépasse de la seconde
                timerGlobal += (clock.getElapsedTime().asMilliseconds() - t4); // les sorties coutent , donc je les ajoute
            }

    } //Endwhile
    ///////////////////////////////////////////////////////////////////////////////////////

    return 0;
}

 

5
Ok donc je suis passé en dessin sur la fenêtre et j'ai retiré la texture.

Je tourne toujours autour des 30 FPS (avec ma méthode de mesure, pas les droits admin au boulot pour installer Fraps).
Le temps de calcul de la fonction window.draw(sf::VertexArray ...) est quasi nul, alors que celui du windows.display() est de l'ordre de 30 msec. Forcément il n'y a plus l'étape où je recopie la texture à l'écran.

En désactivant le dessin ça tourne à 1000 FPS.

ugo

6
A mince, j'ai lu de travers :D

Ok donc sans le dessin je suis proche des 400 FPS.
Par contre les chutes de performances avec le dessin se voient directement, la fenêtre est beaucoup moins fluide. Et dans les deux configurations.

Je vais cherche Fraps et tester pour avoir une mesure plus précise.

Sinon dans le code que j'ai posté il n'y a rien de choquant sur l'utilisation des vertexArrays et renderTexture?

ugo

7
Salut,

je dessine mes vertexArrays sur un sf::renderTexture, puis j'applique la texture résultante sur la fenêtre.

Les positions des vertexes et les couleurs sont initialisées dans la fonction "void initVertexArrays(...)".
Ce sont des carrés verts avec un coin en rouge pour faire classe :)

Pour le fps, j'utilise tout simplement un sf::clock et je prend le temps pour dessiner, puis celui pour faire le windows.display() sur une seconde. Et au bout d'une seconde j'affiche sur la console le temps moyen de ces deux étapes.
Je peux envoyer le code complet (130 lignes +ou-), là j'ai essayé de mettre un code minimal.

ugo




8
Salut,

en parcourant les forums j'ai souvent vu qu'il était préférable de limiter les appels de la fonctions "draw" en utilisant un vertexArray englobant un maximum d'objet.
J'ai donc fait un test où je dessine 100 fois un sf::Quad sur une texture, soit 100 appels à la fonction draw d'un renderTexture. Puis j'ai comparé avec un seul appel d'un vertexArray comprenant 100 fois le même sf::Quad.

Au final ça tourne à 30 FPS en moyenne dans les 2 cas et la majorité du temps est passé dans le window.display()  (même lorsque j'active le display() de renderTexture juste avant).
Je vous envoie un code simplifié de ce que je fais pour essayer de comprendre pourquoi je n'obtiens pas de meilleurs performances dans le cas où je ne fais qu'un seul appel à la fonction "draw".

Cordialement,
ugo

Je suis sous SFML 2.0 dernière version en release. Je possède une carte NVidia.


#include <SFML/Graphics.hpp>

void initVertexArrays(sf::VertexArray &bigVertex, sf::VertexArray &smallVertex, unsigned nbRect, sf::RenderWindow const& window);

int main()
{
    sf::RenderWindow window(sf::VideoMode(124*8, 124*8), "My window");

    sf::RenderTexture  renderTexture;
    renderTexture.create(window.getSize().x,window.getSize().y);

    unsigned int nbRect = 100;
    bool bigVertexEnable = false;       // pour afficher le gros vertex plutot que le petit :D
    bool textureDisplayEnable = false; // pour autoriser le display de la texture en plus de celui sur window

    sf::VertexArray bigVertex;                  // Vertex array contenant nbRect fois un carré
    bigVertex.setPrimitiveType(sf::Quads);
    bigVertex.resize(4*nbRect);

    sf::VertexArray smallVertex;                // Vertex array contenant seulement un carré, mais affiché nbRect fois
    smallVertex.setPrimitiveType(sf::Quads);
    smallVertex.resize(4);

    initVertexArrays(bigVertex, smallVertex,nbRect, window) ; // Initialisation des deux vertex

    ///////////////////////////////////////////////////////////////////////////////////////
    while (window.isOpen())
    {
            sf::Event event;
            while (window.pollEvent(event))
            {
                if (event.type == sf::Event::Closed) window.close();

                if(event.type == sf::Event::KeyPressed)
                {
                    if(event.key.code==sf::Keyboard::Space) bigVertexEnable = ! bigVertexEnable;                // dessin du gros ou du petit vertexArray
                    else if(event.key.code==sf::Keyboard::Return) textureDisplayEnable =! textureDisplayEnable; // display ou non de la renderTexture
                }
            }

            window.clear();
            renderTexture.clear();

            if(bigVertexEnable)                         renderTexture.draw(bigVertex);  // Un seul appel à la fonction draw pour dessiner nbRect fois un quad à la fois
            else     { for(unsigned i=0; i< nbRect;i++) renderTexture.draw(smallVertex); } // nbRect appels à la fonction draw pour dessiner un seul quad à la fois


            if(textureDisplayEnable) renderTexture.display();     // display de la renderTexture

            window.draw(sf::Sprite(renderTexture.getTexture()));    // Dessin de la texture sur la fenêtre

            window.display();   // DISPLAY

    } //Endwhile
    ///////////////////////////////////////////////////////////////////////////////////////

    return 0;
}


 

9
Fenêtrage / Re : Questions sur la fonction display de la classe window
« le: Février 22, 2013, 07:19:05 pm »
 :o je viens de découvrir que j'ai inversé mes timers en refaisant un code minimal  :o

Donc finalement ça fonctionne comme je l'imagine, juste qu'il va falloir que j'optimise la partie dessin...

Désolé du dérangement et merci de ta réponse rapide à mon post.

10
Fenêtrage / Re : Questions sur la fonction display de la classe window
« le: Février 22, 2013, 06:14:54 pm »
Ok je vais faire un code minimal et je le poste de suite.

Merci pour la réponse

11
Fenêtrage / Questions sur la fonction display de la classe window
« le: Février 22, 2013, 06:06:33 pm »
Bonjour,

Je me pose des questions sur la fonction display. Le principe est d'afficher tout à l'écran et de gérer le frame rate (si on l'a spécifié).

Si je dessine un grand nombre de triangles (convexShape) dans une class renderTexture et ensuite je dessine la texture dans ma classe window principale, j'observe une augmentation énorme du temps nécessaire pour le windows.display().

Entre le dessin d'un triangle et de 100 dans ma texture, display passe de ~1 msec à 45 msec
Alors que le dessin des triangles dans la texture, puis le dessin de la texture dans la fenêtre passe de ~0.1 msec à 0.70 msec.

Comment expliquer son augmentation aussi importante alors qu'il y a toujours le même nombre de pixel à dessiner?


12
Graphique / Qt + sfml[1.6] : problème de mémoire
« le: Septembre 27, 2012, 11:12:52 pm »
Salut,

J'utilise sfml version 1.6 avec Qt.
J'ai récupéré le code proposé dans le tutorial et je l'ai ajouté dans ma fenêtre Qt.
J'ai aussi un bouton Qt qui créé une fenêtre sfml ou qui la détruit suivant si elle existe ou non.
Mon soucis est que la mémoire n'est pas supprimée à chaque "delete MyCanvas", même si la fenêtre cesse de s'afficher. Tout semble marcher mais en spammant mon bouton (création / suppression / création etc) mon code devient de plus en plus gros en terme de mémoire occupée.

Je ne sais pas si cela à déjà été abordé et s'il y avait une solution ou explication?

ugo

PS: je vais tenter de refaire mon test avec la dernière version de sfml.

Edit: Pour mon test, j'ai retirer tout chargement d'image ou autre dans la classe MyCanvas.

Pages: [1]