IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AWT/Swing Java Discussion :

Swing et animation de polygones tres lente


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2014
    Messages : 5
    Par défaut Swing et animation de polygones tres lente
    Bonjour à toute la communauté.

    Je me permet de vous soumettre un problème que j'ai avec mon petit logiciel de dessin vectoriel. Je vais tenter d'être à la fois bref et précis.

    Je suis développeur amateur et je travaille depuis quelques mois sur un petit logiciel de dessin vectoriel dont je suis assez fier puisqu'il permet déjà de créer, modifier, manipuler, copier/coller, colorer des polygones/generalPath, à l'unité ou en groupe (via une arborescence de "noeuds de scenes" classique "groupes/sous-groupes" et "polygones/generalPath" représentée par un JTree). Il permet d'enregistrer et ouvrir les dessins ainsi obtenus dans un format que j'ai crée proche du SVG (simplifié). Enfin bref pas mal de boulot pour un amateur, d'autant que je n'utilise pas de librairies externes (style "batik").

    Mon gros problème c'est que les animations qui s'effectuent lorsqu'on manipule un ou plusieurs polygones dans un graphisme de plusieurs polygones sont tres tres lentes. Pour m'en convaincre, j'ai créer differents "dessins" comprenant de plusieurs dizaines à plusieurs milliers de polygones, et je tombe à 5 FPS quand j'affiche 6800 polygones.

    Je suis sous Swing et mes graphismes s'affichent dans un JPanel. Le processus qui s'effectue est des plus simple, c'est celui que l'on trouve dans la plupart des exemples sur le web: les evenements de souris (MouseEvent) engendrent des calculs sur les polygones (position, rotation, redimension) puis enchainent sur un repaint() du JPanel. La méthode paintComponent de ce JPanel appelle les méthodes "Dessiner" de mon SceneManager et de mon DebugSceneManager, qui contiennent respectivement les polygones/groupes et méthodes affiliées pour l'un, une liste des polygone selectionnés pour l'autre. Pour info, le DebugSceneManager sert à mettre en évidence, par dessus la "scene", les polygone selectionnés, ceux sur lesquels on agit.

    Clairement, et peut-être sont-ce là mes erreurs, je n'utilise pas de Thread séparé, pas de BufferStrategy, pas de BufferedImage... Le "repaint" du JPanel est effectivement une opération "lourde" dans la mesure où le SceneManager redessine toute l'arborescence de la scene, polygone apres polygone...

    J'ai essayé de nombreuses astuces, optimisé au mieux mon code, pourtant les repaint() qui s'effectuent "en rafale" en réaction aux mouvement de souris, sont lent, en particulier dans un gros "dessin".

    Alors j'aimerais beaucoup, si l'un de vous se sent le coeur de m'éclairer, qu'on m'explique quelle est la meilleure technique pour afficher et animer un nombre conséquent de polygones dans Swing? Est-ce simplement possible? Est-ce qu'il y a une astuce??? Je n'ai JAMAIS autant galéré, fait d'essais... Et étant donné le temps que je perd à chaque fois... Si on pouvais m'aider ce serait super!!!

    Merci d'avance à ceux qui prendront le temps de me lire.

    Christophe.

    PS: Deux images de mon prog:

    Nom : cp01.jpg
Affichages : 284
Taille : 259,1 Ko
    Nom : cp03.jpg
Affichages : 276
Taille : 411,5 Ko

    Pour illustrer l'affichage du "DebugSceneManager" (ce sont les polygones selectionnés et affichés en bleu)
    Nom : cp04.jpg
