Application dessin CALayer ou autre

Bonjour,


 


J'aimerais faire un petite application de dessin sur OSX et iOS qui pourrait dessiner du texte, des formes :(Rectangle, Cercle, ...) mais aussi quelques objets plus évolués comme des graphiques, des tableaux, et autres.


 


J'ai pensé à  deux approches :


 


La première est d'utiliser une sous classe de NSView ou UIView et de créer des sous classes de NSObject  qui auraient une méthode -drawInContext:(CGContextRef)context; Le drawRect de la vue appellerait les drawInContext de chaque objet par une boucle. La vue utiliserait KVO-KVC pour detecter un changement et rafraichir que la partie de la vue qui a besoin.


 


La deuxième approche serait d'utiliser toujours une sous classe de NSView ou UIView et de créer des sous classes de CALayer avec des méthodes de dessin custom. Le rafraichissement se ferait tout seul et les animations seraient possibles.


 


La question que je me pose est la suivante : La premiere méthode nécessite de faire beaucoup dessin à  chaque changement, va pas t elle trop lente (lors de déplacement d'une forme par exemple) et si j'ai bien compris, les CALayer garde un bitmap de leur dessin, va t elle donc pas trop consommé en mémoire si il en a un nombre non négligeable de superposition?


Comment feriez-vous vous dans une application similaire ?


Réponses

  • Bonjour,


     


    Il y a une autre question préliminaire à  se poser : Quartz ou OpenGL ?


     


    Ensuite il me semble que chaque solution aura ses avantages et ses inconvénients.


    Mais les solutions propriétaires entraà®nent une dépendance.


    Par exemple, il me semble avoir récemment vu une discussion sur les forums Apple sur des bugs au niveau des CATliedLayers (qui sont a priori très séduisants).


    Il y a ensuite la portabilité du code.


     


    Je ne sais pas s'il existe des comparaisons exhaustives entre toutes ces possibilités.


    Si tu trouves, merci de partager.


  • MalaMala Membre, Modérateur

    Core Animation n'est vraiment pas fait pour ça et OpenGL risque de poser d'autres problèmes car c'est loin d'être du haut niveau (tu devrais gérer les textures de chaque objets ainsi que les contraintes matérielles de la GPU sur lequel ça tourne). Je te conseillerais donc de rester sur le concept d'une vue mère qui dessine ses enfants via Quartz 2D. Par contre, si tu veux de vraies performances il faudra faire un mixte entre dessin vectoriel et caches bitmap (attention aux marges en cas d'ombrage).


  • @Mala, Penses-tu a une classe en particulier pour les bitmap sur à  la fois iOS et OSX ?


     


    Est-ce vraiment pénible et compliqué OpenGL car ca l'air vraiment rapide en se basant à  ce que disent les gens sur internet ?


  • OpenGL est très rapide et très compliqué d'emploi. Les jeux vidéos sont développé avec OpenGL, par exemple. A la base c'est conçu pour faire de la 3D, mais on peut s'en servir pour la 2D en bidouillant un peu.
  • MalaMala Membre, Modérateur


    @Mala, Penses-tu a une classe en particulier pour les bitmap sur à  la fois iOS et OSX ?




    Pour du portable, je verrais bien manipuler des CGImage à  titre de cache bitmap. A vérifier s'il y a des subtilités entre les deux systèmes.


     


     




    Est-ce vraiment pénible et compliqué OpenGL car ca l'air vraiment rapide en se basant à  ce que disent les gens sur internet ?




    Oui cela devient vite complexe et encore plus sur du multi-devices.


     


    Quartz 2D permet de faire aussi bien si ce n'est mieux en se prenant beaucoup moins la tête. Il a été conçu pour ça (gestion de transparences, effets d'ombrages, formes de base et plus complexes comme les splines, masquages, dégradés, etc). De même, si tu manipules des CGPath tu as déjà  tout ce qu'il te faut pour faire des "hit tests" lorsqu'un utilisateur clique/touche une zone (voir CGPathContainsPoint() ).


     


    Si on voit parfois des logiciels peu performant c'est juste que le développeur se pose pas trop de question et fait tout en vectoriel. Du coup effectivement par rapport à  de l'OpenGL où tout va être bitmapisé de fait il y aura pas photo. Comble, on lit souvent par ci par là  que le vectoriel c'est plus rapide car on manipule moins de pixels qu'avec des bitmaps. C'est bien sur totalement faux. Calculer et dessiner une spline à  la volée est toujours beaucoup plus gourmand que de faire une simple copie de bits.


     


    Autre chose à  ne pas négliger avec Quartz 2D, si tu sais dessiner dans une vue tu sais aussi le faire dans une image pour l'écrire sur disque. Donc le même code peut être utilisé pour l'affichage et l'export pour peut de changer le contexte graphique.

  • MalaMala Membre, Modérateur

    A noter que fouf pourrait être aussi de bon conseil puisqu'il s'était déjà  fait plaisir sur le sujet avec DrawBerry...


    http://forum.cocoacafe.fr/topic/2352-drawberry/?hl=%2Bdessin+%2Bvectoriel


  • Merci pour vos réponses, en particulier merci Mala.


    Donc comme vous m'avez conseillé, je vais partir sur la solution 1.


     

    Je vais essayer de résumer.

     

    L'application comporte une vue principale qui dessine chaque element dans sa méthode -drawRect:(CGRect)rect par une boucle.

    Un element est une sous classe de NSObject et a une méthode -drawInContext:(CGContextRef)context;

    Un element simple comme un carré ou un cercle se dessine dans la méthode  -drawInContext:

    Alors qu'un élément complexe comme un graphique ou un tableau se dessine dans un CGImageRef lors d'un changement de données ou de zoom par exemple et la méthode -drawInContext dessine directement le CGImageRef quand elle est appelé.
  • MalaMala Membre, Modérateur

    En prenant un peu de recul, tu peux très bien imaginer que ta classe mère de base à  tes objets graphiques gère la notion de cache. La simple surcharge d'une méthode genre...



    - (BOOL)useBitmapCache 

    ...pourrait alors permettre de modifier l'aiguillage de l'affichage à  la volée.


  • C'est effectivement la solution que j'avais plébiscitée quand j'ai commencé mon éditeur vectoriel (ensuite la vie et le travail se sont chargés de m'en écarter). Pour les cache j'avais pensé utiliser est CGLayerRef pour tout un tas de raison qui m'échappent à  ce moment précis (mais c'était pas une mauvaise idée, ça je m'en souviens).


     


    Là  où je n'avais pas réussi à  solutionner le problème c'était pour les outils d'édition (basés sur le modèle du FieldEditor de CoreText) et la gestion du zoom ainsi que les opérations booléennes. Sans parler des artistic-strokes ou caligraphic-strokes pour lesquelles je n'avais pas le moindre début de réponse.  


  • MalaMala Membre, Modérateur

    Pour le zoom, c'est un sujet qu'on avait abordé par le passé avec berfis dans ce topic...


    http://forum.cocoacafe.fr/topic/11807-résolu-zoom-et-recentrage-dune-nsview/


  • Merci pour tous ces conseils !!


     


    J'ai commencé l'implémentation mais je n'ai pas encore fait des dessins vraiment complexes.


    Des que je finis mes examens, je m'y mets à  fond et je vous dirais niveau performance.


Connectez-vous ou Inscrivez-vous pour répondre.