Code archives/Graphics/transparent sprites in b+

This code has been declared by its author to be Public Domain code.

Download source code

transparent sprites in b+ by ford escort2004
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

Clyde2004
Excellent Routine Mate, Welldone :)


Andy_A2008
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



Code Archives Forum