Affichages : 267
Taille : 160,0 Ko

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 909
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 909
    Billets dans le blog
    54
    Par défaut
    Citation Envoyé par kribsx Voir le message
    sont-ce là mes erreurs, je n'utilise pas de Thread séparé, pas de BufferStrategy, pas de BufferedImage... Le "repaint" du JPanel est effectivement une opération "lourde" dans la mesure où le SceneManager redessine toute l'arborescence de la scene, polygone apres polygone...
    Donc en gros, ton paintComponent() consiste a parcourir intégralement la liste de tes polygones et a tous les dessiner directement sur l'ecran ?

    Parmi les premières optimisations progressivement envisageables (vu qu'on a pas vu de code difficile de dire ce que tu utilises déjà) :

    1. Ne pas dessiner les trucs complètement en dehors de la zone de clip du graphics.
    2. Lors des réactions aux clics de la souris, invoquer repaint(x, y, w, h) plutôt que repaint() -> Ne pas dessiner les trucs complètement en dehors de la zone de clip (devenue restreinte) du graphics.
    3. En cas d'animation, invoquer repaint(x, y, w, h) plutôt que repaint() -> Ne pas dessiner les trucs complètement en dehors de la zone de clip (devenue restreinte) du graphics.
    4. Dessiner dans une BufferedImage qui sert de tampon offscreen -> composer ce tampon a l’écran.
    5. Optimiser le dessin dans le tampon -> calculer la zone de clip -> Ne pas dessiner les trucs complètement en dehors de la zone de clip du graphics du tampon.
    6. Mettre en place un système de simple-thread :
      1. Le thread qui sert a dessiner dans le tampon et invoquera repaint(...)
    7. Mettre en place un système de double-thread :
      1. Le thread qui sert a dessiner dans le tampon.
      2. Le thread qui invoque repaint(...) pour dessiner le tampon a l’écran a un taux de rafraichissement fixe.
    8. Explorer BufferStrategy etc.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Je te conseille de jeter un coup d'oeil à la bibliothèque open source Piccolo2D qui met en oeuvre ce genre de choses. J'ai pu afficher des dizaines de milliers d'objets, et groupes d'objets, avec animation, tranformées affines, etc. Le code de sélection est également intéressant à regarder. J'ai rencontré un peu plus de difficultés avec des images bitmap (il n'y a pas de gestion de double tampon) mais j'ai pu le régler avec du resampling dynamique (en quelque sorte en gérant un double-buffer avec cache au niveau de l'objet), le zoom étant légèrement impacté au delà de 10000 objets, mais le pan, les animations, les rollovers restent très fluides.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  4. #4
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2014
    Messages : 5
    Par défaut
    Merci à vous deux pour vos réponses.

    Bouye: Aucun problème à transmettre tout ou partie du code, mais la partie "problématique" est tellement grosse, divisée en plusieurs parties (JPanel, DebugSceneManager, SceneManager) que je me suis dit que je n'allais pas d'entrée "imposer" la lecture de tout ce bazar à ceux qui prendraient la peine de me lire. J'ai apéro ce soir mais je vous pose ça tout à l'heure sans problèmes.

    Pour ce qui est de la zone de clip j'ai effectivement limité le dessin à une zone visible, mais dans le "Draw" du SceneManager, pas dans le repaint() du JPanel. En fait j'ai pensé que le JPanel ne connaissait pas l'emplacement des polygones et par conséquent j'ai crée une méthode pour détecter si le polygone possède un point visible dans la vue ou pas. En plus du fait que ça n'affiche pas les rectangles plus grands que la vue (par exemple), ça ne m'a fait gagné que 2 FPS. Je vais donc essayé les astuces que tu m'as donné. Par contre il m'avait semblé avoir compris que BufferStrategy n'etait pas adapté à Swing puisqu'il fallait utiliser un "Canvas", qui serait un composant AWT, et que le JPanel est automatiquement "double-buffer". Mais alors là c'est des trucs qui me dépassent . Merci

    joel.drigo: En fait j'ai fait ce programme sans planifier quoi que ce soit, il a évolué doucement au fil de mes envies. C'est à dire que je n'avais même pas envisagé au début lui faire faire tout ce qu'il fait aujourd'hui. Donc en fait je me retrouve avec un "gros" programme (pour moi lol) sur les bras et je me vois mal reprendre à zéro maintenant, et mettre à la poubelle toutes ces classes et méthodes que j'ai crée moi même. Même si effectivement je sais pertinemment qu'il y a de nombreuses alternatives tres performantes, et qui ont déjà tout ce que je pense faire plus tard. Faut dire aussi que je prends plaisir à faire tout ça moi même, ça m'a permis et me permet de comprendre un peu tout ça de l'interieur, par la pratique. En principe je me suis toujours démerdé seul à partir d'exemples et autres tutos, mais là c'est vrai que je bloque niveau optimisation "graphique". Faut dire que je ne suis pas du tout du métier, ni même étudiant dans le domaine. Me manque sûrement certaines bases, une bonne formation, même si je crois pas être au niveau zéro. Pour info je suis dans le BTP je joue au développeur sur mon temps libre . Merci pour l'astuce. Sinon, aurais-tu un lien ou un tuto , ou saurais-tu m'en dire plus sur le principe du cache au niveau de l'objet?

    PS à vous deux: Je viens de remarqué, suite à la réponse de Bouye sur la "zone de clip", que lorsque j'applique un zoom inférieur à 100% (je dézoome quoi...), le FPS regrimpe tres nettement, malgré les 6800 polygones!!! J'obtiens 32 FPS en réduisant la taille à 1/10 (Zoom 10%)!!! Dans ma méthode zoom je redimensionne les polygones mais également le JPanel qui les contient. J'en déduis donc que la taille de la zone de repaint() à une influence énorme. Me reste à essayer les astuces de Bouye pour voir ce que je peux obtenir comme ça, parce que bon c'est difficile de faire du dessin vectoriel dans un espace de 100X100 pixels !!! Merci à vous deux je reviens plus tard je poste mon code et je vous tiens informé sur l'évolution de mon problème qui me casse les #### et me bloque depuis trop longtemps!

  5. #5
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Sans tout réécrire depuis zéro, tu peux refactoriser certaines parties, ajuster, intégrer en partie des idées, petit à petit réécrire certaines parties (tout dépend de ta vision à long terme sur ton projet).
    Par exemple, je pense à ce que tu écris :
    Citation Envoyé par kribsx Voir le message
    j'ai crée une méthode pour détecter si le polygone possède un point visible dans la vue ou pas.
    Dans Piccolo2D, comme très classiquement dans ce genre de système, tout node (polygone ou autre) à des bounds (local, global), qui sont mis à jour lors de la modification/création du node (du polygone le cas échéant), la modification des bounds d'un node est remontée à son parent pour que ses bounds soient mise à jour. Ensuite, au lieu de chercher si un point (de path) est dans le clip ou pas, Piccolo2D teste rapidement l'intersection avec les bounds. Et seulement ensuite, il y a éventuellement un test sur chaque point. Ainsi ça élimine très rapidement des milliers de polygone hors clip quelque soit leur complexité et leur nombre de points. De même, le processu de paint est délégué à un painter, qui empile les clips et les bounds, ce qui donne en résultat une sorte de test ressemblant à du quadtree, qui optimise également le traitement. Voilà une idée qui me semble normalement pas trop difficile en théorie d'implémenter sans tout réécrire, quelque soit ton archi actuele par ailleurs (partiellement si nécessaire : au moins tenir à jour des bounds de polygone pour faire un premier filtre rapide).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  6. #6
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2014
    Messages : 5
    Par défaut
    joel.drigo: Effectivement, sans me contenter d'utiliser Piccolo2D bêtement, je vais l'étudier et m'en inspirer. Merci.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [wifi]transfert de données tres lent
    Par Grimaud dans le forum Hardware
    Réponses: 5
    Dernier message: 30/01/2006, 12h34
  2. [FB 1.5.2] Requetes tres lentes via VPN
    Par gudul dans le forum Connexion aux bases de données
    Réponses: 8
    Dernier message: 05/01/2006, 18h52
  3. NFS : Mount très lent
    Par litbos dans le forum Réseau
    Réponses: 2
    Dernier message: 28/12/2005, 14h23
  4. Impression très très lente avec Samba
    Par Daav dans le forum Réseau
    Réponses: 4
    Dernier message: 29/12/2004, 18h45
  5. Réponses: 6
    Dernier message: 29/09/2004, 12h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo