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 - PetitPoney

Pages: [1] 2 3 Suivante »
1
Graphique / Re : Initialisation d'un sf::RenderWindow
« le: Novembre 12, 2013, 10:19:00 am »
Salut !

Je travaille actuellement sur un projet de 3ème année en école d'info. On utilise la SFML aussi :).
Pour ta question voilà ce que nous avons au niveau de l'architecture.

Un Manager qui est le big brother du jeux.
Ce Manager contient plusieurs sous partie du programme découpé en "Engine". Par exemple, nous avons un GameEngine (s'occupe de mettre à jour les propriété des objets du jeux), un PhysicEngine qui lui ne s'occupe que des calculs physiques (collisions etc), un GraphicEngine qui ne fait que de l'affichage, NetworkEngine, InputEngine etc etc.

Donc sur le principe d'avoir une classe qui ne fait que l'affichage je suis plus que d'accord, ça permet de bien séparer les différentes parties du code.
Cepedant si tu pars sur ce principe de plusieurs moteurs, essaie d'avoir quelque chose de cohérent au niveau de la structure de ceux-ci (par exemple, en passant par une interface IEngine qui oblige tous les moteurs à avoir la même forme, initialize(), update(), stop() par exemple).
Le Manager n'est chargé que de faire communiquer les engines, appeler leurs fonctions start()  update() stop(), et des choses annexes au jeu.

Si quelqu'un a des remarques à faire je suis preneur   :)

Cordialement.

2
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 24, 2013, 03:37:40 pm »
Non, ça peut descendre en dessous mais c'est "a vu d'oeil" la valeur maximale.

Pourquoi les VBO ?


J'ai déjà fait pas mal d'openGL + VBO pour un jeux en 3D qui avait plus d'affichage à faire que mon projet 2D actuel, pourtant celui-ci était plus rapide. Par contre il n'y avait en effet pas d'utilisation de shader.

Au niveau de l'optimisation.

Comme je l'ai dis précédement j'ai déjà fait un gros travail d'optimisation en rassemblant les objets du même groupe dans trois vertexArray afin de n'avoir que trois draw à utiliser pour plusieurs centaines d'objet.

Actuellement si je spam comme un sale pour avoir un maximum d'objet à l'écran, je monte au grand maxium à 20 draw/frame (en comprenant donc l'application de shader). En utilisant des sf::RenderTexture de la taille de ma fenêtre, je suis en fullscreen à ~25fps, en 1280*720 je monte à ~40pfs, en 800*600 c'est la fête je passe à ~70fps.

Je suppose donc que le problème vient des sf::RenderTexture.
Ce que je ne comprend pas c'est que j'utilise une texture (loadFromFile)  de 2048*2048 pour dessiner mon background étoilé dynamic (sf::VertexArray de 500 sf::Triangles) et je n'ai pas de soucis avec ça.

Pourquoi ça et pas autre chose ?
J'ai déjà pensé à multiThread mes mise à jour de sf::VertexArray, mais je n'ai pas vraiment approfondi le sujet.

EDIT : Les mises à jours des deux plus gros sf::VertexArray ont maintenant leur propre thread. Ce qui ne ralenti pas l'affichage lors de ces mises à jours.
Je n'ai pas gagner en fps, toujours à cause des sf::RenderTexture et de l'application de mes shaders.

En faisant quelques recherches je suis tomber sur ça http://www.jonathanhaehnel.fr/blog/article/render-to-texture-avec-opengl-3-et-glsl-shaders.html
Si mon problème vient bel et bien des sf::RenderTexture, cette technique pourrait-elle m'aider ?

EDIT 2 : D'après les sources de la SFML, les FBO sont déjà implémenté dans la sfml, je ne me trompe pas ?

EDIT3 : J'obtiens finalement des performances correcte en appliquant qu'un seul glow global à toute ma scène. J'utilise donc deux sf::RenderTexture de la taille de ma fenêtre (+ quelques plus petits pour l'application de petits shader locaux).
Je suis maintenant à ~55fps en 1920*1080 ce qui est satisfaisant.

3
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 24, 2013, 02:57:22 pm »
Je comprend tout à fait.

Cependant, je n'ai toujours pas trouvé de solutions pour appliquer mes shader de façon globale sur mon écran 1080p sans tomber à 30fps (si ce n'est utilisé de plus petit sf::RenderTexture ce qui donne un résultat moche).

Pensez vous que je gagnerais à passer directement par openGL et utiliser des VBO ?

4
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 24, 2013, 02:35:59 pm »
Justement, le programme sur lequel je travail actuellement est pour moi assez avancé pour se pencher sur des questions de performances car nous atteignons environ 30fps (du exclusivement à la partie graphique) ce qui n'est pas correct.

