Excellent Routine Mate, Welldone :)
Code archives/Graphics/transparent sprites in b+
This code has been declared by its author to be Public Domain code.
Download source code
| i'm not sure it's fast enought to use it in games or maybe for small sprites and not too much of these but here's the code anyway:) |
;------this must be included before the functions call Dim lookup#(255) For a=0 To 255 lookup#(a)=(a*1.0)/100 Next ;------------------------------------------------------ Function bufferize(image,flag,rm,gm,bm) ; this function convert a picture to a rgb coded memorybank ; flag 1 free the memory of the original image after the process ;rm,gm,bm rgb of the color mask (not drawed) w=ImageWidth(image) ;get the width h=ImageHeight(image) ;get the height bank=CreateBank((w*h*3)+7) ;the 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 imaghe width PokeShort(bank,2,h) ;store the image height PokeByte(bank,4,rm) ;store the red value of the mask PokeByte(bank,5,gm) ;store the green value of the mask PokeByte(bank,6,bm) ;store the blue value of the mask offset=7 For y=0 To h-1 ; For x=0 To w-1 ; c=(ReadPixelFast(x,y,ImageBuffer(image))Shl 8)Shr 8 ; read the curent pixel r=(c Shl 8)Shr 24 g=(c Shl 16)Shr 24 b=(c Shl 24)Shr 24 PokeByte bank,offset,r;store the red value of the curent pixel offset=offset+1 PokeByte bank,offset,g;store the green value of the curent pixel offset=offset+1 PokeByte bank,offset,b;store the blue value of the curent pixel offset=offset+1 Next Next UnlockBuffer ImageBuffer(image) If flag=1 FreeImage image EndIf 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 the mask color will not be drawn same as maskimage ; Function alphasprite(bank,xx,yy,percent,flag); this draw a previously memory saved image to the position x,yand percent alpha blending if flag=1 then masked 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) offset=7 LockBuffer buffer For y=0 To h-1 ; For x=0 To w-1 r2=PeekByte(bank,offset) ;the offset=offset+1 ;r g2=PeekByte(bank,offset) ;b offset=offset+1 ;values b2=PeekByte(bank,offset) ;the offset=offset+1 ;pictures 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 c=ReadPixelFast(xx+x,yy+y,buffer) ; read the curent pixel r1=(c Shl 8)Shr 24 g1=(c Shl 16)Shr 24 b1=(c Shl 24)Shr 24 r=(lookup(r2)*(percent)+lookup(r1)*(100-(percent)))Shl 16;prepare the values g=(lookup(g2)*(percent)+lookup(g1)*(100-(percent)))Shl 8 ;to b=(lookup(b2)*(percent)+lookup(b1)*(100-(percent))) ;bewritepixeled WritePixelFast xx+x,yy+y,r+g+b,buffer;draw the new color pixel EndIf EndIf Next Next UnlockBuffer buffer End Function |
Comments
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