Metaballs 2D
Publié : lun. 21/mai/2007 20:57
Bonjour,
voici un code qui reproduit l'effet "Metaballs" (désolé c'est pas tres commenté, voir même pas du tout
)
vous aurez besoin de l'image suivante dans le répertoire du programme :

est-ce que quelqu'un aurais une idée d'optimisation de la fonction DisplayMeta pour que le calcul de la metaball se fasse le plus rapidement possible... svp ??
voici un code qui reproduit l'effet "Metaballs" (désolé c'est pas tres commenté, voir même pas du tout

vous aurez besoin de l'image suivante dans le répertoire du programme :

Code : Tout sélectionner
If InitSprite () = 0 Or InitKeyboard()= 0
MessageRequester ("Erreur", "Impossible d'initialiser directx",#PB_MessageRequester_Ok)
End
EndIf
;---------- Plein écran ----------
#WindowWidth = 640
#WindowHeight = 480
If OpenScreen(#WindowWidth, #WindowHeight, 32, "Starfield") = 0
MessageRequester ("Erreur", "Impossible d'ouvrir l'écran",#PB_MessageRequester_Ok)
End
EndIf
;----------------------------------
UsePNGImageDecoder()
EnableDebugger
nSprite = CatchSprite(#PB_Any, ?IMGMeta)
If nSprite = 0
MessageRequester ("Erreur", "Erreur à l'ouverture de la metaball !", #PB_MessageRequester_Ok)
End
EndIf
Structure maStruct
PixelB.c
PixelG.c
PixelR.c
PixelA.c
EndStructure
Global SpriteWidth = SpriteWidth (nSprite)
Global SpriteHeight = SpriteHeight(nSprite)
Global Dim PixelMeta.c (SpriteWidth,SpriteHeight)
DisplaySprite (nSprite, 0, 0)
StartDrawing (ScreenOutput ())
For X = 0 To SpriteWidth
For Y = 0 To SpriteHeight
PixelMeta(X,Y) = Red (Point(X,Y))
Next
Next
StopDrawing()
ClearScreen(0)
FlipBuffers()
ClearScreen (0)
Structure MetaBall
X.w
Y.w
x2.f
y2.f
Rayon.c
EndStructure
#NbMetaBalls = 10
Dim TabMeta.MetaBall (#NbMetaBalls)
For i = 1 To #NbMetaBalls
TabMeta(i)\X = Random(#WindowWidth-SpriteWidth) ;#WindowWidth / 2
TabMeta(i)\Y = Random (#WindowHeight-SpriteHeight) ;#WindowHeight / 2
TabMeta(i)\x2 = Random (50) - 25
TabMeta(i)\y2 = Random (50) - 25
Next
EnableDebugger
CallDebugger
Procedure DisplayMeta(*Meta.MetaBall)
Buffer = DrawingBuffer() + (*Meta\X) << 2
Pitch = DrawingBufferPitch()
Flag = 0
For X = 0 To SpriteWidth
ptr = Buffer + X<<2
For Y = 0 To SpriteHeight
*Pixel.maStruct = ptr + ((*Meta\Y) + Y) * Pitch
coulR.c = *Pixel\PixelR
coulMetaR.c = PixelMeta(X,Y) ;\PixelR
If coulR.c > 0
Flag = 1
EndIf
r2.w = (coulR + coulMetaR)
If r2 >= 128
r2 = 255
EndIf
*Pixel\PixelR = r2
*Pixel\PixelG = 0
*Pixel\PixelB = 0
Next
Next
If Flag = 1
*Meta\x2 = (*Meta\x2) / 10
*Meta\y2 = (*Meta\y2) / 10
Flag = 0
EndIf
EndProcedure
Repeat
ClearScreen (0)
If StartDrawing (ScreenOutput ())
For i = 1 To #NbMetaBalls
TabMeta(i)\x2 = ((TabMeta(i)\x2) * 0.98) + Random (2) - 1
TabMeta(i)\y2 = ((TabMeta(i)\y2) * 0.98) + Random (2) - 1
If (TabMeta(i)\X + TabMeta(i)\x2) >= (#WindowWidth-SpriteWidth) Or (TabMeta(i)\X + TabMeta(i)\x2) <= 0
TabMeta(i)\x2 = -TabMeta(i)\x2
EndIf
If (TabMeta(i)\Y + TabMeta(i)\y2) >= (#WindowHeight-SpriteHeight) Or (TabMeta(i)\Y + TabMeta(i)\y2) <= 0
TabMeta(i)\y2 = -TabMeta(i)\y2
EndIf
TabMeta(i)\X = TabMeta(i)\X + TabMeta(i)\x2
TabMeta(i)\Y = TabMeta(i)\Y + TabMeta(i)\y2
DisplayMeta(@TabMeta(i))
Next
StopDrawing ()
EndIf
FlipBuffers ()
ExamineKeyboard ()
Until KeyboardPushed (#PB_Key_Escape) Or WindowEvent() = #PB_Event_CloseWindow
End
DataSection
IMGMeta: IncludeBinary "MetaBallSeb.png"
; IDE Options = PureBasic v4.00 (Windows - x86)
; CursorPosition = 66
; FirstLine = 39
; Folding = -
; IDE Options = PureBasic v4.00 (Windows - x86)
; CursorPosition = 93
; FirstLine = 81
; Folding = -
est-ce que quelqu'un aurais une idée d'optimisation de la fonction DisplayMeta pour que le calcul de la metaball se fasse le plus rapidement possible... svp ??
