mercredi 3 juin 2015

Animatoon - informations générales liées au développement

Le 29 mai 2015, j'ai commencé à entièrement recoder animatoon avec purebasic en utilisant la bibliothèque pour les jeux (screen et sprites).

1) Introduction

Au départ, Purebasic dispose de plusieurs bibliothèques, qui ajoutent des fonctionnalités intéressantes pour le développement.
Par exemple, sur 3arks/Arkeos (mon projet de RPG mis en pause), j'ai utilisé la bibliothèque graphique Screen, Sprite, mouse, keyboard, ainsi que quelques fonctions liées à la bibliothèque graphique 2D Drawing.

Pour plus d'informations sur les bibliothèques de purebasic, voir ici :
http://www.purebasic.com/french/documentation/

Depuis 2011, j'ai recodé plusieurs fois Animatoon avec purebasic, en essayant de nouvelles techniques à chaque fois et en essayant d'optimiser le plus possible le code.

La version sur laquelle je travaille est la version utilisant les Sprites et le screen. Cette version est la plus performantes, mais elle dépend beaucoup de la CG et du CPU dont on dispose.
Cependant, j'ai un ordinateur assez faiblard, donc mes tests sont très encourageants, car sur cette machine, c'est parfaitement fluide, même au-delà de 2048*2048, et je peux utiliser beaucoup de calques avant que ça ne se mette à ramer (j'ai testé avec 30 calques sans aucun soucis).

2) récapitulatif

- Version Image (dessin) + canvas affichant les calques (affichage)
Images (calques), image (brush), calques affiché sur le canvas
Version utilisant des images (calques) sur lesquelles je dessine d'autres images (brush), puis je dessine chaque calque sur le canvas, avant de l'avoir effacer au préalable.

    Avantages : facile
    Inconvénients : cette version rame vite au-delà de 800*600 et 2 calques.
    Version utilisant cette technique : animatoon et Teo (voir la rubrique download). Ces versions ne sont plus mises à jour, car elles devenaient vite inutilisables.



- Version Image (dessin) + canvas temps réel (affichage)
Images (calques), image (brush), canvas temps réel
Version utilisant des images (calques) sur lesquelles je dessine d'autres images. En parallèle, je dessine directement le brush sur le canvas. Cette version va très vite car dessiner sur un canvas en 5000*5000 est presque immédiat. Le problème est pour les calques au-dessus du calque courant : les calques ne sont plus affichés sur le canvas (sinon, ça fait ramer, c'est le principe de la version précédente) et donc apparait toujours sous mes nouveaux traits. Récemment, j'ai testé un systèmes de dalle (tile) et j'actualise uniquement les dalles (tiles) sur lesquelles je suis passé.

    Avantages : assez fluide, grande image possible (5000*5000), plusieurs calques sans ramer (jusque 5)
    Inconvénients : la gestion des calques du dessus et des tiles est vite complexe. En plus, si on ajoute plus de 3 ou 4 calques, on se retrouve avec un système qui rame à nouveau très vite.
    Version utilisant cette technique : animatoon-Optimisée (non disponible)



