December 04, 2020, 11:18:36 AM

Author Topic: [bb] transparent sprites in b+ by ford escort [ 1+ years ago ]  (Read 433 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
Title : transparent sprites in b+
Author : ford escort
Posted : 1+ years ago

Description : 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:)

Code :
Code: BlitzBasic
  1. ;------this must be included before the functions call
  2. Dim lookup#(255)
  3. For a=0 To 255
  4.         lookup#(a)=(a*1.0)/100
  5. Next
  6. ;------------------------------------------------------
  7. Function bufferize(image,flag,rm,gm,bm) ; this function convert a picture to a rgb coded memorybank
  8.                                                                         ; flag 1 free the memory of the original image after the process                                                       
  9.                                                                         ;rm,gm,bm rgb of the color mask (not drawed)
  10.         w=ImageWidth(image)                     ;get the width
  11.         h=ImageHeight(image)                    ;get the height
  12.         bank=CreateBank((w*h*3)+7)              ;the First 4 bytes to store the width and height of the picture+3 for the mask
  13.         LockBuffer ImageBuffer(image)   ;lock the buffer to speedup things
  14.         PokeShort(bank,0,w)             ;store the imaghe width
  15.         PokeShort(bank,2,h)             ;store the image height
  16.         PokeByte(bank,4,rm)             ;store the red value of the mask
  17.         PokeByte(bank,5,gm)             ;store the green value of the mask
  18.         PokeByte(bank,6,bm)             ;store the blue value of the mask
  19.         offset=7
  20.         For y=0 To h-1                                  ;
  21.                 For x=0 To w-1                          ;
  22.                         c=(ReadPixelFast(x,y,ImageBuffer(image))Shl 8)Shr 8 ; read the curent pixel
  23.                         r=(c Shl 8)Shr 24
  24.                         g=(c Shl 16)Shr 24
  25.                         b=(c Shl 24)Shr 24
  26.                         PokeByte bank,offset,r;store the red value of the curent pixel
  27.                         offset=offset+1
  28.                         PokeByte bank,offset,g;store the green value of the curent pixel
  29.                         offset=offset+1
  30.                         PokeByte bank,offset,b;store the blue value of the curent pixel
  31.                         offset=offset+1
  32.                 Next
  33.         Next
  34. UnlockBuffer ImageBuffer(image)
  35. If flag=1
  36.         FreeImage image
  37. EndIf
  38. Return bank
  39. End Function
  41. ;usage:
  42. ;
  43. ;
  44. ;alphasprite(bank,xx,yy,percent,flag)
  45. ;bank : the handle of the bank containing the sprite (made with bufferize function)
  46. ;xx,yy: onscreen coordinate where the sprite will be drawn
  47. ;percent: transparency percentage
  48. ;flag : if set to 1 the mask color will not be drawn same as maskimage
  49. ;
  50. 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
  51.         buffer=GraphicsBuffer()
  52.         gtw=GraphicsWidth()
  53.         gth=GraphicsHeight()
  54.         w=PeekShort(bank,0)
  55.         h=PeekShort(bank,2)
  56.         rm=PeekByte(bank,4)
  57.         gm=PeekByte(bank,5)
  58.         bm=PeekByte(bank,6)
  59.         offset=7
  60.         LockBuffer buffer
  61.         For y=0 To h-1                          ;
  62.                 For x=0 To w-1
  63.                         r2=PeekByte(bank,offset)        ;the
  64.                         offset=offset+1                         ;r
  65.                         g2=PeekByte(bank,offset)        ;b
  66.                         offset=offset+1                         ;values
  67.                         b2=PeekByte(bank,offset)        ;the
  68.                         offset=offset+1                         ;pictures
  69.                         If xx+x<=Gtw And yy+y<=GtH      ; the coordinates are IN the drawing buffer
  70.                                 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
  71.                                         c=ReadPixelFast(xx+x,yy+y,buffer) ; read the curent pixel
  72.                                         r1=(c Shl 8)Shr 24
  73.                                         g1=(c Shl 16)Shr 24
  74.                                         b1=(c Shl 24)Shr 24
  75.                                         r=(lookup(r2)*(percent)+lookup(r1)*(100-(percent)))Shl 16;prepare the values
  76.                                         g=(lookup(g2)*(percent)+lookup(g1)*(100-(percent)))Shl 8  ;to
  77.                                         b=(lookup(b2)*(percent)+lookup(b1)*(100-(percent)))       ;bewritepixeled
  78.                                         WritePixelFast xx+x,yy+y,r+g+b,buffer;draw the new color pixel
  79.                                 EndIf                  
  80.                         EndIf
  81.                 Next
  82.         Next
  83.         UnlockBuffer buffer
  84. End Function

Comments :

Clyde(Posted 1+ years ago)

 Excellent Routine Mate, Welldone :)

Andy_A(Posted 1+ years ago)

 Here's an optimized version of ford escort's routine with a simple usage demo.
Code: [Select]
;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

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

FreeBank bankPointer%
FreeImage bknd%


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()

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
PokeByte bank,offset,PeekByte(rgbVal%,1) ;store current pixel grn value
PokeByte bank,offset,PeekByte(rgbVal%,0) ;store current pixel blu value
UnlockBuffer ImageBuffer(image)
If flag=1
FreeImage image
End If
FreeBank rgbVal%
Return bank
End Function

;=================== 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

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

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

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)

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
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
End Function


SimplePortal 2.3.6 © 2008-2014, SimplePortal