Page 1 sur 1

Fonction FlipSprite

Publié : lun. 06/sept./2004 7:54
par Thyphoon
Salut
J'ai trouvé une solution pour faire une commande de flip sprite (2D)
Direction=0 Mirroire Horizontal
Direction=1 Mirroire Vertical
Mais il y a un petit bug il y a toujours une ligne qui ne bouge pas
Voici le code toute sugestion est la bien venu...

Code : Tout sélectionner

hdc.l = GetDC_(0) 
ReleaseDC_(0, hdc) 

Procedure MirrorSprite(SpriteID.l, Direction.l) 
  hdc = StartDrawing(SpriteOutput(SpriteID)) 
    Height = SpriteHeight(SpriteID) 
    Width = SpriteWidth(SpriteID) 
    If Direction 
      StretchBlt_(hdc, 0, Height, Width, -Height, hdc, 0, 0, Width, Height, #SRCCOPY) 
    Else 
      StretchBlt_(hdc, Width, 0, -Width, Height, hdc, 0, 0, Width, Height, #SRCCOPY) 
    EndIf 
  StopDrawing() 
EndProcedure 

Publié : lun. 06/sept./2004 10:19
par Backup
ce qui aurai ete cool, c'est que tu nous mettes un exemple tout fait et simple de ta procedure en utilisant une forme geometrique pour le sprite !!!! :)
(je suis feneant et j'ai la bulle de creer ça ! :lol:

Publié : lun. 06/sept./2004 10:51
par Thyphoon
Lollll tu as raison :lol:
Voilà :P
Espace pour fliper le sprite
Escape pour sortir
;- Init DirectX
If InitSprite() = 0 Or InitKeyboard() = 0
MessageRequester("Erreur", "Impossible d'initialiser DirectX", 0)
CloseWindow(0) : End
EndIf

res = OpenWindow(0, 0, 0, 640, 480, #PB_Window_TitleBar | #PB_Window_ScreenCentered, "")
OpenWindowedScreen(res, 0, 0, 640, 480, 0, 0, 0)

CreateSprite(1, 50, 50,0)
StartDrawing(SpriteOutput(1))
FrontColor(255, 0, 0)
Line(0, 0, 50,25)
Line (0,0,0,50)
Line(50,25,-50,25)
StopDrawing()

hdc.l = GetDC_(0)
ReleaseDC_(0, hdc)

Procedure MirrorSprite(SpriteID.l, Direction.l)
hdc = StartDrawing(SpriteOutput(SpriteID))
Height = SpriteHeight(SpriteID)
Width = SpriteWidth(SpriteID)
If Direction
StretchBlt_(hdc, 0, Height, Width, -Height, hdc, 0, 0, Width, Height, #SRCCOPY)
Else
StretchBlt_(hdc, Width, 0, -Width, Height, hdc, 0, 0, Width, Height, #SRCCOPY)
EndIf
StopDrawing()
EndProcedure

Repeat
FlipBuffers()
ClearScreen(0,0,0)
ExamineKeyboard()
If KeyboardPushed(#PB_Key_space)
Delay(200)
MirrorSprite(1,0)
EndIf
DisplaySprite(1,320,200)
While WindowEvent():Wend ; evite le plantage clic gauche
Until KeyboardPushed(#PB_Key_Escape)
On remarque donc que la première colone de la pixel ne bouge pas

Publié : lun. 06/sept./2004 11:17
par comtois
j'ai comparé ta procédure avec les essais de fonctions que j'avais fait

La fonction avec buffer , déconne ( gestion incomplète ) , mais reste la plus rapide pour l'instant , à voir quand elle fonctionnera vraiment dans tous les cas si ça ne va pas la ralentir :)

sinon la fonction FlipSprite(no.l) avec des plots met le même temps que ta fonction , l'avantage de la fonction FlipSprite(no.l) c'est qu'elle retourne bien l'ensemble du sprite :)

Code : Tout sélectionner

;- Init DirectX 
If InitSprite() = 0 Or InitKeyboard() = 0 
  MessageRequester("Erreur", "Impossible d'initialiser DirectX", 0) 
  CloseWindow(0) : End 
EndIf 

res = OpenWindow(0, 0, 0, 640, 480, #PB_Window_TitleBar | #PB_Window_ScreenCentered, "") 
OpenWindowedScreen(res, 0, 0, 640, 480, 0, 0, 0) 

Global  adresse , pitch , Format 

CreateSprite(1, 64, 64,0) 
StartDrawing(SpriteOutput(1)) 
FrontColor(255, 0, 0) 
Line(0, 0, 50,25) 
Line (0,0,0,50) 
Line(50,25,-50,25) 
adresse = DrawingBuffer() 
pitch = DrawingBufferPitch() 
Format = DrawingBufferPixelFormat() 
StopDrawing() 

hdc.l = GetDC_(0) 
ReleaseDC_(0, hdc) 

Procedure MirrorSprite(SpriteID.l, Direction.l) 
  hdc = StartDrawing(SpriteOutput(SpriteID)) 
  Height = SpriteHeight(SpriteID) 
  Width = SpriteWidth(SpriteID) 
  If Direction 
    StretchBlt_(hdc, 0, Height, Width, -Height, hdc, 0, 0, Width, Height, #SRCCOPY) 
  Else 
    StretchBlt_(hdc, Width, 0, -Width, Height, hdc, 0, 0, Width, Height, #SRCCOPY) 
  EndIf 
  StopDrawing() 
EndProcedure 

Procedure BufferFlipSprite(no.l) 
  ; bon apparemment ça ne fonctionne qu'avec des multiples de 8 ? 
  ; voir comment le pitch intervient dans le calcul de l'adresse !!
  If Format > 5 
    Nboctet = 4 
  ElseIf Format = 2 Or Format = 3 
    Nboctet = 2 
  Else 
    ProcedureReturn 0 ; je ne vais pas m'emmerder à gérer les autres cas alors que personne ne va utiliser cette procédure :) 
  EndIf  
  For v = 0 To SpriteHeight(no) - 1 
    adr = adresse + ((u + (SpriteWidth(no) * v)) * Nboctet)  
    adr1 = adresse + ((SpriteWidth(no) - 1 - u + (SpriteWidth(no) * v)) * Nboctet) 
    For u = 0 To (SpriteWidth(no) - 1 ) / 2 
      If Nboctet = 4 
        CoulG = PeekL(adr) 
        CoulD = PeekL(adr1) 
        PokeL(adr,CoulD) 
        PokeL(adr1,CoulG) 
        
      Else 
        CoulG = PeekW(adr) 
        CoulD = PeekW(adr1) 
        PokeW(adr,CoulD) 
        PokeW(adr1,CoulG) 
      EndIf  
      adr + Nboctet 
      adr1 - Nboctet 
    Next u 
  Next v 
EndProcedure 

Procedure FlipSprite(no.l) 
  StartDrawing(SpriteOutput(no)) 
  For v = 0 To SpriteHeight(no)-1 
    For u = 0 To (SpriteWidth(no) - 1 ) / 2 
      CoulG = Point(u, v) 
      CoulD = Point(SpriteHeight(no) - 1 - u,v) 
      Plot(u,v,CoulD) 
      Plot(SpriteHeight(no) - 1 - u,v,CoulG) 
    Next u 
  Next v 
  StopDrawing() 
EndProcedure 

Temps = ElapsedMilliseconds() 
For i = 1 To 1000 
  BufferFlipSprite(1) 
Next i  
Total = ElapsedMilliseconds() - Temps 
Debug "Avec Buffer" 
Debug Total 
  
Temps = ElapsedMilliseconds() 
For i = 1 To 1000 
  FlipSprite(1) 
Next i  
Total = ElapsedMilliseconds() - Temps 
Debug "Sans Buffer" 
Debug Total  


Temps = ElapsedMilliseconds() 
For i = 1 To 1000 
  FlipSprite(1) 
Next i  
Total = ElapsedMilliseconds() - Temps 
Debug "Avec StretchBlt_" 
Debug Total  
  
; Repeat 
  ; FlipBuffers() 
  ; ClearScreen(0,0,0) 
  ; ExamineKeyboard() 
  ; If KeyboardReleased(#PB_Key_Space) 
    ; ;Delay(200) 
    ; ;MirrorSprite(1,0) 
    ; BufferFlipSprite(1)
    ; ; FlipSprite(1)
  ; EndIf 
  ; DisplaySprite(1,320,200) 
  ; While WindowEvent():Wend ; evite le plantage clic gauche 
; Until KeyboardPushed(#PB_Key_Escape) 

Publié : lun. 06/sept./2004 11:23
par Thyphoon
Merci ! :D
je pense que pour l'instant je vais utiliser ton FlipSprite ... :)
:wink:

Publié : lun. 06/sept./2004 11:29
par Thyphoon
Parcontre Une petite correction a ta procedure !

Code : Tout sélectionner

Procedure FlipSprite(no.l) 
  StartDrawing(SpriteOutput(no)) 
  For v = 0 To SpriteHeight(no)-1 
    For u = 0 To (SpriteWidth(no) - 1 ) / 2 
      CoulG = Point(u, v) 
      CoulD = Point(SpriteWidth(no) - 1 - u,v) ; remplacement de SpriteHeight par SpriteWidth
      Plot(u,v,CoulD) 
      Plot(SpriteWidth(no) - 1 - u,v,CoulG) ; remplacement de SpriteHeight par SpriteWidth

    Next u 
  Next v 
  StopDrawing() 
EndProcedure 

Publié : lun. 06/sept./2004 19:11
par comtois
exact , avec ma manie de faire des copier coller , voila le résultat :)

Merci d'avoir corriger .

Publié : mar. 07/sept./2004 10:02
par comtois
En cherchant à simplifier la procédure Flipsprite() , pour limiter les calculs dans les boucles , je me suis aperçu que je ne testais pas ta procédure , mais flipsprite() (encore avec ma manie des copier coller) , donc c'est normal que les temps soient identiques :oops:

en refaisant le test , ta fonction bat tous les records , reste à corriger le bug .
Je n'ai pas cherché sur codearchiv , mais je serais étonné qu'on ne puisse pas y trouver une fonction de ce type .

Publié : mar. 07/sept./2004 12:49
par Thyphoon
j'ai regardé sur codearchiv mais j'ai pas trouvé :(
il manque a Purebasic des fonctions rapide pour les sprites 2Ds ! je comprends pas que ça soit si lent sur des machines d'aujordh'ui alors que sur des machines de plus de 10Ans comme sur les A1200 on fait la même choses sans pb et ralentissment apparent !

Publié : mar. 07/sept./2004 13:19
par comtois
as-tu fait une suggestion au sujet de la fonction flip dans la section Suggestion et amélioration ?

Publié : mar. 07/sept./2004 13:28
par Thyphoon
A non je n'y ai pas pensé...j'y vais de ce pas !! :o) :P

Publié : dim. 10/oct./2004 21:20
par Dräc
Petite correction :

Dans ta routine MirrorSprite, il faut remplacer

StretchBlt_(hDC, Width, 0, -Width, Height, hDC, 0, 0, Width, Height, #SRCCOPY)
par
StretchBlt_(hDC, Width-1, 0, -Width, Height, hDC, 0, 0, Width, Height, #SRCCOPY)

et
StretchBlt_(hDC, 0, Height, Width, -Height, hDC, 0, 0, Width, Height, #SRCCOPY)
par
StretchBlt_(hDC, 0, Height-1, Width, -Height, hDC, 0, 0, Width, Height, #SRCCOPY)

afin d’effectuer le traitement jusqu’aux derniers bits ;)

Publié : lun. 11/oct./2004 13:06
par Thyphoon
Merci beaucoup !!! :P
Tes un as !!