Sprite, Sprite3D...

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Sprite, Sprite3D...

Message par Dr. Dri »

J'ai été inspiré hier soir ^^

Code : Tout sélectionner

Structure PB_Sprite
  Sprite.l      ; DirectDrawSurface7 pointer
  Width.w       ; Current width of the sprite (could change if ClipSprite() is used)
  Height.w      ; Current height of the sprite (could change if ClipSprite() is used)
  Depth.w       ; Sprite depth
  Mode.w        ; Sprite mode, as descripted in LoadSprite()
  FileName.l    ; Pointer on the filename, if any
  RealWidth.w   ; Original width of the sprite when it was loaded
  RealHeight.w  ; Original height of the sprite when it was loaded
  ClipX.w       ; X offset if ClipSprite()
  ClipY.w       ; Y offset if ClipSprite()
EndStructure

Procedure SpriteRealWidth(Sprite.l)
  Protected RealWidth.l, *sprite.PB_Sprite
  
  *sprite = IsSprite(Sprite)
  If *sprite
    RealWidth = *sprite\RealWidth
  EndIf
  
  ProcedureReturn RealWidth
EndProcedure

Procedure SpriteRealHeight(Sprite.l)
  Protected RealHeight.l, *sprite.PB_Sprite
  
  *sprite = IsSprite(Sprite)
  If *sprite
    RealHeight = *sprite\RealHeight
  EndIf
  
  ProcedureReturn RealHeight
EndProcedure

Procedure SpriteClipX(Sprite.l)
  Protected ClipX.l, *sprite.PB_Sprite
  
  *sprite = IsSprite(Sprite)
  If *sprite
    ClipX = *sprite\ClipX
  EndIf
  
  ProcedureReturn ClipX
EndProcedure

Procedure SpriteClipY(Sprite.l)
  Protected ClipY.l, *sprite.PB_Sprite
  
  *sprite = IsSprite(Sprite)
  If *sprite
    ClipY = *sprite\ClipY
  EndIf
  
  ProcedureReturn ClipY
EndProcedure
Dri ;)
Dernière modification par Dr. Dri le lun. 30/janv./2006 19:30, modifié 1 fois.
Avatar de l’utilisateur
Crystal Noir
Messages : 892
Inscription : mar. 27/janv./2004 10:07

Message par Crystal Noir »

sympa ^^ aller hop sur devmag la news lol
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

J'comprend pas trop.
T'as réécrit une structure qui existé déjà, mais non donnée ?
Et qd on fais des GrabSprite(), on peut récupérer certaines valeurs c'est ça ?
Les largeurs/hauteurs réelles / clippées ?
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Tient j'avais pas vu les questions de lionel_om
Pour répondre aux trois questions
-présente dans le purebasic library descriptor (dans le dossier LibrarySDK)
-je sais pas
-euh

Maintenant j'ai fait remonter ce topic, parce que j'ai fait une fonction maison qui a été mainte fois demandée (ClipSprite3D) et c'était tellement simple que j'en suis presque dégouté...

Allez on commence par les remerciements ^^
Cpl.Bator avec son cube Sprite3D qui m'a donné la motivation
comtois par le biais de qui je connaissais le principe des textures UV
(je fais pas de 3D mais je regarde toujours ses codes tres intéressants =)

Code : Tout sélectionner

Procedure SwapMemory(MemoryID1.l, MemoryID2.l, Length.l)
  Protected Swap.l, MemoryID3.l
  
  If MemoryID1 And MemoryID2 And Length > 0
    
    MemoryID3 = AllocateMemory(Length)
    
    If MemoryID3
      CopyMemory(MemoryID1, MemoryID3, Length)
      CopyMemory(MemoryID2, MemoryID1, Length)
      CopyMemory(MemoryID3, MemoryID2, Length)
      
      FreeMemory(MemoryID3)
      Swap = #True
    EndIf
    
  EndIf
  
  ProcedureReturn Swap
EndProcedure

Structure D3DTLVERTEX
  sx.f
  sy.f
  sz.f
  rhw.f
  color.l
  specular.l
  tu.f
  tv.f
EndStructure

Structure PB_Sprite3D
  *Texture.IDirectDrawSurface7
  Vertice.D3DTLVERTEX[4]
  Width.w
  Height.w
EndStructure

Procedure.w Sprite3DWidth(Sprite3D.l)
  Protected Width.w, *Sprite3D.PB_Sprite3D
  
  *Sprite3D = IsSprite3D(Sprite3D)
  
  If *Sprite3D
    Width = *Sprite3D\Width
  EndIf
  
  ProcedureReturn Width
EndProcedure

