Per-Pixel Texture Alpha?

Blitz3D Forums/Blitz3D Programming/Per-Pixel Texture Alpha?

HappyCat(Posted 2005) [#1]
Is it possible to apply "true" per-pixel alpha to a texture in code?

I can apply the alpha to the texture okay (after the texture's been applied to the entity and using WritePixelFast(X, Y, (Alpha Shl 24) Or RGB, TextureBuffer) ) but it doesn't seem to be applied properly. Any pixels with alpha 128 or less are not rendered, while any pixels with alpha 129 or more are rendered fully opaque.

I've tried all sort of combinations of EntityBlend, EntityFX and TextureBlend, but most of those just make it worse :-)

Is this actually possible?


JoshK(Posted 2005) [#2]
LoadTexture() with a certain texture flags. (I think 4.)

Download TGATool to make textures with alpha channels:
www.leadwerks.com


HappyCat(Posted 2005) [#3]
I'm having to do it in code 'cos I'm building the texture at runtime.


Ross C(Posted 2005) [#4]
Your texture seems to be using masking, instead of alpha. When you create the texture, make sure you use the alpha flag.

Texture masking works on the basis of the number being above 128 being poaque and less then being transparent, as you have found out. But, probably because you are using the mask flag, instead of the alpha flag.


HappyCat(Posted 2005) [#5]
I'm pretty sure I'm passing the correct flag into the routine that creates the texture but I'm not sure if I've ever actually traced it through to make sure it gets to the CreateTexture properly. Thanks - I'll check it out.


jfk EO-11110(Posted 2005) [#6]
Halo - 4?!? WTH! Must be Alz..thingy...
It's t=createtexture(width, height, 2)

and if you have multiple texture layers, you may get troubles, depending on the blending modes of the other layers.

AND: if you read RGB, make sure to mask it with $FFFFFF to make sure its alpha byte won't deliver random bits.


HappyCat(Posted 2005) [#7]
I'd forgotten to mask the read pixel with $00ffffff, which is particularly daft as I knew I had to do it. Thanks guys, all working now :-)


(tu) sinu(Posted 2005) [#8]
could someone post a working example of this code cos i've been trying to create textures with the alpha working.thnx


HappyCat(Posted 2005) [#9]
What I did was either load or create your texture with TextureFlags = 2

I get the texture from an entity with:

Local Brush = GetEntityBrush(Entity)
Local Texture = GetBrushTexture(Brush)
Then I use ApplyAlphaToTexture (below) to apply alpha to the texture (very roughly) according to brightness:

Function ApplyAlphaToTexture(Texture)

	Local tw = TextureWidth(Texture)
	Local th = TextureHeight(Texture)
	
	Local tb=TextureBuffer(Texture)
	LockBuffer(tb)

	Local x,y
	For x=0 To tw-1
		For y=0 To th-1
	
			Local RGB = ReadPixelFast(x,y,tb) And $00ffffff
			
			Local Red = GetRedFromRGB(RGB)
			Local Green = GetGreenFromRGB(RGB)
			Local Blue = GetBlueFromRGB(RGB)

			; Calculate the alpha (very roughly) according to the brightness of the pixel
			Local Alpha = (Red + Green + Blue) / 3

			
			WritePixelFast(x, y, (Alpha Shl 24) Or RGB, tb)	
			
		Next
	Next
	
	UnlockBuffer tb
	
End Function

Function GetRedFromRGB(RGB)
	Return RGB / (256 * 256) + 256
End Function

Function GetGreenFromRGB(RGB)
	Return (RGB Mod (256 * 256)) / 256 + 256
End Function

Function GetBlueFromRGB(RGB)
	Return (RGB Mod (256 * 256)) Mod 256 + 256
End Function
Hope that helps.


jfk EO-11110(Posted 2005) [#10]
BTW:
Local Brush = GetEntityBrush(Entity)

will create a copy of the original brush, so you have to delete it when it isn't used anymore.


HappyCat(Posted 2005) [#11]
Yes, very true jfk :-)


I've hit a snag though. The following code (slightly different from what I posted above) works fine on one PC (with Geforce 4 gfx), but on another (with Intel gfx) the ReadPixelFast returns $0000FFFF for pixels that are quite clearly black (should be $00000000). In fact, for all pixels the Green and Blue are always $FF.

Anyone got any ideas why this might happen?

	Local TexBuff = TextureBuffer(Texture)
	LockBuffer(TexBuff)

	For X = 0 To TextureWidth(Texture) -1
		For Y = 0 To TextureHeight(Texture) -1
	
			Local RGB = ReadPixelFast(X, Y, TexBuff) And $00ffffff
			
			Local Red = (RGB Shr 16) And $ff
			Local Green = (RGB Shr 8) And $ff
			Local Blue = RGB And $ff
			Local Alpha = (Red + Green + Blue) / 3
			
			DebugLog (Hex(RGB) + " > " + Red + ", " + Green + ", " + Blue + " = " + Alpha)
			
			WritePixelFast(X, Y, (Alpha Shl 24) Or RGB, TexBuff)	
			
		Next
	Next
	
	UnlockBuffer(TexBuff)



HappyCat(Posted 2005) [#12]
More info: whatever I And the readpixel with, the last 2 bytes of the resulting value are the same as the last 2 bytes of the And value. So if I And it with $00123456 I get $00003456. It looks to my (inexpert) eye like ReadPixelFast is only returing 2 bytes.

This is all in 32-bit mode btw.


HappyCat(Posted 2005) [#13]
Actually I realised in the shower this morning that if the readpixel returns $0000FFFF then of course the last 2 bytes will equal the mask. So, erm, ignore the post above :-)

The problem (black pixels returning $0000FFFF) still remains though.