Here's an optimized version of ford escort's routine with a simple usage demo.
;transparent sprites in b+ by ford escort
;
;Inner-loop optimizations and simple demo by Andy_A
AppTitle "transparent sprites"
;------this must be included before the functions call
Dim lookup#(255), img%(255), bkd%(255)
populate() ;<- fills look-up table
Global sw=640,sh=480
Global hSprite%, bknd%
Graphics sw,sh,32,2
SetBuffer BackBuffer()
SeedRnd MilliSecs()
;create simple graphics
setUpGraphics()
bankPointer% = bufferize(hSprite%,1,0,0,0)
fntArial20% = LoadFont("Arial",20,True,False,False)
SetFont fntArial20%
Color 32,190,255
inc% = 5
blinkRate% = 64 ;<-- blink rate in milliseconds
maskFlag% = 1 ;<-- change to 0 for no masking
While MouseHit(1)=0
Cls
DrawBlock bknd,0,0
x = MouseX()
y = MouseY()
If st < MilliSecs() Then
st = MilliSecs() + blinkRate%
pct% = pct% + inc%
If pct% > 95 Then inc% = -5
If pct% < 5 Then inc% = 5
End If
Text (320,445,"'Click' to exit.",True,False)
alphasprite(bankPointer,x,y,pct%,maskFlag%)
Flip
Wend
FreeBank bankPointer%
FreeImage bknd%
End
;------------------------------------------------------
Function bufferize%(image%, flag%, rm%, gm%, bm%)
; this function converts a picture to an rgb coded memorybank
; set flag=1 to free the memory of the original image after 'bufferize-ing'
; rm,gm,bm rgb of the color mask (not drawn)
Local w%, h%, bank%, rgbVal%, offset%, x%, y%, r%, g%, b%
w=ImageWidth(image) ; get image width
h=ImageHeight(image) ; get image height
bank=CreateBank((w*h*3)+7) ; allot first 4 bytes to store the width and height
; of the picture+3 For the mask
LockBuffer ImageBuffer(image) ; lock the buffer to speedup things
PokeShort(bank,0,w) ; store the image width
PokeShort(bank,2,h) ; store the image height
PokeByte(bank,4,rm) ; store the red mask value
PokeByte(bank,5,gm) ; store the green mask value
PokeByte(bank,6,bm) ; store the blue mask value
rgbVal% = CreateBank(4) ; 4 byte bank stores value of ReadPixelFast()
offset=7
For y=0 To h-1
For x=0 To w-1
; read current pixel into rgbVal% bank
PokeInt(rgbVal%, 0,ReadPixelFast(x,y, ImageBuffer(image)))
; Store directly into bank (no SHIFTing! No ANDing! Very Fast!)
PokeByte bank,offset,PeekByte(rgbVal%,2) ;store current pixel red value
offset=offset+1
PokeByte bank,offset,PeekByte(rgbVal%,1) ;store current pixel grn value
offset=offset+1
PokeByte bank,offset,PeekByte(rgbVal%,0) ;store current pixel blu value
offset=offset+1
Next
Next
UnlockBuffer ImageBuffer(image)
If flag=1
FreeImage image
End If
FreeBank rgbVal%
Return bank
End Function
;usage:
;
;
;=================== alphasprite(bank, xx, yy, percent, flag) =======================
; bank : the handle of the bank containing the sprite (made with bufferize function)
; xx,yy: onscreen coordinate where the sprite will be drawn
; percent: transparency percentage
; flag : if set to 1 then mask color will not be drawn (same as maskimage)
;
;this draws the image previously saved in memory to x,y coords specified
;percent is the amount of opacity (0% = transparent, 100% = opaque)
;If flag=1 then masking color of memory saved image is NOT blended or drawn
Function alphasprite(bank%, xx%, yy%, percent%, flag%)
Local buffer%, gtw%, gth%, w%, h%, rm%, gm%, bm%, pixRGB%
Local i%, offset%, y%, x%, r1%, g1%, b1%, r2%, g2%, b2%
;make sure percent is within valid range of 0 <= percent <= 100
If percent < 0 Or percent > 100 Then percent = percent Mod 101
buffer=GraphicsBuffer()
gtw=GraphicsWidth()
gth=GraphicsHeight()
w=PeekShort(bank,0)
h=PeekShort(bank,2)
rm=PeekByte(bank,4)
gm=PeekByte(bank,5)
bm=PeekByte(bank,6)
pixRGB% = CreateBank(4) ; 4 byte bank stores value of ReadPixelFast()
; The bigger the image, the more cycles this saves
; as long as the image is 8x16 (128 pixels) or larger
For i = 0 To 255
img%(i) = Floor( lookup(i) * percent )
bkd%(i) = Floor( lookup(i) * (100-percent) )
Next
offset=7
LockBuffer buffer
For y=0 To h-1
For x=0 To w-1
r2=PeekByte(bank,offset) ; r
offset=offset+1 ; g
g2=PeekByte(bank,offset) ; b
offset=offset+1 ; values
b2=PeekByte(bank,offset) ; of the
offset=offset+1 ; bufferized image
If xx+x<=gtw And yy+y<=gth ; the coordinates are in the drawing buffer
If flag=0 Or (flag=1 And r2<>rm Or g2<>gm Or b2<>bm); the flag =0 or the colors are not the masked colors
; read the current pixel into pixRGB% bank
PokeInt(pixRGB%, 0,ReadPixelFast(xx+x, yy+y, buffer))
; store new rgb values into pixRGB% bank
PokeByte(pixRGB%, 2, img(r2)+bkd(PeekByte(pixRGB%,2))) ;r1))
PokeByte(pixRGB%, 1, img(g2)+bkd(PeekByte(pixRGB%,1))) ;g1))
PokeByte(pixRGB%, 0, img(b2)+bkd(PeekByte(pixRGB%,0))) ;b1))
;draw the alpha-blended pixel
WritePixelFast xx+x, yy+y, PeekInt(pixRGB%,0), buffer
End If
End If
Next
Next
UnlockBuffer buffer
FreeBank pixRGB%
End Function
;Create simple sprite and place random rect's on screen to see alpha effect
Function setUpGraphics%()
Local fntArial36B%, textWide%, textHigh%
Local i%, j%, k%, r%, g%, b%
Local msg$
Cls
fntArial36B = LoadFont("Arial", 36, True,False,False)
SetFont fntArial36B%
msg$ = "Alpha-Sprite!" ;<- place your own message here
txtWide% = StringWidth(msg$)
txtHigh% = StringHeight(msg$)
hSprite% = CreateImage(txtWide%, txtHigh%)
Color 255, 255, 255 ;set color of text
Text 100, 100, msg$
GrabImage(hSprite%, 100, 100)
Cls
For i% = 1 To 400
r% = Rand(0,192)
g% = Rand(0,176)
b% = Rand(0,255)
Color r%, g%, b%
j% = Rand(-50,540)
k% = Rand(-50,380)
Rect j%, k%, Rand(60,150), Rand(60,150),True
Color 255-r%, 255-g%, 255-b%
j% = Rand(-50,540)
k% = Rand(-50,380)
Oval j%, k%, Rand(60,150), Rand(60,150),True
Next
Color 0,0,0
Oval 240,435,160,40
SetBuffer BackBuffer()
;create image buffer the size of current window
bknd% = CreateImage(GraphicsWidth(), GraphicsHeight())
;grab what's on the screen and store in image buffer
GrabImage(bknd%, 0, 0)
FreeFont fntArial36B%
End Function
; fill the look-up table with float values
Function populate()
For a=0 To 255
lookup#(a)=Float(a)/100.0
Next
End Function
|