Page 1 sur 1

Sprite, Sprite3D...

Publié : ven. 04/nov./2005 10:19
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 ;)

Publié : ven. 04/nov./2005 11:28
par Crystal Noir
sympa ^^ aller hop sur devmag la news lol

Publié : ven. 04/nov./2005 12:43
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 ?

Publié : dim. 29/janv./2006 16:12
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]

Publié : dim. 29/janv./2006 16:29
par comtois
Bien vu :)

Publié : dim. 29/janv./2006 16:31
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

Publié : lun. 30/janv./2006 19:38
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