sprite outline
Posted: Wed Oct 08, 2003 1:56 pm
Here is a procedure i wrote to create an outline for a sprite. It can be useful for example if you want to highlight a selected sprite object. The idea is to scan the sprite in four directions (left to right, right to left, top to bottom, bottom to top) and to write a specified outline color at the sprite boundaries. By excluding the transparent color it allows for a near-perfect outline. I say near-perfect because due to the scan loop breaking each time a boundary is met, a few boundaries pixels are not taken in account.
Although, it is already quite fast, i wonder if it can be accelerated even more or if anyone has a better idea to get a perfect outline.
Pythagoras
Although, it is already quite fast, i wonder if it can be accelerated even more or if anyone has a better idea to get a perfect outline.
Code: Select all
#GFX_OUTLINE = 1
Procedure DisplaySpriteOutline(sprite_id.l,x.l,y.l,transparent_color.l,outline_color.l)
CopySprite(sprite_id,#GFX_OUTLINE)
; From left to right - top to bottom
StartDrawing(SpriteOutput(#GFX_OUTLINE))
adr=DrawingBuffer()
add=DrawingBufferPitch()
StopDrawing()
For j=0 To SpriteHeight(#GFX_OUTLINE)-1
*adr2 =adr
For i=0 To SpriteWidth(#GFX_OUTLINE)-1
color.l = PeekL(*adr2)
If color <> transparent_color : PokeL(*adr2,outline_color) : break : EndIf
*adr2+4
Next
adr+add
Next
; From right to left - top to bottom
StartDrawing(SpriteOutput(#GFX_OUTLINE))
adr=DrawingBuffer()
add=DrawingBufferPitch()
StopDrawing()
For j=0 To SpriteHeight(#GFX_OUTLINE)-1
*adr2 =adr + (4*(SpriteWidth(#GFX_OUTLINE)-1))
For i=0 To SpriteWidth(#GFX_OUTLINE)-1
color.l = PeekL(*adr2)
If color <> transparent_color : PokeL(*adr2,outline_color) : break : EndIf
*adr2-4
Next
adr+add
Next
; From top to bottom - left to Right
StartDrawing(SpriteOutput(#GFX_OUTLINE))
adr=DrawingBuffer()
add=DrawingBufferPitch()
StopDrawing()
For i=0 To SpriteWidth(#GFX_OUTLINE)-1
*adr2 = adr
For j=0 To SpriteHeight(#GFX_OUTLINE)-1
color.l = PeekL(*adr2)
If color <> transparent_color : PokeL(*adr2,outline_color) : break : EndIf
*adr2+add
Next
adr+4
Next
; From bottom to top - left to Right
StartDrawing(SpriteOutput(#GFX_OUTLINE))
adr=DrawingBuffer()
add=DrawingBufferPitch()
StopDrawing()
For i=0 To SpriteWidth(#GFX_OUTLINE)-1
*adr2 = adr +(add*(SpriteHeight(#GFX_OUTLINE)-1))
For j=0 To SpriteHeight(#GFX_OUTLINE)-1
color.l = PeekL(*adr2)
If color <> transparent_color : PokeL(*adr2,outline_color) : break : EndIf
*adr2-add
Next
adr+4
Next
TransparentSpriteColor(#GFX_OUTLINE,Red(transparent_color),Green(transparent_color),Blue(transparent_color))
DisplayTransparentSprite(#GFX_OUTLINE,x,y)
FreeSprite(#GFX_OUTLINE)
EndProcedure
; TEST PROGRAM
InitSprite()
OpenWindow(1,100,100,100,#PB_Window_SystemMenu,"Outline")
OpenWindowedScreen(WindowID(),0,0,100,100,0,0,0)
; Load the sprite you want to test the procedure with and set the correct transparent color.
LoadSprite(2,"test.bmp") : TransparentSpriteColor(252,252,252)
Repeat
FlipBuffers()
ClearScreen(0,0,0)
DisplayTransparentSprite(2,50,50)
DisplaySpriteOutline(2,50,50,$FCFCFC,$FF0000)
Until EventID = #PB_EventCloseWindow