- Version dessins sur Image (dessin) + OpenGlcanvas  (affichage)
Images (calques), image (brush), OpenGlcanvas pour l'affichage.
Comme toutes les versions, je dessine mon brush sur mon calque (image courante), puis j'affiche cette image sur le calque OpenGL.

    Avantages : l'openGl canvas permet d'avoir un zoom facile et fluide. C'est très rapide. Grâce à ce nouveau gadget (version Purebasic 5.30), on a accès aux shaders en temps réel, ce qui est top !
    Inconvénients : pour le moment, l'openGL ne dispose d'aucune fonctionnalité pour l'affichage (image ou autre). On doit donc tout coder par nous-mêmes, ce qui n'est pas une mince affaire ^^ (j'ai dû un peu me pencher sur opengl du coup).
    Version Utilisant cette technique : aucune, je n'ai fait que quelques tests pour le moment.
J'espère que Fred (le dev de Purebasic) ajoutera quelques fonctions à ce gadget (comme un StartDrawing(canvasGlOutput()) par exemple, ce qui permettrait de dessiner facilement des images ou autre dessus :).



- Version dessin sur image et sur sprite +  affichage des sprites sur screen
 Images (calque courant), image (brush) sprite (brush pour le prévisualisation et screen pour l'affichage.
En gros, j'effectue deux opérations en même temps : je dessine sur le calque courant (une image) avec mon brush (une autre image) et en même temps, je dessine sur le sprite courant (le calque pour l'affichage) sur le screen. J'affiche ensuite d'autres sprites (les autres calques), au dessous ou en dessous.

    Avantage : avec le screen et les sprites, on a beaucoup d'avantage : très rapide, très grandes images (5000*5000), beaucoup de calques possibles sans faire ramer (on peut avoir facilement 20 calques sans soucis), j'ai le zoom grâce aux sprites (ZoomSprite()), les rotations (canvas
    Inconvénient : le screen et les sprites sont liés au PC et la CG, au CPu, etc.. Donc, il peut arriver que sur des aordinateurs différents, on ait des résultats différents (au niveau rendu). Donc, il est possible que j'ajoute une option permettant d'avoir le rendu image si on le souhaite.
    Version utilisant cette technique : animatoon-Screen est en cours de développement, prochainement  disponible ;).


3) code de base

Ceci concerne la nouvelle technique : dessins sur image, puis sur sprite et affichage sur screen.

Pour gérer les calques, j'utilise une structure Layer, ainsi qu'une liste (New list()) ou un tableau (dim()).
La structure ressemble à ça :
Structure sLayer
Image.i ; l'image sur laquelle je vais dessiner
ImageBM.i ; nécessaire pour les blendmode
x.w : y.w ; position et taille
View.a : Lock.a :
Bm.a ; le blendmode
Alpha.a ; la transparence
name$ ; le nom, etc..
EndStructure
Idem, j'ai une structure pour le brush, avec ses paramètres (image, size, alpha, scatter, rotation, randomrotation, etc...).

Puis, je dessine mon brush (brush\image) sur le calque 1 (layer(0)\image) avec :

If Startdrawing(Layer(LayerActif)\image)
    Drawingmode(#pb_2ddrawing_alphablend) ; le blendmode normal, à changer pour un blendmode add, multiply ou autre
    ; il manque les opération de changement du brush
    ; je garde l'image du brush original, j'en fais une copie que je modifie si besoin( pour changer la taille, rotation, couleur
    ; ici les opérations de transformation : rotation brush, size brush...
    x = mouseX + Random(scatter) - Random(Scatter)
    y = mouseY + Random(scatter) - Random(Scatter)
    DrawAlphaImage(imageId(brush\imgNew), X, Y) ; on dessine l'image du brush
    Stopdrawing()
Endif
Et ensuite, je peins sur mon sprite actif de la même manière avec
If StartDrawing(Layer(LayerActif)\Sprite) ...

Et j'affiche mes sprites sur mon screen :
ClearScreen() ; j'efface l'écran
For i = 0 to arraySize(Layer())
    DisplayTransparentSprite(LAyer(i)\sprite, 0,0)
Next i
Flipbuffers ; j'affiche l'écran

C'est assez simple, mais ça fonctionne plutôt bien.
Evidemment, il faut faire attention car sur les grandes images (5000*5000) afficher plusieurs sprites de 5000*5000 peut être problématique sur certains ordinateurs.

L'avantage est de pouvoir utiliser OpenGl ou DirectX si besoin.



 4) partage du code entre version

Afin d'éviter de tout refaire, entre chaque version, j'essaie de récupérer un maximum de procédures et de code.
Par exemple, pour les rotation d'image, les presets de brush, les procédures d'affichages, de blendmode, els fx, les transformations d'image (désaturation, brightness), etc...


Aucun commentaire:

Enregistrer un commentaire