C'est pour cette raison que je cherche à ne pas faire du gaspillage de ressources à ce niveau.

Si vous êtes intéressé par notre projet et nos problèmatiques nous pouvons vous donner un accès a notre git.

5
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 23, 2013, 10:24:40 pm »
D'accord donc si je comprend bien j'atteins les limites de ma machine ? Ou même de la SFML (du moins openGL plutôt je dirais) ?

Ce que je ne comprend pas, c'est qu'en faisant des choses relativement simple mon programme n'est pas performant, alors qu'en parrallèle un StarCraft2 tourne en medium sans problème.

6
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 23, 2013, 09:31:35 pm »
Je viens d'essayer avec un shader qui ne fait que renvoyer la couleur de la texture reçue en entrée (toujours en deux pass pour rester dans mon objectif d'application multiple de shader).
Je tourne à 200 fps ce qui fait malgré tout une belle chutte.

Est-ce qu'utiliser un shader loadFromMemory est plus performant qu'un shader loadFromFile ?


Au passage, voilà le shader qui applique un glow à toute la scène

uniform sampler2D       texture;
uniform sampler2D       textureBase;
uniform vec2            pixelSize;
uniform float           pass;
uniform float           range;
uniform float           intensity;

void firstPass(float values[25])
{
  vec2 pos = gl_FragCoord.xy * pixelSize;
  vec4 result = vec4(0, 0, 0, 0);
  vec2 curSamplePos = vec2(pos.x - range * 12.0 * pixelSize.x, pos.y);

  for(int i = 0; i < 25; i++)
    {
      result += texture2D(texture, curSamplePos) * values[i];
      curSamplePos.x += range * pixelSize.x;
    }
  gl_FragColor = result * intensity;
}

void secondPass(float values[25])
{
  vec2 pos = gl_FragCoord.xy * pixelSize;
  vec4 result = vec4(0, 0, 0, 0);
  vec2 curSamplePos = vec2(pos.x, pos.y - range * 12.0 * pixelSize.y);

  for(int i = 0; i < 25; i++)
    {
      result += texture2D(texture, curSamplePos) * values[i];
      curSamplePos.y += range * pixelSize.y;
    }
  // Final result
  gl_FragColor = result * intensity + texture2D(textureBase, gl_TexCoord[0].xy);
}

void main()
{
  float values[25];
  int i = 0;

  values[i++]=0.015; values[i++]=0.015; values[i++]=0.031; values[i++]=0.031; values[i++]=0.031;
  values[i++]=0.031; values[i++]=0.046; values[i++]=0.046; values[i++]=0.046; values[i++]=0.046;
  values[i++]=0.061; values[i++]=0.061; values[i++]=0.076; values[i++]=0.061; values[i++]=0.061;
  values[i++]=0.046; values[i++]=0.046; values[i++]=0.046; values[i++]=0.046; values[i++]=0.031;
  values[i++]=0.031; values[i++]=0.031; values[i++]=0.031; values[i++]=0.015; values[i++]=0.015;

  /* First pass */
  if (pass == 0.0)
    firstPass(values);
  /* Second pass */
  else if (pass == 1.0)
    secondPass(values);
}
 

Autre test que je viens de faire :
Utiliser des textures de 800*600 dans une fenêtre de 800*600. Avec le shader glow de base, je suis à ~200fps. J'ai également séparer mes deux pass en deux shader différents.

7
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 23, 2013, 08:47:17 pm »
Bonjour !

Je me permet de relancer ce topic car je n'ai toujours pas réglé mon problème de performance pour l'application de shader globaux.

Avant tout, j'ai fais un gros travail d'optimisation dans le code. En effet, toute mes "bullets" font maintenant parties d'un seul sf::VertexArray que je met à jour à chaque frame. Aussi, tout mes systèmes de particules sont également rassemblé dans un seul sf::VertexArray.
En gros, je dois gagner environ 300/350 draw par frame (HUGE :D).

Cependant, j'ai toujours un problème de chute de fps pour l'application de shader globaux. J'ai donc décidé de faire un exemple de code qui illustre ce problème.

Les shaders ne seront pas en std::string car il y a pas mal de code, ils sont donc en pièce jointe a mettre dans le même répertoire de le binaire.

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

std::string intToString(const int &i)
{
        std::stringstream ss;

        ss << i;
        return ss.str();
}

