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 escort
(Posted 23 years ago)
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

Clyde
(Posted 23 years ago)
Excellent Routine Mate, Welldone :)

Andy_A
(Posted 19 years ago)
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