Here is my blurred drop shadow demo:
If any of you can make this routine run (much) faster, please let me know!
I tried to make a pixmap with PF_A8 format for the alphachannel only. But that did not work because readpixel returns a 32 bit integer.
Anyway, here is the code (don't know how to include source code in a seperate scrollable text field).
Strict
Graphics 800, 600
AutoMidHandle(1)
SetClsColor 255,255,255
Const margin = 10
Local argbBlack:Int = (255 Shl 24)
Local argbWhite:Int = (255 Shl 24) + (255 Shl 16) + (255 Shl 8) + 255
Global rocket:Timage = LoadImage("gfx\blobship.png", DYNAMICIMAGE) 'or any other png file with alpha channel
Global rocketAlpha:TPixmap = CreatePixmap(rocket.width + margin * 2, rocket.height + margin * 2, PF_RGBA8888)
ClearPixels(rocketAlpha, 0)
Global shadow:TImage = CreateImage(rocketAlpha.width, rocketAlpha.height, DYNAMICIMAGE)
Global PixMap:TPixmap
pixmap = LockImage(rocket)
'copy alphaChannel from original image
For Local x:Int = 0 To rocket.width - 1
For Local y:Int = 0 To rocket.height - 1
Local a:Int = ReadPixel(pixmap, x, y)
a = (a Shr 24) Shl 24 'remove RGB values
WritePixel(rocketAlpha, x + margin, y + margin, a)
Next
Next
UnlockImage(rocket)
SetAlpha 1
SetBlend ALPHABLEND
Local r:Int = 0
Local fr:Float = 0
Local cx = 400
Local cy = 300
Local radius = 200
pixmap = LockImage(shadow)
blurImage(0.2 + fr * 0.8)
UnlockImage(shadow)
While Not KeyHit(KEY_ESCAPE)
Cls
SetRotation 0
SetColor 255, 0, 0
DrawRect 150, 150, 300, 200
SetRotation r + 180
SetColor 255, 255, 255
SetAlpha 0.4
Rem ******** remove rem to dynamically change the blur amount based on the altitude of the ship
pixmap = LockImage(shadow)
blurImage(0.2 + fr * 0.8)
UnlockImage(shadow)
End Rem
DrawImage shadow, cx+Cos(r) * radius + margin * (1-fr), cy + Sin(r) * radius + margin * (1-fr)
SetAlpha 1
DrawImage rocket, cx + Cos(r) * radius, cy + Sin(r) * radius
r = (r+1) Mod 360
fr = (Sin(r) + 1) / 2 'rotation between 0..1
Flip
Wend
End
'*************** modified blurring functions *******************
Function blurImage(k:Float = 0.5)
'k - blurring amount. Value between 0.0 and 1.0
' 0.1 = Extreme, 0.9 = Minimal
Local pm:TPixmap = CopyPixmap(rocketAlpha)
For Local x:Int = 1 To (pm.Width - 1)
For Local z:Int = 0 To (pm.Height - 1)
WritePixel(pm, x, z, blurPixel(ReadPixel(pm, x, z), ReadPixel(pm, x - 1, z), k))
Next
Next
For Local x:Int = (pm.Width - 3) To 0 Step -1
For Local z:Int = 0 To (pm.Height - 1)
WritePixel(pm, x, z, blurPixel(ReadPixel(pm, x, z), ReadPixel(pm, x + 1, z), k))
Next
Next
For Local x:Int = 0 To (pm.Width - 1)
For Local z:Int = 1 To (pm.Height - 1)
WritePixel(pm, x, z, blurPixel(ReadPixel(pm, x, z), ReadPixel(pm, x, z - 1), k))
Next
Next
For Local x:Int = 0 To (pm.Width - 1)
For Local z:Int = (pm.Height - 3) To 0 Step -1
WritePixel(pm, x, z, blurPixel(ReadPixel(pm, x, z), ReadPixel(pm, x, z + 1), k))
Next
Next
For Local x:Int = 0 To pm.width - 1
For Local y:Int = 0 To pm.height - 1
Local a = ReadPixel(pm, x, y)
WritePixel(pixmap, x, y, a)
Next
Next
End Function
'**************************************************************
Function blurPixel:Int(px:Int, px2:Int, k:Float)
Local fpx:Float = Float(px Shr 24)
Local fpx2:Float = Float(px2 Shr 24)
Return Int((fpx2 * (1 - k)) + (fpx * k)) Shl 24
EndFunction
'**************************************************************