void loadShader(sf::Shader &pass1, sf::Shader &pass2)
{
        pass1.loadFromFile("vertex.vert", "fragment.frag");
        pass2.loadFromFile("vertex.vert", "fragment.frag");

        pass1.setParameter("texture", pass1.CurrentTexture);
        pass1.setParameter("pixelSize", 1.0f / (float)1920.0f,
                1.0f / (float)1080.0f);
        pass1.setParameter("pass", 0.0);
        pass1.setParameter("range", 2.0);
        pass1.setParameter("intensity", 1.0);

        pass2.setParameter("texture", pass2.CurrentTexture);
        pass2.setParameter("pixelSize", 1.0f / (float)1920.0f,
                1.0f / (float)1080.0f);
        pass2.setParameter("pass", 1.0);
        pass2.setParameter("range", 2.0);
        pass2.setParameter("intensity", 1.0);
}

sf::RenderTexture *applyShader(sf::RenderTexture &buffer1, sf::RenderTexture &buffer2,
        sf::CircleShape &shape, sf::Text &fps,
        sf::Shader &pass1, sf::Shader &pass2)
{
        buffer1.clear();
        buffer2.clear();

        // Draw objects in first buffer
        buffer1.draw(shape);
        buffer1.draw(fps);
        buffer1.display();

        pass1.setParameter("textureBase", buffer1.getTexture());
        pass2.setParameter("textureBase", buffer1.getTexture());

        // Apply shader
        buffer2.draw(sf::Sprite(buffer1.getTexture()), &pass1);
        buffer2.display();
        buffer1.draw(sf::Sprite(buffer2.getTexture()), &pass2);
        buffer2.display();

        return &buffer1;
}

int main(void)
{
        sf::RenderWindow window(sf::VideoMode(1920, 1080), "Shader application, performance", sf::Style::Fullscreen);
       
        // Buffers
        sf::RenderTexture buffer1;
        buffer1.create(1920, 1080);
        sf::RenderTexture buffer2;
        buffer2.create(1920, 1080);

        // CircleShape
        sf::CircleShape shape;
        shape.setRadius(200);
        shape.setPosition(1920.0f / 2.0f, 1080.0f / 2.0f);
        shape.setOrigin(shape.getRadius(), shape.getRadius());
        shape.setFillColor(sf::Color::Green);

        // FPS
        sf::Clock clock;
        clock.restart();
        int frame = 0;
        sf::Font font;
        font.loadFromFile("arial.ttf");
        sf::Text fps("", font);

        // Shaders
        sf::Shader pass1;
        sf::Shader pass2;
        loadShader(pass1, pass2);
       
        while (window.isOpen())
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Close window : exit
            if (event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
                window.close();
        }
               
                // Clear
                window.clear();

                // FPS
                if (clock.getElapsedTime().asSeconds() > 1.0f)
                {
                        fps.setString("fps : " + intToString(frame));
                        clock.restart();
                        frame = 0;
                }
       
                // Shader version, comment this to desactivate shader
                sf::RenderTexture *final = applyShader(buffer1, buffer2, shape, fps, pass1, pass2);            
                window.draw(sf::Sprite(final->getTexture()));

                // No shader version, uncomment this to desactivate shader
                //window.draw(fps);
                //window.draw(shape);

                window.display();
                frame++;
        }

        return 0;
}
 


Sans shader, je tourne preque à 1000 fps (je viens de mettre à jour mes drivers graphiques).
Avec, je tombe à 60 fps.

J'ai déjà essayé d'utiliser des texture puissance de 2, le problème c'est que 1024*1024 c'est petit (donc pour scale à la taille de l'écran c'est moche), 2048*2048 c'est trop gourmand.

J'espère avoir été clair  :).

Merci d'avoir pris le temps de lire mon post.
Cordialement

8
Graphique / Pixel clamping, problème de clignotement
« le: Octobre 18, 2013, 12:39:00 am »
Bonjour !  :)

Je cherche un moyen de régler un problème de "pixel clamping". En effet, lorsqu'un objet devient plus petit qu'un pixel, il se met à clignoter lors de déplacement, ce qui est tout à fait normal. Je cherche donc un moyen d'eviter ce problème en camplant la taille de mes objets à un pixel.

Un petit bout de code :

       

    #include <SFML/Window.hpp>
    #include <SFML/Graphics.hpp>
     
    int main(void)
    {
      sf::RenderWindow window(sf::VideoMode(1000, 500), "test");
      sf::View view;
      view.setCenter(500, 250);
      view.setSize(4000, 2000);
     
      sf::RectangleShape rect;
      rect.setPosition(499, 0);
      rect.setSize(sf::Vector2f(2.0, 1000.0));
     
      while (window.isOpen())
        {
          sf::Event event;
          while (window.pollEvent(event))
            {
              if (event.type == sf::Event::Closed)
                window.close();
              else if (event.type == sf::Event::MouseWheelMoved)
                {
                  if (event.mouseWheel.delta > 0)
                    view.setSize(view.getSize().x + 20,
                                 view.getSize().y + 20);
                  else
                    view.setSize(view.getSize().x - 20,
                                 view.getSize().y - 20);
                }
     
              if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                view.move(-0.5, 0);
              else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                view.move(0.5, 0);
              window.setView(view);
            }
          window.clear();
          window.draw(rect);
          window.display();
        }
      return 0;
    }

 