Procedure.w Sprite3DHeight(Sprite3D.l)
  Protected Height.w, *Sprite3D.PB_Sprite3D
  
  *Sprite3D = IsSprite3D(Sprite3D)
  
  If *Sprite3D
    Height = *Sprite3D\Height
  EndIf
  
  ProcedureReturn Height
EndProcedure

Procedure.l ClipSprite3D(Sprite3D.l, x.l, y.l, Width.l, Height.l)
  Protected Clip.l, *Sprite3D.PB_Sprite3D
  
  *Sprite3D = IsSprite3D(Sprite3D)
  
  If Width = #PB_Default
    Width = Sprite3DWidth(Sprite3D)
  EndIf
  
  If Height = #PB_Default
    Height = Sprite3DHeight(Sprite3D)
  EndIf
  
  If *Sprite3D And Width > 0 And Height > 0
    *Sprite3D\Vertice[0]\tu = x / *Sprite3D\Width
    *Sprite3D\Vertice[0]\tv = y / *Sprite3D\Height
    
    *Sprite3D\Vertice[1]\tu = (x + Width) / *Sprite3D\Width
    *Sprite3D\Vertice[1]\tv = y / *Sprite3D\Height
    
    *Sprite3D\Vertice[2]\tu = x / *Sprite3D\Width
    *Sprite3D\Vertice[2]\tv = (y + Height) / *Sprite3D\Height
    
    *Sprite3D\Vertice[3]\tu = (x + Width)  / *Sprite3D\Width
    *Sprite3D\Vertice[3]\tv = (y + Height) / *Sprite3D\Height
    
    Clip = #True
  EndIf
  
  ProcedureReturn Clip
EndProcedure

Procedure.l MirrorSprite3D(Sprite3D.l)
  Protected Mirror.l, *Sprite3D.PB_Sprite3D
  
  *Sprite3D = IsSprite3D(Sprite3D)
  
  If *Sprite3D
    SwapMemory(*Sprite3D\Vertice[0], *Sprite3D\Vertice[1], SizeOf(D3DTLVERTEX))
    SwapMemory(*Sprite3D\Vertice[2], *Sprite3D\Vertice[3], SizeOf(D3DTLVERTEX))
    
    Mirror = #True
  EndIf
  
  ProcedureReturn Mirror
EndProcedure

Procedure.l FlipSprite3D(Sprite3D.l)
  Protected Mirror.l, *Sprite3D.PB_Sprite3D
  
  *Sprite3D = IsSprite3D(Sprite3D)
  
  If *Sprite3D
    SwapMemory(*Sprite3D\Vertice[0], *Sprite3D\Vertice[2], SizeOf(D3DTLVERTEX))
    SwapMemory(*Sprite3D\Vertice[1], *Sprite3D\Vertice[3], SizeOf(D3DTLVERTEX))
    
    Mirror = #True
  EndIf
  
  ProcedureReturn Mirror
EndProcedure
Dri 0X

PS. Promis un exemple et des explications d'ici demain ^^

[edit]j'ai ajouté mirror, flip et swap[/edit]
Dernière modification par Dr. Dri le lun. 30/janv./2006 19:34, modifié 1 fois.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Bien vu :)
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Bon bah finalement un petit exemple c'est pas long à faire ^^

Pour les explications, la fonction s'utilise comme le ClipSprite de base sauf que si on donne -1 pour la largeur ou la hauteur, la fonction prendra la largeur ou la hauteur d'origine.

Si le clipping va jusqu'en dehors du Sprite3D, je vous laisse constater de ce qui se passe (la texture semble être répétée en boucle)

voici un exemple
pour avoir un clipping qui déborde du sprite3D il suffit de décommenter la ligne de code en question

Code : Tout sélectionner

If InitSprite() = #False Or InitSprite3D() = #False Or InitKeyboard() = #False
  End
EndIf

