Flip,gray,shadow Sprites ,All PB Versions-No Api

Share your advanced PureBasic knowledge/code with the community.
User avatar
Rings
Moderator
Moderator
Posts: 1427
Joined: Sat Apr 26, 2003 1:11 am

Flip,gray,shadow Sprites ,All PB Versions-No Api

Post by Rings »

Description:
with these procedures you can mirror a sprite horizontal or
vertical, turn a sprite into a grey one, or create a shadowsprite
(usefull for pseudo-3d-effect).
All routines saves the alpha-channel (if there was one )

Todo:
stuff with less then 3 bytes per pixel.

Can anyone test this code with other PB-version than mine?
i have PB4.1 running under Win-XP and Linux (PCLinuxOS) .
The Code should be running on all PB Plattforms.
MacOSX perhaps ?
Image

Code: Select all

If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester("Error", "Can't open DirectX 7 Or later", 0)
  End
EndIf
If InitSprite3D() = 0
  MessageRequester("Error", "Direct3D system can't be initialized correctly", 0)
  End
EndIf

Procedure SpriteMirrorHorizontal(SpriteID)
;Mirrors a sprite horizontal
StartDrawing(SpriteOutput(SpriteID))
 IW = SpriteWidth(SpriteID)
 IH = SpriteHeight(SpriteID)
 Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
 Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 
 *pxData1.LONG = Buffer
 *pxData2.LONG = *pxData1 + (IH-1)*Pitch

 mem=AllocateMemory(Pitch)
 For lines=0 To IH/2-1
  CopyMemory(*pxData1,mem,pitch)
  CopyMemory(*pxData2,*pxData1,pitch)
  CopyMemory(mem,*pxData2,pitch)
  *pxData1 + pitch
  *pxData2 - pitch
 Next
 StopDrawing()
 If mem: FreeMemory(mem):EndIf
 
EndProcedure


Procedure SpriteMirrorVertical(SpriteID)
;Mirrors a sprite vertical
StartDrawing(SpriteOutput(SpriteID))
 IW = SpriteWidth(SpriteID)
 IH = SpriteHeight(SpriteID)
 Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
 Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 
 *pxData1.LONG = Buffer
 *pxData2.LONG = *pxData1 + (IH-1)*Pitch
 PixelFormat=DrawingBufferPixelFormat()
 ByteOffset=4
 Select PixelFormat
  Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
   ByteOffset=1
  Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
   ByteOffset=3
  Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
   ByteOffset=3
  Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
   ByteOffset=4
  Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
   ByteOffset=4
 EndSelect

 For Lines=0 To IH-1
  *pxData1 = Buffer + (Lines*pitch)
  *pxData2 = *pxData1 + pitch-4
  For t=0 To (IW/2)-1
   m=*pxData1\l
   *pxData1\l=*pxData2\l
   *pxData2\l=m
   *pxData1 + ByteOffset
   *pxData2 - ByteOffset
  Next
 Next
 StopDrawing()
 
EndProcedure


Procedure SpriteGray(ID)
;grays a ID
If IsSprite(id)=0:ProcedureReturn 0:EndIf

 StartDrawing(SpriteOutput(ID))
 IW = SpriteWidth(ID)
 IH = SpriteHeight(ID)
 Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
 Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 *pxData1.LONG 
 PixelFormat=DrawingBufferPixelFormat() 
 
 Select PixelFormat
  Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
   ByteOffset=1
  Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
   ByteOffset=3
  Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
   ByteOffset=3
  Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
   ByteOffset=4
  Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
   ByteOffset=4
 EndSelect

 For Lines=0 To IH-1
  *pxData1 = Buffer + (Lines*pitch)
  For t=0 To IW-1
   m=*pxData1\l
  
   Select Pixelformat
    Case #PB_PixelFormat_16Bits

    Case #PB_PixelFormat_24Bits_BGR,#PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
     
     p=m >> 24 & $FF ;the additive alpha
     r= m >> 16 & $FF
     g= m >> 8 & $FF
     b= m  & $FF 
     gray=((r*29)+(g*58)+(b*11))/100
     m=   gray | gray << 8 | gray << 16 | p << 24

    Case #PB_PixelFormat_24Bits_RGB,#PB_PixelFormat_32Bits_RGB
     p=m >> 24 & $FF ;the additive alpha
     b= m >> 16 & $FF
     g= m >> 8 & $FF
     r= m  & $FF 
     gray=((r*29)+(g*58)+(b*11))/100
     m=   gray | gray << 8 | gray << 16 | p << 24

   EndSelect
     
   *pxData1\l=m
   *pxData1 + ByteOffset
  Next
 Next
 StopDrawing()
 
EndProcedure

