[Tuto]Fx et blendmode

Informations pour bien débuter en PureBasic
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

[Tuto]Fx et blendmode

Message par blendman »

Ou comment faire des effets de lumières sur vos jeux :)

Edité et complété le 15/03/2011

Le but :
réaliser un effet de lumière, ou d'ombre : nous allons afficher un sprite avec un "mode fusion" (blendmode) différent, afin de changer son aspect.
Il pourra avoir l'air plus lumineux, ou plus sombre.

Utilité :
par exemple, pour un sort de magie dans un jeu d'aventure ou RPG, ou une explosion dans un space shoot, ou encore pour créer un effet jour/nuit.
On peut trouver beaucoup d' autres utilités.

Explication sommaire sur les "blendmode" :
Qu'est-ce qu'un blendmode.
Si vous connaissez un peu gimp ou photoshop, vous saurez que les calques ont ce que l'on appelle les modes de fusion (= blendmode).
Le mode de fusion (ou blendmode) est une façon d'afficher une image (ou un sprite dans un jeu), en fonction de ce qu'il y a en dessous.

Prenons 2 images A et B.
- L'image A sur trouve sur le calque du dessus.
- l'image B sur le calque du dessous.
- L'image A est donc "vue au dessus " de l'image B.

Parmi les mode de fusion, on trouve ceux-ci :
- normal : on superpose juste une image A (avec transparence ou non) au dessus d'une autre image B
- produit : l'image A du dessus assombrit celle du dessous (la B)
- mode addition : l'image A du dessus "éclaire" l'image B du dessous
- mode inversion : l'image A du dessus inverse les couleurs de l'image B du dessous, en fonction des couleurs de l'image A
etc...

Il existe beaucoup d'autres modes de fusion, le mieux pour voir l'intérêt étant de les tester :).

Avec purebasic, nous avons la possibilité d'exploiter très simplement ces modes de fusion.

Nous allons voir comment faire cela facilement.


Le code pour utiliser le blend mode, ainsi que la méthode
utiliser le blendmode est assez simple. Il y nénamoins une suite de chose à réaliser dans l'ordre :
- tout d'abord avoir un sprite, et le "convertir en sprite3D avec createSprite3D()
- puis démarre le mode 3D avec start3D()
- puis changer le blendmode avec Sprite3DBlendingMode(ModeSource, ModeDestination) : voir un peu plus bas l'explication en détail.
- ensuite afficher le sprite 3D avec DisplaySprite3D()
- ne pas oublier de remettre le blend mode normal avec Sprite3DBlendingMode(5,6), sinon, tous vos sprites risque d'être dessiner avec l'autre blendmode.


