Mask ANY colour from a texture

Community Forums/Showcase/Mask ANY colour from a texture

Ross C(Posted 2004) [#1]
Hey, wasn't sure where to put this, so :)

This function will go through the texture passed across, and mask off the RGB colors passed across, so you don't always have to use black to mask.

This works by searching the texture, and finding the alpha values. The way masking works, is, if the alpha value is below 128 that texel will be masked. If it's over 128, it will be visible. Remember tho, masking in blitz3d doesn't work on the color of the texel, rather the alpha values in it.

You must provide your own Texture for this.

Additionally, i've provided a function to clear any mask values from a texture. Just call:

prepare_texture(tex)


To wipe any masking from a texture. This will wipe all alpha information from the texture. These functions are for use in game, probably before you game starts. I'll be adding more.


Graphics3D 800,600
SetBuffer BackBuffer()

cam=CreateCamera()
PositionEntity cam,0,0,-10

Global sprite=CreateSprite()
Global tex=LoadTexture("image1.png",4)
EntityTexture sprite,tex


cube=CreateCube()
PositionEntity cube,0,0,2
ScaleEntity cube,6,2,1


prepare_texture(tex)

While Not KeyHit(1)


	If KeyHit(2) Then texture_mask_colour(tex,  0,255,0,55) ; will clear green colours within 55 either way, fading.
	
	If KeyHit(4) Then texture_mask_colour(tex,0,0,0,50) ; will clear black and values 55 close to it.
	
	If KeyHit(3) EntityAlpha sprite,0.5
	UpdateWorld
	RenderWorld
	Text 0,0," Press 1 to mask green from the texture"
	Text 0,10," Press 3 to mask black from the texture"
	Text 0,20," Press 2 to turn on entityalpha "
	Flip
Wend
End


;--------------------------------------------------------------------
;  This function will clear a texture of all it's alpha information |
;--------------------------------------------------------------------
;parameters  =  texture : the texture you wish to clear alpha information from
Function prepare_texture(texture)

	LockBuffer TextureBuffer(texture)

	For loop=0 To TextureWidth(texture)
		For loop1=0 To TextureHeight(texture)

			RGB1=ReadPixelFast(loop,loop1,TextureBuffer(texture))
			r=(RGB1 And $FF0000)shr 16;separate out the red
			g=(RGB1 And $FF00) shr 8;green
			b=RGB1 And $FF;and blue parts of the color
			a=(RGB1 And $FF000000)Shr 24
			
			a=255; remove any alpha information currently in the texture.

			newrgb= (a shl 24) or (r shl 16) or (g shl 8) or b; combine the ARGB back into a number

			WritePixelFast(loop,loop1,newrgb,TextureBuffer(texture)); write the info back to the texture
		Next
	Next

	UnlockBuffer TextureBuffer(texture)

End Function


;---------------------------------------------------------------------
;  This function will mask the passed across RGB of the texture also |
;  passed across. Do NOT pass across a value for flag if you only    |
;  want to mask an exact colour.                                     |
;---------------------------------------------------------------------
;parameters = texture   : the texture you wish to clear alpha information from
;           = r1        : the red value to mask
;           = g1        : the green value to mask
;           = b1        : the blue value to mask
;           = tolerance : the tolerance value. If set to 0, then the function will only mask the
;                         EXACT colours passed across. Higher value will mask values close to the colour.

Function texture_mask_colour(texture,r1,g1,b1,tolerance=0)

	
	LockBuffer TextureBuffer(texture)

	For loop=0 To TextureWidth(texture)
		For loop1=0 To TextureHeight(texture)
			RGB1=ReadPixelFast(loop,loop1,TextureBuffer(texture)) ; read the RGB value from the texture
			r=(RGB1 And $FF0000)shr 16;separate out the red
			g=(RGB1 And $FF00) shr 8;green
			b=RGB1 And $FF;and blue parts of the color
			a=(RGB1 And $FF000000)Shr 24 ; extract the alpha

			If r>=r1-tolerance And r=<r1+tolerance And g=>g1-tolerance And g=<g1+tolerance And b=>b1-tolerance And b=<b1+tolerance Then; check RGB lies with the tolerance
				;temp=((Abs(r-r1)+Abs(g-g1)+Abs(b-b1))/3.0)*4.0 ; alpha the values based on the tolerance value
				a=0;temp

			End If

			newrgb= (a shl 24) or (r shl 16) or (g shl 8) or b ; combine the ARGB back into one value

			WritePixelFast(loop,loop1,newrgb,TextureBuffer(texture)); write back to the texture
		Next
	Next
	UnlockBuffer TextureBuffer(texture)
End Function



jfk EO-11110(Posted 2004) [#2]
Useful functions, but you could replace

r=(RGB1 And $FF0000)/$10000;separate out the red
g=(RGB1 And $FF00)/$100;green

and

newrgb= a*16777216+r*65536+g*256+b; combine the ARGB back into a number

by

r=(RGB1 And $FF0000)shr 16;separate out the red
g=(RGB1 And $FF00) shr 8;green

and

newrgb= (a shl 24) or (r shl 16) or (g shl 8) or b ; combine the ARGB back into a number

Tho ist's the same, but the second notation is probably more machine friendly. The "/$100" Notation is oftenly used when a Language doesn't offer logical bit-shifting commands. In fact those commands do exist on the CPU Command level.


Ross C(Posted 2004) [#3]
Ok, thanks for the tip :) I'll alter that!