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 ?
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