Spock a écrit :je voulais savoir, (et tu l'a surement deja expliqué, mais j'ai du zaper )
pourquoi tu utilises la Lib Sprites comme calque , a la place de la Lib images ?
(ou j'ai peut etre pas tout compris )
En fait, j'utilise les deux libs : sprite (pour l'affichage temporaire) et image (pour le dessin)
C'est toi qui m'avait conseillé les sprites car c'était très rapide et c'est vrai
.
J'utilise la lib sprite uniquement pour l'affichage.
Lorsque je dessine sur l'écran :
- je conserve la position X et Y (j'utilise windowmouseX() et windowmouseY() car avec mouseX() et MouseY(), j'ai quelques soucis avec ma tablette graphique, au niveau vitesse, de plus, ça m'évite de capturer la souris dans l'écran
)
- j'affiche le papier (dans mon exemple c'est #spfond) + les calques (les sprites) en dessous de mon calque courant : donc ça va très vite.
- je dessine les images de ma brosse, avec les opérations (rotations, scale, couleur, etc...) sur le sprite courant, puis, je l'affiche
- je dessine les images de ma brosse, avec les opérations (rotations, scale, couleur, etc...) sur mon image
- j'affiche les calques du dessus (les sprites).
L'idéal serait d'utiliser les threads pour : conserver la position X et Y de la souris, dessiner sur le sprite, dessiner sur l'image.
Dessiner l'image sur le sprite est long si c'est une image qui fait plus de 1024*768.
Par contre, dessiner des sprites sur l'écran est très rapide, donc on peut avoir beaucoup de calques d'afficher ^^.
Voilà le code de base (très simplifié ^^) pour mieux comprendre :
Code : Tout sélectionner
; Animatoon : exemple basique du code pour dessiner.
;{ enumeration
Enumeration ; menuitem
#menu_Clear
#menu_LayerAdd
EndEnumeration
Enumeration ; gadgets
#G_BrushSize
#G_BrushAlpha
#G_BrushColor
#G_layerList
EndEnumeration
#SpFond = 0
#ImgBrushColor = 0
;}
;{ structure
Structure sBrush
Size.w
Alpha.a
Scatter.w
Rotation.w
Color.i
R.a
G.a
b.a
EndStructure
Global brush.sBrush
With brush
\size = 10
\Alpha = 120
\r = Random(255)
\g = Random(255)
\b = Random(255)
\Color = RGBA(\r,\g,\b,\Alpha)
EndWith
Structure sLayer
Alpha.a
View.a
Bm.a
Position.a
Image.i
ImageAlpha.i
Sprite.i
Gadget.i
X.w
y.w
Nom$
W.w
H.w
EndStructure
Global Dim layer.sLayer(0)
;}
Global doc_w,doc_h,layerId,NewPainting,canvasX,canvasY,Zoom.w
doc_w = 1024
doc_h = 768
Zoom = 100
;{ procedures
Procedure Layer_Add()
n =ArraySize(layer())
With layer(n)
\Alpha = 255
\view = 1
\Position = n
\Nom$ = "Layer"+Str(n)
\Image = CreateImage(#PB_Any, doc_w, doc_h, 32,#PB_Image_Transparent)
\ImageAlpha = CreateImage(#PB_Any, doc_w, doc_h, 32,#PB_Image_Transparent)
\Sprite = CreateSprite(#PB_Any, doc_w,doc_h,#PB_Sprite_AlphaBlending)
If StartDrawing(SpriteOutput(\Sprite)) ; on efface le sprite
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0,0,doc_w,doc_h,RGBA(0,0,0,0))
StopDrawing()
EndIf
layerId = n
EndWith
ClearGadgetItems(#G_layerList)
For i =0 To n
AddGadgetItem(#G_layerList,i,layer(i)\Nom$)
Next i
ReDim layer(n+1)
EndProcedure
Procedure Layer_Draw(i)
z.d =Zoom *0.01
Select layer(i)\Bm
Case 0
SpriteBlendingMode(#PB_Sprite_BlendSourceAlpha, #PB_Sprite_BlendInvertSourceAlpha)
Case 1 ; multiply
SpriteBlendingMode(4,0)
Case 2 ; Add
SpriteBlendingMode(3,1)
EndSelect
ZoomSprite(layer(i)\Sprite,z*ImageWidth(layer(i)\Image),z*ImageHeight(layer(i)\Image))
DisplayTransparentSprite(layer(i)\Sprite,layer(i)\x+canvasX,layer(i)\y+canvasY,layer(i)\Alpha)
SpriteBlendingMode(#PB_Sprite_BlendSourceAlpha, #PB_Sprite_BlendInvertSourceAlpha)
EndProcedure
Procedure Layer_Update(i)
EndProcedure
Procedure ScreenUpdate()
If NewPainting
If StartDrawing(SpriteOutput(Layer(layerId)\Sprite)) ; on efface le sprite
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0,0,doc_w,doc_h,RGBA(0,0,0,0))
DrawAlphaImage(ImageID(layer(layerid)\Image),0,0)
StopDrawing()
EndIf
NewPainting = 0
EndIf
ClearScreen(RGB(120,120,120))
DisplayTransparentSprite(#SpFond,canvasX,canvasY)
For i= 0 To ArraySize(layer())-1
Layer_draw(i)
Next i
FlipBuffers()
EndProcedure
Procedure UpdateColorPreview()
If StartDrawing(ImageOutput(#ImgBrushColor))
Box(0,0,OutputWidth(),OutputHeight(),RGB(brush\R,brush\G,brush\B))
StopDrawing()
EndIf
SetGadgetState(#G_BrushColor,ImageID(#ImgBrushColor))
EndProcedure
;}
;{ openwindow
screenwidth = 1200
screenheight = 768
OpenWindow(0, 0, 0, screenwidth, screenheight, "Animatoon base", #PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget)
InitSprite()
ScreenX = 100
ScreenY = 0
If OpenWindowedScreen(WindowID(0),ScreenX,ScreenY,screenwidth-ScreenX-100, screenheight)=0
MessageRequester("Error", "Can't Open Screen!", 0)
End
EndIf
;{ menu
If CreateMenu(0,WindowID(0))
MenuTitle("Editions")
MenuItem(#Menu_Clear,"Effacer")
MenuTitle("Calques")
MenuItem(#Menu_LayerAdd,"Ajouter calque")
EndIf
;}
;{ gadgets
If PanelGadget(#PB_Any,0,0,ScreenX-5,WindowHeight(0))
x = 10
y = 10
SpinGadget(#G_BrushSize,x,y,50,20,1,500,#PB_Spin_Numeric):y+25
GadgetToolTip(#G_BrushSize,"Taille de la brosse")
SetGadgetState(#G_BrushSize,brush\Size)
SpinGadget(#G_BrushAlpha,x,y,50,20,0,255,#PB_Spin_Numeric):y+25
GadgetToolTip(#G_BrushAlpha,"Opacité de la brosse")
SetGadgetState(#G_BrushAlpha,brush\Alpha)
If CreateImage(#ImgBrushColor,64,64)
UpdateColorPreview()
EndIf
ImageGadget(#G_BrushColor,x,y,64,64,ImageID(#ImgBrushColor))
CloseGadgetList()
EndIf
If PanelGadget(#PB_Any,WindowWidth(0)-95,0,105,WindowHeight(0))
x = 10
y = 10
ListViewGadget(#G_layerList,x,y,80,100)
CloseGadgetList()
EndIf
;}
;{ autre
If CreateSprite(#SpFond,Doc_w,doc_h,#PB_Sprite_AlphaBlending)
If StartDrawing(SpriteOutput(#SpFond))
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0,0,doc_w,doc_h,RGBA(160,160,160,255))
StopDrawing()
EndIf
EndIf
Layer_Add()
ScreenUpdate()
;}
;}
Repeat
mx = WindowMouseX(0) - ScreenX
my = WindowMouseY(0) - ScreenY
Repeat
Event = WaitWindowEvent(1)
EventGadget = EventGadget()
Select event
Case #PB_Event_Gadget
Select EventGadget
Case #G_layerList
LayerId =GetGadgetState(#G_layerList)
Case #G_BrushSize
brush\Size = GetGadgetState(#G_BrushSize)
Case #G_BrushAlpha
brush\Alpha = GetGadgetState(#G_BrushAlpha)
brush\color =RGBA(brush\r,brush\g,brush\b,brush\Alpha)
Case #G_BrushColor
If EventType() = #PB_EventType_LeftDoubleClick
col = ColorRequester(brush\color)
brush\r = Red(Col)
brush\g = Green(Col)
brush\b = Blue(Col)
brush\color =RGBA(brush\r,brush\g,brush\b,brush\Alpha)
UpdateColorPreview()
EndIf
EndSelect
Case #PB_Event_Menu
Select EventMenu()
Case #menu_Clear
If StartDrawing(ImageOutput(Layer(layerId)\Image)) ; on efface le sprite
DrawingMode(#PB_2DDrawing_AllChannels)
Box(0,0,doc_w,doc_h,RGBA(0,0,0,0))
StopDrawing()
EndIf
NewPainting = 1
ScreenUpdate()
Case #menu_LayerAdd
Layer_Add()
EndSelect
Case #PB_Event_LeftClick ; mouse button up
paint = 0
Case #WM_LBUTTONDOWN ; mouse button down : pas d'équivalent event général
If mx>=0 And my>=0 And mx<ScreenWidth() And my<ScreenHeight()
paint = 1
EndIf
Case #PB_Event_CloseWindow
End
EndSelect
Until event = 0 Or paint = 1
If mx>=0 And my>=0 And mx<ScreenWidth() And my<ScreenHeight()
If paint = 1
; on peint, j'update donc
ClearScreen(RGB(120,120,120))
DisplayTransparentSprite(#SpFond,canvasX,canvasY)
For i= 0 To ArraySize(layer())-1
If i< layerId
Layer_draw(i)
Else
Break
EndIf
Next i
; je peins sur le sprite, attention c'est temporaire, uniquement pour l'affichage rapide.
If StartDrawing(SpriteOutput(layer(layerid)\Sprite))
DrawingMode(#PB_2DDrawing_AlphaBlend)
xx = mx + Random(brush\Scatter)-Random(brush\Scatter)
yy = my + Random(brush\Scatter)-Random(brush\Scatter)
Circle(xx,yy,Brush\size,brush\color)
StopDrawing()
EndIf
; puis je peins sur l'image, que je conserve
If StartDrawing(ImageOutput(layer(layerid)\Image))
DrawingMode(#PB_2DDrawing_AlphaBlend)
;xx = mx - Brush\size + Random(brush\Scatter)-Random(brush\Scatter)
;yy = my - Brush\size + Random(brush\Scatter)-Random(brush\Scatter)
Circle(xx,yy,Brush\size,brush\color)
StopDrawing()
EndIf
For i= layerId To ArraySize(layer())-1
layer_draw(i)
Next i
FlipBuffers()
Else
EndIf
EndIf
; autre : keyboards par exemple
Until Event = #PB_Event_CloseWindow
Pour le moment, je n'ai pas encore travaillé sur l'optimisation du code, mais comme c'est encore assez fluide, je ferais ça plus tard ^^.