If OpenWindow(0, 0, 0, 640, 480, #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered, "Sprite3D") = #False
  End
EndIf

If OpenWindowedScreen(WindowID(), 0, 0, 640, 480, #False, 0, 0) = #False
  End
EndIf

;crée une texture de 128*128 avec un carré de 64*64 en bas à droite
;et un cercle en plein milieu
CreateSprite(0, 128, 128, #PB_Sprite_Texture)
If StartDrawing( SpriteOutput(0) )
  Box(0, 0, 128, 128, $FF0000)
  Box(64, 64, 64, 64, $00FFFF)
  Circle(64, 64, 32, $000000)
  StopDrawing()
EndIf

If IsSprite(0) And CreateSprite3D(0, 0)
 
  inc = 1
 
  Repeat
    ExamineKeyboard()
    ClearScreen(0, 0, 0)
   
    offset + inc
    If offset = 20 Or offset = 0
      inc = -inc
    EndIf
    
    ;la touche espace clip le sprite de manière à n'avoir que le carré jaune
    If KeyboardPushed(#PB_Key_Space)
      ClipSprite3D(0, 64, 64, 64, 64)
      ;pour déborder du Sprite3D et voir ce qu'il advient, décomenter la ligne suivante
      ;ClipSprite3D(0, 64, 64, 128, 128)
    Else
      ;quand la touche est relachée ca enleve le clipping
      ClipSprite3D(0, 0, 0, #PB_Default, #PB_Default)
    EndIf
   
    If Start3D()
      TransformSprite3D(0,  0,0,1,  100,0,1,  100,100,1,  0,100,1)
      DisplaySprite3D(0, 0, offset)
     
      TransformSprite3D(0,  0,0,1,  100,0,1,  100,100,1,  0,100,1)
      DisplaySprite3D(0, 150, offset)
     
      TransformSprite3D(0,  0,0,1,  200,20,1.5,  0,100,1,  0,100,1)
      DisplaySprite3D(0,  200,  200)
      TransformSprite3D(0,  200,20,1,  200,20,1.5,  200,80,1.5,  0,100,1)
      DisplaySprite3D(0, 200, 200+offset)
     
      Stop3D()
    EndIf
   
    If KeyboardPushed(#PB_Key_Escape)
      Quit = #True
    EndIf
   
    Repeat
      Event = WindowEvent()
      If Event = #PB_Event_CloseWindow
        Quit = #True
      EndIf
    Until Event = #Null
   
    FlipBuffers()
  Until Quit
 
EndIf
Dri :D
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

J'ai codé deux fonctions supplémentaires, MirrorSprite3D (retournement horizontal) et FlipSprite (retournement vertical), avec un exemple d'utilisation ^^

Ce qu'il y a à savoir:
Les effets de ces fonctions sont annulées par un ClipSprite3D
pour revenir à la normal il faut rapeller la fonction
(par exemple deux mirrorsprite3d d'affilé ca ne change rien)

l'exemple:
appuyez sur M pour donner un effet mirroir au sprite
appuyez sur F pour donner un effet flip au sprite

il se peut que la touche M ne fonctionne pas, auquel cas c'est la touche ",?" qui correspond au M du clavier QWERTY

Code : Tout sélectionner

If InitSprite() = #False Or InitSprite3D() = #False Or InitKeyboard() = #False
  End
EndIf

If OpenWindow(0, 0, 0, 640, 480, #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered, "Sprite3D") = #False
  End
EndIf

If OpenWindowedScreen(WindowID(), 0, 0, 640, 480, #False, 0, 0) = #False
  End
EndIf

;crée une texture de 128*128 avec un carré de 64*64 en bas à droite
;et un cercle en plein milieu
CreateSprite(0, 128, 128, #PB_Sprite_Texture)
If StartDrawing( SpriteOutput(0) )
  Box(0, 0, 128, 128, $FF0000)
  Box(64, 64, 64, 64, $00FFFF)
  Circle(64, 64, 32, $FF00FF)
  StopDrawing()
EndIf
TransparentSpriteColor(0, $FF, $00, $FF)

If IsSprite(0) And CreateSprite3D(0, 0)
  
  inc = 1
  
  Repeat
    ClearScreen($FF, $FF, $FF)
    
    offset + inc
    If offset = 128 Or offset = 0
      inc = -inc
    EndIf
    
    If ExamineKeyboard()
      
      If (KeyboardPushed(#PB_Key_M) And mirror = #False) Or (KeyboardReleased(#PB_Key_M) And mirror = #True)
        MirrorSprite3D(0)
        mirror ! #True
      EndIf
      
      If (KeyboardPushed(#PB_Key_F) And flip = #False) Or (KeyboardReleased(#PB_Key_F) And flip = #True)
        FlipSprite3D(0)
        flip ! #True
      EndIf
      
      If KeyboardPushed(#PB_Key_Escape)
        Quit = #True
      EndIf
      
    EndIf
    
    If Start3D()
      
      TransformSprite3D(0,  0,0,1,  200,20,1.5,  0,100,1,  0,100,1)
      DisplaySprite3D(0,  200,  200)
      TransformSprite3D(0,  200,20,1,  200,20,1.5,  200,80,1.5,  0,100,1)
      DisplaySprite3D(0, 200, 200+offset)
      
      Stop3D()
    EndIf
    
    Repeat
      Event = WindowEvent()
      If Event = #PB_Event_CloseWindow
        Quit = #True
      EndIf
    Until Event = #Null
    
    FlipBuffers(1)
  Until Quit
  
EndIf
Dri 0X
Répondre