Alphablend not working how I expected
BlitzMax Forums/BlitzMax Beginners Area/Alphablend not working how I expected
| ||
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 |
| ||
I don't see no black pixels.. |
| ||
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. |
| ||
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? |
| ||
You too, eh Jim. Hmm, this is a bit annoying. |
| ||
I get black pixels with DX driver and OK with GL driver. Using 7600gt |
| ||
Ah that explains it.. I was importing brl.glmax2d. |
| ||
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 |
| ||
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? |
| ||
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. |
| ||
maybe you can use an alternative: |
| ||
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. |
| ||
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. |
| ||
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 |
| ||
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. |
| ||
big10p : can't you use Jesse's previous code but add your flags to the loadimage(pm)... |
| ||
I tried that tonyg but it still doesn't work for mipmapped images in DX. |
| ||
Hmmm... it does for me. Are you sure you ran my edited code? |
| ||
Your code isn't using the MIPMAPPEDIMAGE flag, though. :) |
| ||
Blimey, my mistake. I'll take that comma out for you... |
| ||
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. |