Alphablend not working how I expected

BlitzMax Forums/BlitzMax Beginners Area/Alphablend not working how I expected

big10p(Posted 2008) [#1]
I create an image of a white circle on a black backround. Then I clear the black backgound pixels' alpha channel and set the white circle pixels' alpha channel to opaque.

Now, when I display the image using ALPHABLEND blend mode, it just displays as if I'm using SOLIDBLEND. I expected the black pixels to not be drawn at all. What have I done wrong?

	Graphics 800, 600

	Const IMAGE_FLAGS:Int = DYNAMICIMAGE | MIPMAPPEDIMAGE
	Local image:Timage = CreateImage(128, 128, 1, IMAGE_FLAGS)

	' Draw white circle on black background & copy to image.
	SetClsColor 0, 0, 0
	Cls 
	SetColor 255, 255, 255
	SetBlend SOLIDBLEND
	DrawOval 0, 0, 128, 128
	GrabImage image, 0, 0
	SetColor 255, 255, 255

	' Set black pixels to transparent and white pixels to opaque.
	Local pmap:TPixmap = LockImage(image, 0, False, False)
	For Local x:Int = 0 To PixmapWidth(pmap)-1
		For Local y:Int = 0 To PixmapHeight(pmap)-1
			Local p:Int = ReadPixel(pmap, x, y)

			If p=$FF000000
				' Clear alpha channel (transparent) on black pixels.
				WritePixel(pmap, x, y, $00000000) 
			Else
				' Set alpha channel (opaque) on white pixels.
				WritePixel(pmap, x, y, $FFFFFFFF)
			EndIf 
		Next
	Next
	UnlockImage image

	' Draw alphablended image.
	SetClsColor 150, 0, 150
	Cls
	SetBlend ALPHABLEND
	DrawImage image, 10, 10
	Flip

	WaitKey()
	End



plash(Posted 2008) [#2]
I don't see no black pixels..


Jim Teeuwen(Posted 2008) [#3]
For some reason it only works if I put SetGraphicsDriver(glmax2ddriver()) in at the top.

And it only works for the GL driver, not the directx drivers.


big10p(Posted 2008) [#4]
They're black here, believe me.

Just talking to someone on IRC who also gets the black pixels unless he uses SetGraphicsDriver(GLMax2DDriver()). That 'fix' also works for me. Wonder why the D3D driver doesn't work?


big10p(Posted 2008) [#5]
You too, eh Jim. Hmm, this is a bit annoying.


tonyg(Posted 2008) [#6]
I get black pixels with DX driver and OK with GL driver.
Using 7600gt


plash(Posted 2008) [#7]
Ah that explains it.. I was importing brl.glmax2d.


Jesse(Posted 2008) [#8]
for some reason when the DINAMICIMAGE flag is set it does not allow the image pixels to be replaced:

Graphics 800, 600

	Const IMAGE_FLAGS:Int = DYNAMICIMAGE | MIPMAPPEDIMAGE
	Local image:Timage = CreateImage(128, 128, 1, IMAGE_FLAGS)

	' Draw white circle on black background & copy to image.
	SetClsColor 0, 0, 0
	Cls 
	SetColor 255, 255, 255
	SetBlend SOLIDBLEND
	DrawOval 0, 0, 128, 128
	GrabImage image, 0, 0
	SetColor 255, 255, 255

	' Set black pixels to transparent and white pixels to opaque.
	Local pmap:TPixmap = LockImage(image, 0, False, False)
	For Local x:Int = 0 To PixmapWidth(pmap)-1
		For Local y:Int = 0 To PixmapHeight(pmap)-1
			Local p:Int = ReadPixel(pmap, x, y)
			Print Hex(P)
			If p=$FF000000
				' Clear alpha channel (transparent) on black pixels.
				WritePixel(pmap, x, y, $00000000) 
			Else
				' Set alpha channel (opaque) on white pixels.
				WritePixel(pmap, x, y, $FFFFFFFF)
			EndIf
			Print Hex(ReadPixel(PMAP,X,Y))
			Print "------------" 
		Next
	Next
	UnlockImage image

	' Draw alphablended image.
	SetClsColor 150, 0, 150
	Cls
	SetBlend ALPHABLEND
	DrawImage image, 10, 10
	Flip

	WaitKey()
	End



big10p(Posted 2008) [#9]
Yes, it seems like WritePixel has no effect when using the DX driver. I don't think it has anything to do with using the DYNAMICIMAGE flag as this is required in order to be able to lock the image in the first place.

Is this a bug/known issue then?


Jesse(Posted 2008) [#10]
I tried different flags and they seem to work.
I don't think it has been reported as a bug yet.

[edit]

you are right it writes to the pixmap but it doesn't write to the image.


Jesse(Posted 2008) [#11]
maybe you can use an alternative:



big10p(Posted 2008) [#12]
Jesse, unfortunately I need to use a mipmapped image which the DX driver still fails with. Obviously DX is having trouble writing the pixmap data back to the mipmapped texture for some reason.

I guess I should report this as a bug? I'm quite surprised no one has noticed this before, though.


Jesse(Posted 2008) [#13]
I am going to look to previous version and see if it didn't broke in the process of updating. I remember using it with no problems once before.
I just noticed in the bug section that Bmax 130 plash reported a bug in the pixmap module that wasn't there before.
http://www.blitzmax.com/Community/posts.php?topic=8125
maybe something else got broken too.


Jesse(Posted 2008) [#14]
I found out that grabimage convert rgba into rgb. I did some tests and my conclusion is that it does not grab the alpha channel from the max2d drawing page or there is no alpha channel in the drawing page:
	Graphics 800, 600

	Const IMAGE_FLAGS:Int = DYNAMICIMAGE | MIPMAPPEDIMAGE
	Local image:Timage = CreateImage(128, 128, 1, IMAGE_FLAGS)

	' Draw white circle on black background & copy to image.
	Local pmap:TPixmap = LockImage(image,0,False,False)
	Print
	Print "original format:"
	
	displayformat(pmap.Format)
	Print
	SetClsColor 0, 0, 0
	Cls 
	SetColor 255, 255, 255
	SetBlend SOLIDBLEND
	DrawOval 0, 0, 128, 128
	GrabImage image, 0, 0
	SetColor 255, 255, 255

	' Set black pixels to transparent and white pixels to opaque.
	pmap:TPixmap = LockImage(image, 0, False, False)
	Local n:Int = 0
	Print
	Print "after grabpixmap:"
	displayFormat(pmap.format)

Function displayFormat(Format:Int)
	Select Format
	
		Case PF_A8 Print "8 bit alpha" 
		Case PF_I8 Print "8 bit intensity"
		Case PF_RGB888 Print "24 bit big endian RGB" 
		Case PF_BGR888 Print "24 bit little endian RGB" 
		Case PF_RGBA8888 Print "32 bit big endian RGB with alpha" 
		Case PF_BGRA8888 Print "32 bit little endian RGB with alpha"

	End Select
End Function



big10p(Posted 2008) [#15]
Yeah, I don't know whether the backbuffer stores alpha or not. It's not really of any consequence though as I'm manually setting the alpha channel after grabing the image, anyway. The issue is getting the altered pixmap data back to a mipmapped image texture, when using the DX driver.


tonyg(Posted 2008) [#16]
big10p : can't you use Jesse's previous code but add your flags to the loadimage(pm)...



big10p(Posted 2008) [#17]
I tried that tonyg but it still doesn't work for mipmapped images in DX.


tonyg(Posted 2008) [#18]
Hmmm... it does for me. Are you sure you ran my edited code?


big10p(Posted 2008) [#19]
Your code isn't using the MIPMAPPEDIMAGE flag, though. :)


tonyg(Posted 2008) [#20]
Blimey, my mistake. I'll take that comma out for you...



big10p(Posted 2008) [#21]
Oh, I see. I tried it just with the DYNAMICIMAGE and MIPMAPPEDIMAGE flags set and it didn't work. It seems I also need to use the MASKEDIMAGE flag too, to get it to work in DX. Funny how I don't need to in OGL, though. Cheers.