Lors du lancement il n'y aura rien d'affiché. Utilisez les flèche de direction droite/gauche pour voir l'effet de clignotement.

Plusieurs pistes :
  • Augmenter la taille de l'objet jusqu'à obtenir : object.getGlobalBounds.width == screenPixelSize.x
    Dans ce cas, comment calcul-t-on la correspondance entre un pixel physique et un pixel en coordonnée sfml ? (viewSize.x / windowResolution.x   ??)
  • Faire du supersampling, mais au final ça ne fait que repousser le problème, et c'est plus gourmand en calcul

Cordialement

EDIT :
La première solution consisterait à ajouter dans la boucle quelque chose du genre :

while (rect.getGlobalBounds().width / view.getSize().x < 0.00078125)
   rect.scale(1.00001, 1.0);
// 0.00078125 = rect.getGlobalBounds().width / view.getSize().x   pour lequel il n'y a pas de clignotement (largeur du rectangle == 1 pixel physique)
 
Mais c'est vraiment moche :/

9
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 03, 2013, 12:38:31 pm »
Du coup voilà comment je procède.

J'ai crée une classe que l'on va appelé "ProjectileSystem" qui a pour attribut :
  • Un conteneur d'objet "Projectile" (une unsorted_map)
  • Une principale renderTexture dans lequel je trace tous mes projectiles
  • Deux autre renderTexture que l'utilise pour appliquer mes shader

Avantages :
  • Une unsorted_map est très pratique et pas très gourmande pour les opérations de suppression (log si je me souviens bien)
  • Elle permet justement de supprimer simplement des élements de la map
  • Si je veux plusieurs type de bullet, je n'ai qu'à créer plusieurs "principales" renderTexture et je dispatch mes projectiles dans l'une ou l'autre
  • Tout cela convient parfaitement à mon système de ping / pong pour l'application de shaders
  • Performances nickel !  :)

10
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 01, 2013, 01:36:22 pm »
Merci pour ces explications.

Je vais implémenter mes sf::VertexArray et je reviendrais poster mon feedback   :)

D'ailleurs, je vois que la classe sf::VertexArray est en fait une surcouche d'un std::vector. Pourquoi ne pas proposer une fonction permettant de supprimer tel ou tel élement du VertexArray ?
Car en l'occurence j'en ai besoin pour delete les projectiles qui depop de la scène.

Ah, c'est sûrement à cause de ça (doc c++)
Citer
Compared to the other dynamic sequence containers (deques, lists and forward_lists), vectors are very efficient accessing its elements (just like arrays) and relatively efficient adding or removing elements from its end. For operations that involve inserting or removing elements at positions other than the end, they perform worse than the others, and have less consistent iterators and references than lists and forward_lists.

Du coup il faudrait que pour chaques frame je recharge mon sf::VertexArray ?  :-\. C'est bof quand même non ?

11
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 01, 2013, 12:33:06 pm »
Citer
Tu te bases sur quoi pour affirmer que "ça commence à faire [beaucoup]" ? A moins que ce ne soient les résultats de ton programme qui te permettent d'arriver à cette conclusion, ça ne sert à rien. Tirer des conclusions sur les performances a priori, ça ne mène qu'à des problèmes fictifs et une complication de code pour... pas grand chose.
Citer
A moins que ce ne soient les résultats de ton programme qui te permettent d'arriver à cette conclusion
C'est exactement ça. Mon groupe a fait pas mal de profiling hier soir sur notre programme pour détecter les parties les plus gourmandes en ressources, et en l'occurence il s'agit de la partie "dessin" de tout mes objets (quand la liste dépasse la centaine d'objet).
D'ailleurs quand j'y pense, ce n'est pas normal. Car j'avais déjà fais un projet précédent qui affichait beaucoup plus d'objets que ça par frame, et les performances était bien meilleure (les pertes de performances arrivaient lorsque que j'avais plusieurs milliers d'objets à tracer).
Il faudrait que je me porte plus sérieusement sur mon programme plutôt que sur des problèmes que je peux penser venir de SFML.

