Sprite3D [win] clip,color,alpha,mirror,handle,copy,anim,FX

Share your advanced PureBasic knowledge/code with the community.
User avatar
IceSoft
Addict
Addict
Posts: 1682
Joined: Thu Jun 24, 2004 8:51 am
Location: Germany

Post by IceSoft »

eddy wrote:Jeep, it's a mod of windows Sprite3D.
We need to know the PB structures for other plateforms.
That is @Fred's job.
Hope he see also the improvent for PureBasic if the Sprite/Sprite3D structures are part of the PureBasic documentation.
Belive! C++ version of Puzzle of Mystralia
<Wrapper>4PB, PB<game>, =QONK=, PetriDish, Movie2Image, PictureManager,...
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

zxtunes.com wrote: Still have bug - press ALT+TAB and have debugger error - "Sprite 3D must be called before Sprite3DBlendingMode".

Code: Select all

Repeat 
   ClearScreen(RGB(0, 0, 0)) 
    
   Start3D() 
SetSprite3DBlend_NORMAL() <- error

Code: Select all

      DisplaySprite3D(10, 100, 200) 
I tested and I have the same message.
It's not a problem from 16 bit mode
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
zxtunes.com
Enthusiast
Enthusiast
Posts: 375
Joined: Wed Apr 23, 2008 7:51 am
Location: Saint-Petersburg, Russia
Contact:

Post by zxtunes.com »

eddy wrote:
I tested and I have the same message.
It's not a problem from 16 bit mode
I also did not speak that it is a problem 16 bit. ;)

in 16 bit bug since 4.00 and bug till now, it not your fault.

Probably it is fault PNG of the decoder?
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

It's not a bug : http://www.purebasic.fr/english/viewtopic.php?t=33232

Since 2.50, PB can manage "the switch back to OS" (ALT+TAB)
My example is incomplete that's why you have this error.

[Edit]
IsScreenActive exists since 2.50 and fixed in 4.00
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Post by Rook Zimbabwe »

Hey Eddy, I have a question before I try to implement your fantastic new code:

When you click to get the handle of the Sprite 3d... Does the clipping include the transparent areas?

Some of my sprites overlap a bit! :D
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
zxtunes.com
Enthusiast
Enthusiast
Posts: 375
Joined: Wed Apr 23, 2008 7:51 am
Location: Saint-Petersburg, Russia
Contact:

Post by zxtunes.com »

eddy wrote:It's not a bug : http://www.purebasic.fr/english/viewtopic.php?t=33232

Since 2.50, PB can manage "the switch back to OS" (ALT+TAB)
My example is incomplete that's why you have this error.

[Edit]
IsScreenActive exists since 2.50 and fixed in 4.00
I had in view of Alphachennel bug in 16bit mode (shit on screen) not ALT+TAB.
User avatar
zxtunes.com
Enthusiast
Enthusiast
Posts: 375
Joined: Wed Apr 23, 2008 7:51 am
Location: Saint-Petersburg, Russia
Contact:

Post by zxtunes.com »

Eddy you planed create analogHGE useful function "SetHotSpot" - "Sets the sprite anchor point"?
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

zxtunes.com wrote:Eddy you planed create analogHGE useful function "SetHotSpot" - "Sets the sprite anchor point"?
There's already a new function SetSprite3DHandle
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
zxtunes.com
Enthusiast
Enthusiast
Posts: 375
Joined: Wed Apr 23, 2008 7:51 am
Location: Saint-Petersburg, Russia
Contact:

Post by zxtunes.com »

eddy wrote:
zxtunes.com wrote:Eddy you planed create analogHGE useful function "SetHotSpot" - "Sets the sprite anchor point"?
There's already a new function SetSprite3DHandle
WOW :shock:

Your code have many surprised for me.

Its powerfull!!

I dreamed of it (clipsprite and etc) 4 years!! (has not appeared yet HGE Wrapper)
User avatar
Fluid Byte
Addict
Addict
Posts: 2336
Joined: Fri Jul 21, 2006 4:41 am
Location: Berlin, Germany

Post by Fluid Byte »

zxtunes.com wrote:I dreamed of it (clipsprite and etc) 4 years!! (has not appeared yet HGE Wrapper)
You could have saved that waiting time by simply using the forum search ... Image
Windows 10 Pro, 64-Bit / Whose Hoff is it anyway?
User avatar
eddy
Addict
Addict
Posts: 1479
Joined: Mon May 26, 2003 3:07 pm
Location: Nantes

Post by eddy »

v1.5
- ADDED : animation
- ADDED : ExamineSprite3D (for animation and fx)
- UPDATE : mirroring support (for clipSprite3D and animation)

Code: Select all