Procedure SpriteShadow(ID,TransparentColor=0)
;transform a sprite into a shadow
If IsSprite(id)=0:ProcedureReturn 0:EndIf

 StartDrawing(SpriteOutput(ID))
 IW = SpriteWidth(ID)
 IH = SpriteHeight(ID)
 Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
 Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 *pxData1.LONG 
 PixelFormat=DrawingBufferPixelFormat() 
 
 Select PixelFormat
  Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
   ByteOffset=1
  Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
   ByteOffset=3
  Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
   ByteOffset=3
  Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
   ByteOffset=4
  Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
   ByteOffset=4
 EndSelect

 For Lines=0 To IH-1
  *pxData1 = Buffer + (Lines*pitch)
  For t=0 To IW-1
   m=*pxData1\l
   If m=TransparentColor
    ;do nothing
   Else
    m=0
   EndIf  
   *pxData1\l=m
   *pxData1 + ByteOffset
  Next
 Next
 StopDrawing()
 
EndProcedure


If OpenScreen(800,600, 32, "Sprite")

  lp=LoadSprite(0, "Data\Geebee2.bmp", #PB_Sprite_Texture)
  If lp=0
   Debug "sprite not loaded"
   End
  EndIf
  TransparentSpriteColor(0, RGB(255, 0, 255)) ; Our pink is transparent :)
 
  ;Draw some boxes
  StartDrawing(SpriteOutput(0))
     Box(0,0,30,30,RGB(250,250,50))
     Box(SpriteWidth(0)-30,0,30,30,RGB(50,250,50))
     Box(SpriteWidth(0)-30,SpriteHeight(0)-30,30,30,RGB(50,50,250))
     Box(0,SpriteHeight(0)-30,30,30,RGB(50,250,250))
  StopDrawing()

  CopySprite(0,1,  #PB_Sprite_Texture)
  SpriteMirrorHorizontal(1)
  TransparentSpriteColor(1, RGB(255, 0, 255)) ; Our pink is transparent :)
  CopySprite(0,2,  #PB_Sprite_Texture)
  SpriteMirrorVertical(2)
  TransparentSpriteColor(2, RGB(255, 0, 255)) ; Our pink is transparent :)
 
  CopySprite(0,3,  #PB_Sprite_Texture)
  SpriteGray(3)
  TransparentSpriteColor(3, RGB(255, 0, 255)) ; Our pink is transparent :)
 
  CopySprite(0,4,  #PB_Sprite_Texture)
  SpriteShadow(4,RGB(255, 0, 255))
  TransparentSpriteColor(4, RGB(255, 0, 255)) ; Our pink is transparent :)

  Repeat
    FlipBuffers()
    ClearScreen(RGB(200,200,255))
    DisplaySprite(0, 00, 30);original
    DisplayTransparentSprite(1, 200, 30);horizontal
    DisplayTransparentSprite(2, 400, 30);vertical
    DisplayTransparentSprite(3, 600, 30);gray
    
    DisplayTransparentSprite(4, 0, 230);Shadow
    
    ExamineKeyboard()
    x+1
  Until x > 2500 Or KeyboardPushed(#PB_Key_Escape)
Else
  MessageRequester("Error", "Can't open a screen !", 0)
EndIf
End 

Last edited by Rings on Tue Nov 20, 2007 7:10 pm, edited 1 time in total.
SPAMINATOR NR.1
User avatar
Rings
Moderator
Moderator
Posts: 1427
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

Update nov,19. :
Added Gray and shadow sprite and corrected some errors
changed picture
SPAMINATOR NR.1
dracflamloc
Addict
Addict
Posts: 1648
Joined: Mon Sep 20, 2004 3:52 pm
Contact:

Post by dracflamloc »

Nice rings, very nice
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8433
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Great work and too useful, thanks for posting.
BERESHEIT
Derek
Addict
Addict
Posts: 2356
Joined: Wed Apr 07, 2004 12:51 am
Location: England

Post by Derek »

Works fine on my 4.1 beta 4 running under Vista business.
User avatar
Rings
Moderator
Moderator
Posts: 1427
Joined: Sat Apr 26, 2003 1:11 am

Post by Rings »

tested succesfully under linux.......
SPAMINATOR NR.1
byo
Enthusiast
Enthusiast
Posts: 635
Joined: Mon Apr 02, 2007 1:43 am
Location: Brazil

Post by byo »

Thank you.
Multiplatform code is always welcome.
Thalius
Enthusiast
Enthusiast
Posts: 711
Joined: Thu Jul 17, 2003 4:15 pm
Contact:

Post by Thalius »

Very nice! Thanks Rings. :D

Works perfectly under Linux aswell.

i fixed the example tho a bit so it runs basically out-of-the-box under linux :
- corrected path
- and excluded Sprite3D init on all OS but Windblows. =p

Code: Select all

If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester("Error", "Can't open DirectX 7 Or later", 0)
  End
EndIf

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  If InitSprite3D() = 0
    MessageRequester("Error", "Direct3D system can't be initialized correctly", 0)
    End
  EndIf
CompilerEndIf

Procedure SpriteMirrorHorizontal(SpriteID)
;Mirrors a sprite horizontal
StartDrawing(SpriteOutput(SpriteID))
 IW = SpriteWidth(SpriteID)
 IH = SpriteHeight(SpriteID)
 Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
 Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 
 *pxData1.LONG = Buffer
 *pxData2.LONG = *pxData1 + (IH-1)*Pitch

 mem=AllocateMemory(Pitch)
 For lines=0 To IH/2-1
  CopyMemory(*pxData1,mem,pitch)
  CopyMemory(*pxData2,*pxData1,pitch)
  CopyMemory(mem,*pxData2,pitch)
  *pxData1 + pitch
  *pxData2 - pitch
 Next
 StopDrawing()
 If mem: FreeMemory(mem):EndIf
 
EndProcedure


Procedure SpriteMirrorVertical(SpriteID)
;Mirrors a sprite vertical
StartDrawing(SpriteOutput(SpriteID))
 IW = SpriteWidth(SpriteID)
 IH = SpriteHeight(SpriteID)
 Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
 Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 
 *pxData1.LONG = Buffer
 *pxData2.LONG = *pxData1 + (IH-1)*Pitch
 PixelFormat=DrawingBufferPixelFormat()
 ByteOffset=4
 Select PixelFormat
  Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
   ByteOffset=1
  Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
   ByteOffset=3
  Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
   ByteOffset=3
  Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
   ByteOffset=4
  Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
   ByteOffset=4
 EndSelect

 For Lines=0 To IH-1
  *pxData1 = Buffer + (Lines*pitch)
  *pxData2 = *pxData1 + pitch-4
  For t=0 To (IW/2)-1
   m=*pxData1\l
   *pxData1\l=*pxData2\l
   *pxData2\l=m
   *pxData1 + ByteOffset
   *pxData2 - ByteOffset
  Next
 Next
 StopDrawing()
 
EndProcedure


Procedure SpriteGray(ID)
;grays a ID
If IsSprite(id)=0:ProcedureReturn 0:EndIf

 StartDrawing(SpriteOutput(ID))
 IW = SpriteWidth(ID)
 IH = SpriteHeight(ID)
 Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
 Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 *pxData1.LONG
 PixelFormat=DrawingBufferPixelFormat()
 
 Select PixelFormat
  Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
   ByteOffset=1
  Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
   ByteOffset=3
  Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
   ByteOffset=3
  Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
   ByteOffset=4
  Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
   ByteOffset=4
 EndSelect

 For Lines=0 To IH-1
  *pxData1 = Buffer + (Lines*pitch)
  For t=0 To IW-1
   m=*pxData1\l
 
   Select Pixelformat
    Case #PB_PixelFormat_16Bits

    Case #PB_PixelFormat_24Bits_BGR,#PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
     
     p=m >> 24 & $FF ;the additive alpha
     r= m >> 16 & $FF
     g= m >> 8 & $FF
     b= m  & $FF
     gray=((r*29)+(g*58)+(b*11))/100
     m=   gray | gray << 8 | gray << 16 | p << 24

    Case #PB_PixelFormat_24Bits_RGB,#PB_PixelFormat_32Bits_RGB
     p=m >> 24 & $FF ;the additive alpha
     b= m >> 16 & $FF
     g= m >> 8 & $FF
     r= m  & $FF
     gray=((r*29)+(g*58)+(b*11))/100
     m=   gray | gray << 8 | gray << 16 | p << 24

   EndSelect
     
   *pxData1\l=m
   *pxData1 + ByteOffset
  Next
 Next
 StopDrawing()
 
EndProcedure

Procedure SpriteShadow(ID,TransparentColor=0)
;transform a sprite into a shadow
If IsSprite(id)=0:ProcedureReturn 0:EndIf

 StartDrawing(SpriteOutput(ID))
 IW = SpriteWidth(ID)
 IH = SpriteHeight(ID)
 Buffer      = DrawingBuffer()             ; Get the start address of the screen buffer
 Pitch       = DrawingBufferPitch()        ; Get the length (in byte) took by one horizontal line
 *pxData1.LONG
 PixelFormat=DrawingBufferPixelFormat()
 
 Select PixelFormat
  Case   #PB_PixelFormat_8Bits       ; 1 Byte pro Pixel, mit Palette ("palettized")
   ByteOffset=1
  Case #PB_PixelFormat_15Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_16Bits      ; 2 Byte pro Pixel
   ByteOffset=2
  Case #PB_PixelFormat_24Bits_RGB  ; 3 Byte pro Pixel (RRGGBB)
   ByteOffset=3
  Case #PB_PixelFormat_24Bits_BGR  ; 3 Byte pro Pixel (BBGGRR)
   ByteOffset=3
  Case #PB_PixelFormat_32Bits_RGB  ; 4 Byte pro Pixel (RRGGBB)
   ByteOffset=4
  Case #PB_PixelFormat_32Bits_BGR  ; 4 Byte pro Pixel (BBGGRR)
   ByteOffset=4
 EndSelect

 For Lines=0 To IH-1
  *pxData1 = Buffer + (Lines*pitch)
  For t=0 To IW-1
   m=*pxData1\l
   If m=TransparentColor
    ;do nothing
   Else
    m=0
   EndIf 
   *pxData1\l=m
   *pxData1 + ByteOffset
  Next
 Next
 StopDrawing()
 
EndProcedure


If OpenScreen(800,600, 32, "Sprite")

  lp=LoadSprite(0, "data/Geebee2.bmp", #PB_Sprite_Texture)
  If lp=0
   Debug "sprite not loaded"
   End
  EndIf
  TransparentSpriteColor(0, RGB(255, 0, 255)) ; Our pink is transparent :)
 
  ;Draw some boxes
  StartDrawing(SpriteOutput(0))
     Box(0,0,30,30,RGB(250,250,50))
     Box(SpriteWidth(0)-30,0,30,30,RGB(50,250,50))
     Box(SpriteWidth(0)-30,SpriteHeight(0)-30,30,30,RGB(50,50,250))
     Box(0,SpriteHeight(0)-30,30,30,RGB(50,250,250))
  StopDrawing()

  CopySprite(0,1,  #PB_Sprite_Texture)
  SpriteMirrorHorizontal(1)
  TransparentSpriteColor(1, RGB(255, 0, 255)) ; Our pink is transparent :)
  CopySprite(0,2,  #PB_Sprite_Texture)
  SpriteMirrorVertical(2)
  TransparentSpriteColor(2, RGB(255, 0, 255)) ; Our pink is transparent :)
 
  CopySprite(0,3,  #PB_Sprite_Texture)
  SpriteGray(3)
  TransparentSpriteColor(3, RGB(255, 0, 255)) ; Our pink is transparent :)
 
  CopySprite(0,4,  #PB_Sprite_Texture)
  SpriteShadow(4,RGB(255, 0, 255))
  TransparentSpriteColor(4, RGB(255, 0, 255)) ; Our pink is transparent :)

  Repeat
    FlipBuffers()
    ClearScreen(RGB(200,200,255))
    DisplaySprite(0, 00, 30);original
    DisplayTransparentSprite(1, 200, 30);horizontal
    DisplayTransparentSprite(2, 400, 30);vertical
    DisplayTransparentSprite(3, 600, 30);gray
   
    DisplayTransparentSprite(4, 0, 230);Shadow
   
    ExamineKeyboard()
    x+1
  Until x > 2500 Or KeyboardPushed(#PB_Key_Escape)
Else
  MessageRequester("Error", "Can't open a screen !", 0)
EndIf
End
Thanks!

Thalius
"In 3D there is never enough Time to do Things right,
but there's always enough Time to make them *look* right."
"psssst! i steal signatures... don't tell anyone! ;)"
User avatar
michel51
Enthusiast
Enthusiast
Posts: 290
Joined: Mon Nov 21, 2005 10:21 pm
Location: Germany

Re: Flip,gray,shadow Sprites ,All PB Versions-No Api

Post by michel51 »

Rings wrote: MacOSX perhaps ?[/code]
On Mac the code is not running, because the "spriteoutput()" occurs an error.
Spriteoutput is not supportet on Mac (see help) or it's a bug :!:
michel51

Mac OS X Snow Leopard (10.6.8 ) Intel
PureBasic V 5.21(x64), V 5.22beta
User avatar
Rings
Moderator
Moderator
Posts: 1427
Joined: Sat Apr 26, 2003 1:11 am

Re: Flip,gray,shadow Sprites ,All PB Versions-No Api

Post by Rings »

michel51 wrote:
Rings wrote: MacOSX perhaps ?[/code]
On Mac the code is not running, because the "spriteoutput()" occurs an error.
Spriteoutput is not supportet on Mac (see help) or it's a bug :!:
thx for testing.
so for now, its not possible to create
userdrawn sprites on mac....
i'm sure that will be changed in the future.
SPAMINATOR NR.1
Post Reply