Quelques chiffres au passage pour illustrer mon propos
0.200ms pour un clear et un draw dans mon programme
Faisant un clear et un draw (au minimum) pour chaques objets je passe 0.400ms par objet / frame.
Avec une centaine d'objet ça me fait donc 40ms / frame soit 25fps.

Cependant ces performances viennent peut être aussi du fait que la taille de mes sf::RenderTexture partagée ne convient pas du tout à la taille de mes projectile (beaucoup de gaspillage de ressources du coup).

Citer
Non, afin de garder une flexibilité maximale. Une fois sur la carte graphique, c'est plus délicat à toucher. Et comme l'API de SFML permet de changer facilement les attributs des entités à tout moment, ça flinguerait les performances de tout mettre systématiquement sur la carte graphique via des VBOs.
D'accord  :)


12
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 01, 2013, 12:06:41 pm »
Citer
Mais plusieurs centaines de projectiles, c'est potentiellement pas grand chose

Si ils sont stoqué sur la carte graphique oui, mais si il faut clear/draw leur buffer à chaque frame, mettre à jour leur geometrie etc ça commence à faire  :-\
D'ailleurs, est-ce que les sf::VertexArray sont push sur la carte graphique ?
J'ai déjà fais des VBO sous openGL et je me souviens que mon programme était devenu un fusée après ça  :)

13
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 01, 2013, 11:23:07 am »
Citer
Citer
Cependant, corriger ce problème ne me permettrait de contourner pas le soucis que j'ai pour afficher de nombreux objets à chaques frames (car le nombre d'appel à clear/draw sera toujours aussi important).
Ok. Donc là on ne parle plus de shaders, juste d'optimiser l'affichage des objets ?

Exact  :). Car dans une frame je peux me retrouver avec une (voir plusieurs, je ne veux limiter en aucun cas mon projet) centaines d'objet à dessiner.
J'ai déjà piqué votre système de particule pour faire mes explosions, et je pensais faire quelque chose d'a peu près identique pour gérer ma/mes centaines de projectile. Cependant si je veux plusieurs projectiles différents (en utilisant des shaders différents), je dois passer par plusieurs vertexArray du coup.

Exact ?  :D

PS : Je reviendrais plus tard sur mon application de shader globaux

14
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 01, 2013, 10:54:02 am »
Citer
Moi je reste toujours bloqué sur le fait que tu n'arrives pas à avoir des performances correctes en appliquant tes shaders sur tout l'écran. Tu ne devrais pas avoir à bidouiller comme tu le fais là.

Ce problème (limitation des fps à 30) était causé par la syncronisation verticale. Vous aviez pointé ce problème. De plus j'ai pour le moment enlever l'application des shaders globaux car la structure de base n'est pas encore tout à fait à mon goût.
Je vais quand même faire un code minimal au cas où je verrais mal la chose.
Cependant, corriger ce problème ne me permettrait de contourner pas le soucis que j'ai pour afficher de nombreux objets à chaques frames (car le nombre d'appel à clear/draw sera toujours aussi important).

Au passage, j'ai une petite question un peu plus "technique".
Est-ce que SFML met plus de temps à draw lorsqu'on lui passe un shader en paramètre ?
Si j'ai bien compris openGL, les shaders "prennent la place" de certains module dans le pipeline d'openGL.
Conclusion, les performances devraient être à peu près équivalente, n'est-ce pas ?

15
Graphique / Re : Performance, sf::RenderTexture et nombreux Shaders
« le: Octobre 01, 2013, 10:19:28 am »
Bonjour  :)

Je vais exposer ici un problème de performance que j'ai et qui d'après moi est tout a fait normal. Je cherche juste la meileure solution afin de contourner ce problème.

Reprenons l'exemple que j'ai donner plus tôt dans ce topic.

Citer
Imaginons que j'ai un personnage qui tire des projectiles de façon rapide et répété (disons 10/sec) et que je veux appliquer des shader sur chaque projectile

Pour l'instant, j'ai deux sf::RenderTexture partagée entre tout mes objets. Cependant, si dans une frame j'ai 200 projectiles à dessiner, cela prend du temps (200 * (clear + draw)).
Forcément, le programme en souffre.

J'ai donc penser à un sf::VertexArray.
Pourquoi :
Utiliser un vertexArray pour afficher tout mes projectiles d'un coup. Cependant cela me limite au niveau des shaders (si je veux plusieurs projectiles différents, il me faut plusieurs vertexArray). Ce sera quoi qu'il en soit toujours plus performant que l'implémentation actuelle.

Y-aurait-il une autre approche que les vertexArray ?

Cordialement.

Pages: [1] 2 3 Suivante »