;{/// STRUCTURE AND CONSTANTS FOR SPRITE3D
Structure DDPIXELFORMAT
   dwSize.l
   dwFlags.l
   dwFourCC.l
   dwRGBBitCount.l
   dwRBitMask.l
   dwGBitMask.l
   dwBBitMask.l
   dwRGBAlphaBitMask.l
EndStructure
Structure DDCOLORKEY
   dwColorSpaceLowValue.l
   dwColorSpaceHighValue.l
EndStructure
Structure DDSCAPS2
   dwCaps.l
   dwCaps2.l
   dwCaps3.l
   dwCaps4.l
EndStructure
Structure DDSURFACEDESC2
   dwSize.l
   dwFlags.l
   dwHeight.l
   dwWidth.l
   lPitch.l
   dwBackBufferCount.l
   dwRefreshRate.l
   dwAlphaBitDepth.l
   dwReserved.l
   lpSurface.l
   ddckCKDestOverlay.DDCOLORKEY
   ddckCKDestBlt.DDCOLORKEY
   ddckCKSrcOverlay.DDCOLORKEY
   ddckCKSrcBlt.DDCOLORKEY
   ddpfPixelFormat.DDPIXELFORMAT
   ddsCaps.DDSCAPS2
   dwTextureStage.l
EndStructure
Structure D3DTLVERTEX
   sx.f
   sy.f
   sz.f
   rhw.f
   color.l
   specular.l
   tu.f
   tv.f
EndStructure

;Standard Structure from PB
Structure PB_SPRITE3D
   Texture.IDirectDrawSurface7; DirectDrawSurface7
   Vertice.D3DTLVERTEX[4]     ; The 4 vertices for the rectangle sprite
   Width.w                    ; width set with ZoomSprite3D()
   Height.w                   ; height set with ZoomSprite3D()
   unknown.l
EndStructure

;Custom Structure for new functions
Structure PB_SPRITE3D_PLUS
   dist.f[4]   ;//Distance
   a.f[4]      ;//Angle
   
   fx.l        ;//Effect
   fxCount.l   ;//Effect Count
   
   Sprite3D.l
   ;*Sprite3D.PB_SPRITE3D
   
   frameIndex.f      ;//Current Frame
   frameCount.l      ;//Count Frames
   frameClips.l      ;//List of clip areas
   framesPerSecond.f ;//Frames per second
   animWay.b         ;//Animation way +1 -1
   animMode.l        ;//Animation
   animRunning.b     ;//Animation is running
EndStructure
Structure PB_SPRITE3D_PLUS_FX
   type.l
   
   start.l
   stop.l
   
   ax.l
   ay.l
   
   bx.l
   by.l
   
   cx.l
   cy.l
   
   mx.l
   my.l
   
   px.l
   py.l
   
EndStructure
Structure PB_SPRITE3D_PLUS_CLIP
   u.f[4]
   v.f[4]
EndStructure
Global NewList PB_SPRITE3D_PLUS.PB_SPRITE3D_PLUS()
Global NewList PB_SPRITE3D_PLUS_FX.PB_SPRITE3D_PLUS_FX()

CompilerIf Defined(D3DBLEND_ZERO, #PB_Constant)=0
   Enumeration
      ;Available Blend Effects
      #D3DBLEND_ZERO=1
      #D3DBLEND_ONE
      #D3DBLEND_SRCCOLOR
      #D3DBLEND_INVSRCCOLOR
      #D3DBLEND_SRCALPHA
      #D3DBLEND_INVSRCALPHA
      #D3DBLEND_DESTALPHA
      #D3DBLEND_INVDESTALPHA
      #D3DBLEND_DESTCOLOR
      #D3DBLEND_INVDESTCOLOR
      #D3DBLEND_SRCALPHASAT
      #D3DBLEND_BOTHSRCALPHA
      #D3DBLEND_BOTHINVSRCALPHA
   EndEnumeration
CompilerEndIf

CompilerIf Defined(TypeFX_Animation, #PB_Constant)=0
   Enumeration
      ;FX constants
      #TypeFX_Animation=0
      #TypeFX_Move
      #TypeFX_Orbit
      
      ;Available Mirror Effects
      #MirrorSprite3D_None=0
      #MirrorSprite3D_Horizontal
      #MirrorSprite3D_Vertical
      #MirrorSprite3D_Both=#MirrorSprite3D_Horizontal | #MirrorSprite3D_Vertical
      
      ;Available Animation
      #AnimateSprite3D_Loop=0    ;//LOOP
      #AnimateSprite3D_Reverse   ;//REVERSE LOOP
      #AnimateSprite3D_PingPong  ;//LOOP + REVERSE LOOP
      #AnimateSprite3D_Once      ;//PLAYING ONCE
      
   EndEnumeration
CompilerEndIf
;}

;{/// CUSTOM SPRITE3D FUNCTIONS
Declare.l GetSprite3DMirrorMode(Sprite3D)
Declare.b SetSprite3DMirrorMode(Sprite3D, MirrorMode)

ProcedureDLL.l CopySprite3D(Sprite3D1, Sprite3D2) ;Copy the #Sprite3D1 to #Sprite3D2
   Protected *Sprite3D1.PB_SPRITE3D=IsSprite3D(Sprite3D1)
   If *Sprite3D1=0 : ProcedureReturn 0 : EndIf
   
   Protected Sprite=CreateSprite(#PB_Any, 1, 1, #PB_Sprite_Texture)
   If Sprite=0 : ProcedureReturn 0 : EndIf
   
   Protected res=CreateSprite3D(Sprite3D2, Sprite)
   If res=0 : FreeSprite(Sprite) : ProcedureReturn 0 : EndIf
   If Sprite3D2=#PB_Any : Sprite3D2=res : EndIf
   
   Protected *Sprite3D2.PB_SPRITE3D=IsSprite3D(Sprite3D2)
   *Sprite3D2\Texture=*Sprite3D1\Texture
   *Sprite3D2\Width=*Sprite3D1\Width
   *Sprite3D2\Height=*Sprite3D1\Height
   *Sprite3D2\unknown=*Sprite3D1\unknown
   
   For i=0 To 3
      *Sprite3D2\Vertice[i]\sx=*Sprite3D1\Vertice[i]\sx
      *Sprite3D2\Vertice[i]\sy=*Sprite3D1\Vertice[i]\sy
      *Sprite3D2\Vertice[i]\sz=*Sprite3D1\Vertice[i]\sz
      *Sprite3D2\Vertice[i]\rhw=*Sprite3D1\Vertice[i]\rhw
      *Sprite3D2\Vertice[i]\color=*Sprite3D1\Vertice[i]\color
      *Sprite3D2\Vertice[i]\specular=*Sprite3D1\Vertice[i]\specular
      *Sprite3D2\Vertice[i]\tu=*Sprite3D1\Vertice[i]\tu
      *Sprite3D2\Vertice[i]\tv=*Sprite3D1\Vertice[i]\tv
   Next
   
   FreeSprite(Sprite)
   ProcedureReturn *Sprite3D2
EndProcedure
ProcedureDLL.b ClipSprite3D(Sprite3D, ClipX, ClipY, ClipWidth, ClipHeight) ;Add clip zone to the specified 3D sprite
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   If *Sprite3D=0 : ProcedureReturn 0 : EndIf
   
   Protected *DDS.IDirectDrawSurface7=*Sprite3D\Texture
   Protected DDSDESC.DDSURFACEDESC2 : DDSDESC\dwSize=SizeOf(DDSURFACEDESC2)
   Protected Result=*DDS\GetSurfaceDesc(DDSDESC)
   If Result : ProcedureReturn 0 : EndIf
   
   Protected MirrorMode=GetSprite3DMirrorMode(Sprite3D)
   *Sprite3D\Vertice[0]\tu=ClipX/DDSDESC\dwWidth
   *Sprite3D\Vertice[0]\tv=ClipY/DDSDESC\dwHeight
   
   *Sprite3D\Vertice[1]\tu=(ClipX+ClipWidth)/DDSDESC\dwWidth
   *Sprite3D\Vertice[1]\tv=ClipY/DDSDESC\dwHeight
   
   *Sprite3D\Vertice[2]\tu=ClipX/DDSDESC\dwWidth
   *Sprite3D\Vertice[2]\tv=(ClipY+ClipHeight)/DDSDESC\dwHeight
   
   *Sprite3D\Vertice[3]\tu=(ClipX+ClipWidth)/DDSDESC\dwWidth
   *Sprite3D\Vertice[3]\tv=(ClipY+ClipHeight)/DDSDESC\dwHeight
   SetSprite3DMirrorMode(Sprite3D, MirrorMode)
   
   *Sprite3D\Vertice[0]\sx=0
   *Sprite3D\Vertice[0]\sy=0
   *Sprite3D\Vertice[0]\sz=0
   
   *Sprite3D\Vertice[1]\sx=ClipWidth
   *Sprite3D\Vertice[1]\sy=0
   *Sprite3D\Vertice[1]\sz=0
   
   *Sprite3D\Vertice[2]\sx=0
   *Sprite3D\Vertice[2]\sy=ClipHeight
   *Sprite3D\Vertice[2]\sz=0
   
   *Sprite3D\Vertice[3]\sx=ClipWidth
   *Sprite3D\Vertice[3]\sy=ClipHeight
   *Sprite3D\Vertice[3]\sz=0
   
   *Sprite3D\Width=ClipWidth
   *Sprite3D\Height=ClipHeight
   
   ProcedureReturn 1 ; return success
EndProcedure
ProcedureDLL.l CreateClippedSprite3D(Sprite3D, Sprite, ClipX, ClipY, ClipWidth, ClipHeight) ;Create a new 3D sprite with the selected area from 2D sprite
   Protected res=CreateSprite3D(Sprite3D, Sprite)
   If Sprite3D=#PB_Any : Sprite3D=res : EndIf
   
   If res And ClipX<>#PB_Ignore
      ClipSprite3D(Sprite3D, ClipX, ClipY, ClipWidth, ClipHeight)
   EndIf
   
   ProcedureReturn res
EndProcedure
ProcedureDLL FreeSprite3DParameters(Sprite3D) ;Free memory allocated for new Sprite3D parameters
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   If *Sprite3D\Vertice[3]\sz
      ChangeCurrentElement(PB_SPRITE3D_PLUS(), *Sprite3D\Vertice[3]\sz)
      Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
      If *param And *param\frameClips : FreeMemory(*param\frameClips) : EndIf
      DeleteElement(PB_SPRITE3D_PLUS())
      *Sprite3D\Vertice[3]\sz=0
   EndIf
EndProcedure

ProcedureDLL SetSprite3DAlpha(Sprite3D, alpha)                 ;Set 3D sprite alpha (transparency 0 - 255)
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   alpha<<24
   For i=0 To 3
      *Sprite3D\Vertice[i]\color & $00FFFFFF+alpha
   Next
EndProcedure
ProcedureDLL SetSprite3DColor(Sprite3D, color)                 ;Set 3D sprite color (RGB)
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   color=Blue(color)+(Green(color)<<8)+(Red(color)<<16)
   For i=0 To 3
      *Sprite3D\Vertice[i]\color & $FF000000+color
   Next
EndProcedure
ProcedureDLL SetSprite3DHandle(Sprite3D, HandleX, HandleY)     ;Set 3D sprite handle (X,Y)
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   *Sprite3D\Vertice[0]\sx=-HandleX
   *Sprite3D\Vertice[0]\sy=-HandleY
   *Sprite3D\Vertice[0]\sz=(HandleX);Trick
   
   *Sprite3D\Vertice[1]\sx=-HandleX+*Sprite3D\Width
   *Sprite3D\Vertice[1]\sy=-HandleY
   *Sprite3D\Vertice[1]\sz=(HandleY);Trick
   
   *Sprite3D\Vertice[2]\sx=-HandleX
   *Sprite3D\Vertice[2]\sy=-HandleY+*Sprite3D\Height
   ;*Sprite3D\Vertice[2]\sz=(Rotation);Trick
   
   *Sprite3D\Vertice[3]\sx=-HandleX+*Sprite3D\Width
   *Sprite3D\Vertice[3]\sy=-HandleY+*Sprite3D\Height
   ;*Sprite3D\Vertice[3]\sz=*param.PB_SPRITE3D_PLUS
   
   Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
   If *param=0
      *param=AddElement(PB_SPRITE3D_PLUS())+8
      *Sprite3D\Vertice[3]\sz=*param
   EndIf
   
   For i=0 To 3
      *param\dist[i]=Sqr(Pow(*Sprite3D\Vertice[i]\sx, 2)+Pow(*Sprite3D\Vertice[i]\sy, 2))
      If (*Sprite3D\Vertice[i]\sx=0)
         *param\a[i]=ATan(*Sprite3D\Vertice[i]\sy/0.0000000001)
      ElseIf *Sprite3D\Vertice[i]\sx>0
         *param\a[i]=ATan(*Sprite3D\Vertice[i]\sy/*Sprite3D\Vertice[i]\sx)
      Else
         *param\a[i]=ATan(*Sprite3D\Vertice[i]\sy/*Sprite3D\Vertice[i]\sx)+#PI
      EndIf
   Next
EndProcedure
ProcedureDLL SetSprite3DHandlePoint(Sprite3D, *Handle.POINT)   ;Set 3D sprite handle POINT
   SetSprite3DHandle(Sprite3D, *Handle\x, *Handle\y)
EndProcedure
ProcedureDLL SetSprite3DSize(Sprite3D, Width, Height)          ;Set 3D sprite size
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   *Sprite3D\Width=Width
   *Sprite3D\Height=Height
   
   SetSprite3DHandle(Sprite3D, *Sprite3D\Vertice[0]\sz, *Sprite3D\Vertice[1]\sz)
EndProcedure
ProcedureDLL SetSprite3DAngle(Sprite3D, Angle, Mode)           ;Set 3D sprite angle (rotation if mode=1)
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   If Mode : Angle+*Sprite3D\Vertice[2]\sz : EndIf
   *Sprite3D\Vertice[2]\sz=Angle
   
   If *Sprite3D\Vertice[3]\sz=0
      SetSprite3DHandle(Sprite3D, *Sprite3D\Vertice[0]\sz, *Sprite3D\Vertice[1]\sz)
   EndIf
   
   Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
   For i=0 To 3
      Protected dist.f=*param\dist[i]
      Protected a.f=*param\a[i]
      a+Angle*#PI/180.0
      *Sprite3D\Vertice[i]\sx=dist*Cos(a)
      *Sprite3D\Vertice[i]\sy=dist*Sin(a)
   Next
EndProcedure
ProcedureDLL.b SetSprite3DMirrorMode(Sprite3D, MirrorMode)     ;Set 3D sprite mirror mode (returns TRUE if any changes)
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   Protected MirroringChanges.b=0
   Protected IsMirrored.b
   Protected DoMirroring.b
   
   IsMirrored=*Sprite3D\Vertice[0]\tu>*Sprite3D\Vertice[1]\tu
   DoMirroring=1 And MirrorMode & #MirrorSprite3D_Horizontal
   If (DoMirroring And IsMirrored=0) Or (DoMirroring=0 And IsMirrored)
      MirroringChanges=1
      Swap *Sprite3D\Vertice[0]\tu, *Sprite3D\Vertice[1]\tu
      Swap *Sprite3D\Vertice[2]\tu, *Sprite3D\Vertice[3]\tu
   EndIf
   
   IsMirrored=*Sprite3D\Vertice[0]\tv>*Sprite3D\Vertice[3]\tv
   DoMirroring=1 And MirrorMode & #MirrorSprite3D_Vertical
   If (DoMirroring And IsMirrored=0) Or (DoMirroring=0 And IsMirrored)
      MirroringChanges=1
      Swap *Sprite3D\Vertice[0]\tv, *Sprite3D\Vertice[3]\tv
      Swap *Sprite3D\Vertice[1]\tv, *Sprite3D\Vertice[2]\tv
   EndIf
   
   ProcedureReturn MirroringChanges
EndProcedure
ProcedureDLL.l GetSprite3DMirrorMode(Sprite3D)                 ;Get 3D sprite Mirroring mode
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   Protected MirroringMode=#MirrorSprite3D_None
   If *Sprite3D\Vertice[0]\tu>*Sprite3D\Vertice[1]\tu
      MirroringMode | #MirrorSprite3D_Horizontal
   EndIf
   If *Sprite3D\Vertice[0]\tv>*Sprite3D\Vertice[3]\tv
      MirroringMode | #MirrorSprite3D_Vertical
   EndIf
   
   ProcedureReturn MirroringMode
EndProcedure
ProcedureDLL.l GetSprite3DAlpha(Sprite3D)                      ;Get 3D sprite alpha
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   Protected alpha=*Sprite3D\Vertice[0]\color & $FF000000
   alpha>>24
   ProcedureReturn alpha
EndProcedure
ProcedureDLL.l GetSprite3DColor(Sprite3D)                      ;Get 3D sprite color
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   Protected color=*Sprite3D\Vertice[0]\color & $00FFFFFF
   ProcedureReturn color
EndProcedure
ProcedureDLL.l GetSprite3DAngle(Sprite3D)                      ;Get 3D sprite angle
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   Protected a=*Sprite3D\Vertice[2]\sz
   ProcedureReturn a%360
EndProcedure
ProcedureDLL.l GetSprite3DHandleX(Sprite3D)                    ;Get 3D sprite handle X
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   Debug *Sprite3D\Vertice[3]\sz
   ProcedureReturn *Sprite3D\Vertice[0]\sz
EndProcedure
ProcedureDLL.l GetSprite3DHandleY(Sprite3D)                    ;Get 3D sprite handle Y
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   ProcedureReturn *Sprite3D\Vertice[1]\sz
EndProcedure
ProcedureDLL GetSprite3DHandle(Sprite3D, *HandleX, *HandleY)   ;Get 3D sprite handle (X,Y)
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   PokeL(*HandleX, *Sprite3D\Vertice[0]\sz)
   PokeL(*HandleY, *Sprite3D\Vertice[1]\sz)
EndProcedure
ProcedureDLL GetSprite3DHandlePoint(Sprite3D, *Handle.POINT)   ;Get 3D sprite handle POINT
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   *Handle\x=*Sprite3D\Vertice[0]\sz
   *Handle\y=*Sprite3D\Vertice[1]\sz
EndProcedure

ProcedureDLL.b AnimateSprite3D(Sprite3D, ClipX, ClipY, ClipWidth, ClipHeight, FramesPerRow, FrameCount, FramesPerSecond=5, AnimMode=#AnimateSprite3D_Loop) ;Define 3D sprite animation
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   Protected *DDS.IDirectDrawSurface7=*Sprite3D\Texture
   Protected DDSDESC.DDSURFACEDESC2 : DDSDESC\dwSize=SizeOf(DDSURFACEDESC2)
   Protected Result=*DDS\GetSurfaceDesc(DDSDESC)
   If Result : ProcedureReturn 0 : EndIf
   
   ClipSprite3D(Sprite3D, ClipX, ClipY, ClipWidth, ClipHeight)
   
   If *Sprite3D\Vertice[3]\sz=0
      SetSprite3DHandle(Sprite3D, *Sprite3D\Vertice[0]\sz, *Sprite3D\Vertice[1]\sz)
   EndIf
   
   Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
   *param\framesPerSecond=FramesPerSecond/1000.0
   *param\frameCount=FrameCount
   *param\frameIndex=0
   *param\animMode=AnimMode
   *param\animWay=1
   *param\animRunning=0
   *param\sprite3D=Sprite3D;*Sprite3D
   If *param\frameClips
      *param\frameClips=ReAllocateMemory(*param\frameClips, SizeOf(PB_SPRITE3D_PLUS_CLIP)*FrameCount)
   Else
      *param\frameClips=AllocateMemory(SizeOf(PB_SPRITE3D_PLUS_CLIP)*FrameCount)
   EndIf
   
   Protected *frameClip.PB_SPRITE3D_PLUS_CLIP=*param\frameClips
   Protected x=ClipX
   Protected y=ClipY
   Protected countFramesPerRow=0
   For frameIndex=0 To FrameCount-1
      
      *frameClip\u[0]=x/DDSDESC\dwWidth
      *frameClip\v[0]=y/DDSDESC\dwHeight
      *frameClip\u[1]=(x+ClipWidth)/DDSDESC\dwWidth
      *frameClip\v[1]=(y)/DDSDESC\dwHeight
      *frameClip\u[2]=(x)/DDSDESC\dwWidth
      *frameClip\v[2]=(y+ClipHeight)/DDSDESC\dwHeight
      *frameClip\u[3]=(x+ClipWidth)/DDSDESC\dwWidth
      *frameClip\v[3]=(y+ClipHeight)/DDSDESC\dwHeight
      
      x+ClipWidth
      countFramesPerRow+1
      If countFramesPerRow=framesPerRow
         countFramesPerRow=0
         x=ClipX
         y+ClipHeight
      EndIf
      
      *frameClip+SizeOf(PB_SPRITE3D_PLUS_CLIP)
   Next
   
   ;    Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
   ;    If *param\fx
   ;       ChangeCurrentElement(PB_SPRITE3D_PLUS_FX(), *param\fx)
   ;    EndIf
   ;    *param\fx=InsertElement(PB_SPRITE3D_PLUS_FX())+8
   ;    *param\fxCount+1
   ;    PB_SPRITE3D_PLUS_FX()\type=#TypeFX_Animation
   ;    PB_SPRITE3D_PLUS_FX()\start=
EndProcedure
ProcedureDLL.b StartSprite3DAnimation(Sprite3D)                ;Start 3D sprite animation
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   If *Sprite3D\Vertice[3]\sz=0 : ProcedureReturn 0 : EndIf
   Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
   *param\animRunning=1
   ProcedureReturn 1
EndProcedure
ProcedureDLL.b StopSprite3DAnimation(Sprite3D)                 ;Stop 3D sprite animation
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   If *Sprite3D\Vertice[3]\sz=0 : ProcedureReturn 0 : EndIf
   Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
   *param\animRunning=0
   ProcedureReturn 1
EndProcedure
ProcedureDLL.b SetSprite3DAnimSpeed(Sprite3D, FramesPerSecond) ;Set 3D sprite animation speed
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   If *Sprite3D\Vertice[3]\sz=0 : ProcedureReturn 0 : EndIf
   Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
   *param\framesPerSecond=FramesPerSecond
   ProcedureReturn 1
EndProcedure
ProcedureDLL.b SetSprite3DAnimMode(Sprite3D, AnimMode)         ;Set 3D sprite animation mode (LOOP, REVERSE, ...)
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   If *Sprite3D\Vertice[3]\sz=0 : ProcedureReturn 0 : EndIf
   Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
   *param\animMode=AnimMode
   ProcedureReturn 1
EndProcedure
ProcedureDLL.b SetSprite3DAnimFrame(Sprite3D, FrameIndex)      ;Set 3D sprite current animation frame
   Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
   
   If *Sprite3D\Vertice[3]\sz=0 : ProcedureReturn 0 : EndIf
   Protected *param.PB_SPRITE3D_PLUS=*Sprite3D\Vertice[3]\sz
   If FrameIndex<0 Or FrameIndex>*param\frameCount : ProcedureReturn 0 : EndIf
   
   *param\frameIndex=FrameIndex
   Protected *frameClip.PB_SPRITE3D_PLUS_CLIP=*param\frameClips+*param\frameIndex*SizeOf(PB_SPRITE3D_PLUS_CLIP)
   Protected MirroringMode=GetSprite3DMirrorMode(Sprite3D)
   For i=0 To 3
      *Sprite3D\Vertice[i]\tu=*frameClip\u[i]
      *Sprite3D\Vertice[i]\tv=*frameClip\v[i]
   Next
   SetSprite3DMirrorMode(Sprite3D, MirroringMode)
   
   ProcedureReturn 1
EndProcedure
ProcedureDLL ExamineSprite3D()
   Static t1, t2, dt
   t2=ElapsedMilliseconds()
   dt=t2-t1
   t1=t2
   
   ForEach PB_SPRITE3D_PLUS()
      Protected Sprite3D=PB_SPRITE3D_PLUS()\sprite3D
      Protected *Sprite3D.PB_SPRITE3D=IsSprite3D(Sprite3D)
      
      ;{/// ANIMATION
      If PB_SPRITE3D_PLUS()\frameCount And PB_SPRITE3D_PLUS()\animRunning
         Select PB_SPRITE3D_PLUS()\animMode
            Case #AnimateSprite3D_Once
               PB_SPRITE3D_PLUS()\frameIndex-PB_SPRITE3D_PLUS()\framesPerSecond*dt
               If PB_SPRITE3D_PLUS()\frameIndex>PB_SPRITE3D_PLUS()\frameCount
                  PB_SPRITE3D_PLUS()\animRunning=0
                  PB_SPRITE3D_PLUS()\frameIndex=PB_SPRITE3D_PLUS()\frameCount-1
               EndIf
            Case #AnimateSprite3D_Loop
               PB_SPRITE3D_PLUS()\frameIndex+PB_SPRITE3D_PLUS()\framesPerSecond*dt
               If PB_SPRITE3D_PLUS()\frameIndex>PB_SPRITE3D_PLUS()\frameCount
                  PB_SPRITE3D_PLUS()\frameIndex=0
               EndIf
            Case #AnimateSprite3D_Reverse
               PB_SPRITE3D_PLUS()\frameIndex-PB_SPRITE3D_PLUS()\framesPerSecond*dt
               If PB_SPRITE3D_PLUS()\frameIndex<0
                  PB_SPRITE3D_PLUS()\frameIndex=PB_SPRITE3D_PLUS()\frameCount-1
               EndIf
            Case #AnimateSprite3D_PingPong
               PB_SPRITE3D_PLUS()\frameIndex+PB_SPRITE3D_PLUS()\animWay*PB_SPRITE3D_PLUS()\framesPerSecond*dt
               If PB_SPRITE3D_PLUS()\frameIndex>PB_SPRITE3D_PLUS()\frameCount-1
                  PB_SPRITE3D_PLUS()\frameIndex=PB_SPRITE3D_PLUS()\frameCount-1
                  PB_SPRITE3D_PLUS()\animWay=-1
               ElseIf PB_SPRITE3D_PLUS()\frameIndex<0
                  PB_SPRITE3D_PLUS()\frameIndex=0
                  PB_SPRITE3D_PLUS()\animWay=1
               EndIf
         EndSelect
         
         Protected *frameClip.PB_SPRITE3D_PLUS_CLIP=PB_SPRITE3D_PLUS()\frameClips+Round(PB_SPRITE3D_PLUS()\frameIndex,#PB_Round_Nearest)*SizeOf(PB_SPRITE3D_PLUS_CLIP)
         Protected MirroringMode=GetSprite3DMirrorMode(Sprite3D)
         For i=0 To 3
            *Sprite3D\Vertice[i]\tu=*frameClip\u[i]
            *Sprite3D\Vertice[i]\tv=*frameClip\v[i]
         Next
         SetSprite3DMirrorMode(Sprite3D, MirroringMode)
      EndIf
      ;}
      
      ;{/// EFFECTS
      If PB_SPRITE3D_PLUS()\fx
         ChangeCurrentElement(PB_SPRITE3D_PLUS_FX(), PB_SPRITE3D_PLUS()\fx)
         For i=1 To PB_SPRITE3D_PLUS()\fxCount
            Select PB_SPRITE3D_PLUS_FX()\type
               Case #TypeFX_Animation
               Case #TypeFX_Move
               Case #TypeFX_Orbit
            EndSelect
            NextElement(PB_SPRITE3D_PLUS_FX())
         Next
      EndIf
      ;}
   Next
EndProcedure

Macro SetSprite3DBlend_NORMAL()
   Sprite3DBlendingMode(#D3DBLEND_SRCALPHA, #D3DBLEND_INVSRCALPHA)
EndMacro
Macro SetSprite3DBlend_INVERT()
   Sprite3DBlendingMode(#D3DBLEND_INVDESTCOLOR, #D3DBLEND_INVSRCALPHA)
EndMacro
Macro SetSprite3DBlend_LIGHT()
   Sprite3DBlendingMode(#D3DBLEND_SRCALPHA, #D3DBLEND_ONE)
EndMacro
Macro SetSprite3DBlend_SHADE()
   Sprite3DBlendingMode(#D3DBLEND_ZERO, #D3DBLEND_SRCCOLOR)
EndMacro
Macro RotateSprite3D(Sprite3D, Angle, Mode)                    ;//WRAPPER
   SetSprite3DAngle(Sprite3D, Angle, Mode)
EndMacro
Macro ZoomSprite3D(Sprite3D, Width, Height)                    ;//WRAPPER
   SetSprite3DSize(Sprite3D, Width, Height)
EndMacro
Macro FreeSprite3D(Sprite3D, FreeSprite3DObject=FreeSprite3D)  ;//WRAPPER
   FreeSprite3DParameters(Sprite3D)
   FreeSprite3DObject(Sprite3D)
EndMacro
Macro MirrorSprite3D(Sprite3D, MirrorMode)                     ;//WRAPPER
   SetSprite3DMirrorMode(Sprite3D, MirrorMode)
EndMacro

;}

;********************
; Example
;********************
InitSprite()
InitSprite3D()
InitKeyboard()
OpenScreen(1024, 768, 32, "Custom PB Sprite3D")
Sprite3DQuality(1)

CreateSprite(1, 256, 256, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(1))
   Box(0, 0, 256, 255, RGB(255, 200, 100))
   For i=0 To 8
      Box(i*8, 0, i, 8, RGB(0, 255, 255))
   Next
   Box(150, 150, 50, 50, RGB(255, 255, 255))
   Box(100, 100, 50, 50, RGB(255, 0, 100))
   Box(236, 0, 20, 256, RGB(255, 255, 255))
StopDrawing()

;Normal Sprite3D + MIRROR
CreateSprite3D(10, 1)
MirrorSprite3D(10, #MirrorSprite3D_Horizontal)
;Clipped Sprite3D+ MIRROR
CreateSprite3D(20, 1)
ClipSprite3D(20, 0, 0, 40, 100)
MirrorSprite3D(20, #MirrorSprite3D_Vertical)
;Clipped Sprite3D + COLOR + TRANSPARENCY
CreateClippedSprite3D(30, 1, 0, 0, 40, 100)
SetSprite3DAlpha(30, 200)
SetSprite3DColor(30, RGB(4, 255, 251))
;Copied Sprite3D + SIZE + ANINAMTION
CopySprite3D(10, 40)
AnimateSprite3D(40, 0, 0, 8, 8, 9, 9, 3, #AnimateSprite3D_PingPong)
StartSprite3DAnimation(40)
SetSprite3DSize(40, 40, 100)
;Copied Sprite3D + SIZE + COLOR
CopySprite3D(10, 50)
SetSprite3DSize(50, 64, 128)
SetSprite3DColor(40, RGB(2, 133, 253))
;Set / Get handle
SetSprite3DHandle(50, 5, 155)
GetSprite3DHandle(50, @handleX, @handleY)
GetSprite3DHandlePoint(50, handle.POINT)

Repeat
   ClearScreen(RGB(0, 0, 0))
   
   Start3D()
      SetSprite3DBlend_NORMAL()
      DisplaySprite3D(10, 100, 200)
      DisplaySprite3D(20, 400, 200)
      DisplaySprite3D(30, 450, 200)
      DisplaySprite3D(40, 430, 230)
      
      RotateSprite3D(50, 1, 1)
      SetSprite3DBlend_LIGHT()
      DisplaySprite3D(50, 150, 200)
      SetSprite3DBlend_INVERT()
      DisplaySprite3D(50, 150, 300)
   Stop3D()
   
   FlipBuffers()
   ExamineKeyboard()
   ExamineSprite3D()
   
   ;Manage ALT + TAB
   If Not IsScreenActive()
      Repeat
         FlipBuffers()
      Until IsScreenActive()
   EndIf
   
Until KeyboardPushed(#PB_Key_Escape)
FreeSprite3D(50)
Imagewin10 x64 5.72 | IDE | PB plugin | Tools | Sprite | JSON | visual tool
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Post by DoubleDutch »

It gets even better! :D

I wonder if there is any way to have completely separate palettes for the same sprite. EG have 8 colour sprites pointing to an 8 colour palette (so you can have another sprite with the same data - but pointing to a different 8 colours), or the same for 16/32/64 colour sprites. Anyone know?
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
Poshu
Enthusiast
Enthusiast
Posts: 459
Joined: Tue Jan 25, 2005 7:01 pm
Location: Canada

Post by Poshu »

I second DoubleDutch's question.
User avatar
DoubleDutch
Addict
Addict
Posts: 3220
Joined: Thu Aug 07, 2003 7:01 pm
Location: United Kingdom
Contact:

Re: Sprite3D [win] clip,color,alpha,mirror,handle,copy,anim,

Post by DoubleDutch »

I guess not?
https://deluxepixel.com <- My Business website
https://reportcomplete.com <- School end of term reports system
X
Enthusiast
Enthusiast
Posts: 311
Joined: Tue Apr 04, 2006 6:27 am

Re: Sprite3D [win] clip,color,alpha,mirror,handle,copy,anim,

Post by X »

Is there any chance for a 64bit/dx9 version of this code? Right now, the graphics are all screwed up if you attempt to use the SetSprite3DColor procedure.
Post Reply