Explication sur le blendmode :
Les modes source et destination
> on va définir avec ces paramètres quel mode de mélange de couleurs est à utiliser pour à la fois la couleur source et celle de destination.
Nous pouvons utiliser les constantes suivantes pour chaque paramètre. Chaque constante définie un facteur de mélange. On utilise donc une constante pour la source, et une autre pour la destination (2 constantes différentes ou 2 constantes identiques, cela dépend de ce que l'on souhaite comme effet) :
#D3DBLEND_ZERO = 1
#D3DBLEND_ONE = 2
#D3DBLEND_SRCCOLOR = 3
#D3DBLEND_INVSRCCOLOR = 4
#D3DBLEND_SRCALPHA = 5
#D3DBLEND_INVSRCALPHA = 6
#D3DBLEND_DESTALPHA = 7
#D3DBLEND_INVDESTALPHA = 8
#D3DBLEND_DESTCOLOR = 9
#D3DBLEND_INVDESTCOLOR = 10
#D3DBLEND_SRCALPHASAT = 11
#D3DBLEND_BOTHSRCALPHA = 12
#D3DBLEND_BOTHINVSRCALPHA = 13

Explication plus poussé (remerciement à Onilink, car celui-ci est tiré de son tutoriel sur le CBNA) :
"Chaque constante définie un facteur de mélange, s signifie source, et d destination (Rs = Red source, Rd = Red destination).

#D3DBLEND_ZERO : (0, 0, 0, 0)
#D3DBLEND_ONE : (1, 1, 1, 1)

#D3DBLEND_SRCCOLOR : (Rs, Gs, Bs, As)
#D3DBLEND_DESTCOLOR : (Rd, Gd, Bd, Ad)

#D3DBLEND_INVSRCCOLOR : (1–Rs, 1–Gs, 1–Bs, 1–As)
#D3DBLEND_INVDESTCOLOR : (1–Rd, 1–Gd, 1–Bd, 1–Ad)

#D3DBLEND_SRCALPHA : (As, As, As, As)
#D3DBLEND_DESTALPHA : (Ad, Ad, Ad, Ad)

#D3DBLEND_INVSRCALPHA : (1–As, 1–As, 1–As, 1–As)
#D3DBLEND_INVDESTALPHA : (1–Ad, 1–Ad, 1–Ad, 1–Ad)

#D3DBLEND_SRCALPHASAT : (f, f, f, 1) -> f = min(As, 1–Ad)


Notre résultat seras donc calculé de cette manière :
mélange = [source] * [facteur mélange source] + [destination] * [facteur mélange destination]

Je tient a préciser qu'ici, les composantes de nos couleurs donc Rs, Gs, Bs, As et Rd, Gs, Bs, As, seront rapportées a des valeurs comprises entre 0 et 1 pour le calcul (le blanc seras donc (1,1,1,1) et le noir (0,0,0,0) , le gris (0.5, 0.5, 0.5, 0.5)).

Pour que vous compreniez mieux voici quelques modes de mélanges.

- Mode normal
Sprite3DBlendingMode(#D3DBLEND_SRCALPHA, #D3DBLEND_INVSRCALPHA).

mélange = [source] * [As,As,As,As] + [destination] * [1-As,1-As,1-As,1-As]

- Mode additif
Sprite3DBlendingMode( #D3DBLEND_ONE, #D3DBLEND_ONE)

mélange = [source] * [1,1,1,1] + [destination] * [1,1,1,1]
mélange = [source] + [destination]"


L'image :
Pour le png, utilisez une image de votre choix, il faut juste qu'elle ait plusieurs couleurs et du contraste pour mieux voir les effets. Éventuellement, avec un canal alpha c'est encore mieux ;).

Vous pouvez utilisez celle-ci :
Image


Et maintenant l'exemple complet
Le code :

Code : Tout sélectionner

;{ ************************ Infos **************************
; purebasic 4.51
; exemple by blendman 03/2011
; effet de lumière, blendmode
; (ici, nous trouvons juste des informations)
;}

;{************************ variables, constante *************
; tout d'abord, on définit nos constantes
;

  #window  = 0 ; constante pour la fenêtre
  #fire       = 0; constante pour le sprite

;}

;{ ************************ initialisation ******************
;ici, on initialise tout ce qui est nécessaire pour le fonctionnement du programme
InitKeyboard () ; le clavier
InitSprite() ; on initialise les sprites
InitSprite3D() ; on va utiliser un sprite3D, il faut initialiser cela
UsePNGImageDecoder() ; enfin, on a besoin du "decoder" png, car notre image est en png
;}



;{ ************************ open window *********************
;ensuite, on ouvre la fenêtre et on crée l'écran
OpenWindow(#window, 0, 0,800, 600, "Fx et blendmode" , #PB_Window_SystemMenu|#PB_Window_BorderLess |#PB_Window_ScreenCentered ) ; d'abord, on crée la fenêtre
OpenWindowedScreen( WindowID (#window),0,0, 800,600, 1, 0,0) ; on crée un écran contenu dans la fenêtre
;}

;{ ************************ sprite et loading ***************
;dans cette partie on charge notre sprite, et on crée le sprite3D à partir de celui-ci. 
;Le sprite3D est plus ou moins une sorte de plan sur lequel notre image est dessinée.
; on doit utiliser un sprite3D pour gérer la transparence des png.
LoadSprite(#fire,"fx.png",#PB_Sprite_AlphaBlending|#PB_Sprite_Texture) ; on charge le png. 
;Il est important de mettre les paramètres
;#PB_Sprite_AlphaBlending|#PB_Sprite_Texture
; pour gérer la transprance du png
CreateSprite3D(#fire,#fire) ; là, on crée le sprite 3D
;}

;{ ************************ boucle principale ***************
;puis on crée notre boucle principale
Repeat ; la boucle principale se répète jusqu'à "until" (voir en bas du code)

FlipBuffers () ; inversion du buffer
ClearScreen ( RGB (125,125,125)) ; on efface l'écran avec une couleur grise 

Event= WindowEvent () ; on regarde les évènements dans la fenêtre
ExamineKeyboard () ; on doit lancer ceci pour pouvoir utiliser les touches du clavier


; voici la partie où on va
; s'occuper des mode de fusion (blend mode) :

Start3D() ; tout d'abord, il faut démarrer le mode "3D"
; mode de fusion add
Sprite3DBlendingMode(7,2) ; avec ce code on définit un mode de fusion : ici, c'est le mode "additif" (donne un effet de lumière aux sprites) 
;edit : j'ai changé le mode de (2,2) en (7,2), cela permet de pouvoir gérer la transparence sur les sprite3D ;)
DisplaySprite3D(#fire, 100,200) ; on dessine le sprite
Sprite3DBlendingMode(5,6) ; et on n'oublie pas de revenir au blendmode normal :)

;mode de fusion multiply (produit) ;un autre mode de fusion
Sprite3DBlendingMode(9,6) ; on définit donc le nouveau mode de fusion pour notre/nos sprite
DisplaySprite3D(#fire, 200,200) ; on les dessine
Sprite3DBlendingMode(5,6) ; et on remet en blendmode normal

; mode de fusion normal
Sprite3DBlendingMode(5,6) ; le nouveau mode (ici, j'ai choisit le mode normal, pour comparer avec les autres
DisplaySprite3D(#fire, 300,200) ; on dessine le sprite
Sprite3DBlendingMode(5,6) ;on revient au mode normal

; mode de fusion screen
Sprite3DBlendingMode(9,2) ; on définit donc le nouveau mode de fusion pour notre/nos sprite
DisplaySprite3D(#fire, 100,400); on  dessine
Sprite3DBlendingMode(5,6) ;on revient au mode normal

; mode de fusion invert
Sprite3DBlendingMode(8,4) ; on définit donc le nouveau mode de fusion pour notre/nos sprite
DisplaySprite3D(#fire, 200,400); on dessine
Sprite3DBlendingMode(5,6);on revient au mode normal
Stop3D() ; on a terminé de dessiner nos sprites3D, on arrête donc le mode 3D.

Until Event= #PB_Event_CloseWindow Or KeyboardPushed ( #PB_Key_Escape ) ;ici, on indique que si on clique sur la croix en haut ou que l'on appuie sur la touche échappe, cela arrête le programme.
; vous vous rappelez , en haut, la boucle commence à repeat.... until. Le until c'est ici :).
;}
Et voilà, c'est tout :).

Maintenant, c'est à vous de joueur, et faites de belles lumières et de beaux effets.


Remerciement
Onilink du CBNA pour son tutoriel sur les blendmode, dont celui-ci est inspiré :)
le tutoriel d'Onilink (tutoriel pour game Maker à la base) :
http://cbna.forumactif.com/t10259-tutor ... blend+mode