Pixmaps don't draw alpha?
BlitzMax Forums/BlitzMax Beginners Area/Pixmaps don't draw alpha?
| ||
So I have started to make a painting program in Blitz using pixmaps, but I quickly came across a problem: pixmaps don't work with alpha. In this piece of jumble I've put together, the gradient should get more transparent on the right, and more solid on the left. Also, try painting: the brush is solid, but it should be soft. You can see, on mouse over, that I have encoded the pixels correctly (the first two letters of the hex value are for alpha), yet it doesn't draw correctly. And yes, the format is RGBA8888 and yes, ALPHABLEND is on. SuperStrict Framework brl.blitz Import brl.glmax2d Import brl.retro Import brl.polledinput Import brl.keycodes Graphics 800, 600 SetBlend(ALPHABLEND) SetColor(255, 255, 255) SetAlpha(1) SetClsColor(255, 200, 200) Global pix:TPixmap = CreatePixmap(256, 256, PF_RGBA8888) ClearPixels(pix, $BBBBBBBB) For Local xx:Int = 0 To 255 For Local yy:Int = 0 To 255 WritePixel(pix, xx, yy, MakeCol(xx, 0, yy, 255)) Next Next While Not AppTerminate() Cls If MouseX() >= 20 And MouseX() < 276 And MouseY() >= 20 And MouseY() < 276 DrawText(Hex:String(ReadPixel(pix, MouseX() - 20, MouseY() - 20)), 310, 40) If MouseDown(MOUSE_LEFT) DrawBrush() DrawPixmap(pix, 20, 20) Flip Wend Function MakeCol:Int(a:Byte, r:Byte, g:Byte, b:Byte) Local n:Int Local m:Byte ptr = VarPtr n m[0] = b m[1] = g m[2] = r m[3] = a Return n EndFunction Function DrawBrush() Local rx:Int = MouseX() - 20 Local ry:Int = MouseY() - 20 For Local aa:Int = 0 To 360 Step 2 For Local d:Int = 0 To 17 writepix(pix, rx + Ceil(d * Cos(aa)), ry + Ceil(d * Sin(aa)), MakeCol(Ceil(255 - (255 / 17) * d), 0, 255, 0)) Next Next End Function Function writepix(pixmap:TPixmap, x:Int, y:Int, argb:Int) If x >= 0 And x < pixmap.width And y >= 0 And y < pixmap.height And pixmap <> Null WritePixel(pixmap, x, y, argb) EndFunction |
| ||
DrawPixmap transfers pixel data from main memory directly into the backbuffer in video ram. It doesn't do any `blending` whatsoever. It's basically kind of like a `CopyRect` function. You copy existing pixels as-is to a destination as-is. Blending modifies pixels on the fly which does not happen with pixmaps. If you want to blend your pixmap you must convert it to an Image first. |
| ||
Gah, I was afraid you would say something like that. However, I did find a function which does what I described, but it's buggy: GLDrawPixmap. Try replacing my DrawPixmap with it, and you'll see what I mean. You'll also see that my brush idea failed, but I've sorted that out now using http://en.wikipedia.org/wiki/Alpha_compositing that. With that in mind, if I can't get DrawPixmap to work or GLDrawPixmap to work reliably, how fast would it be to draw the pixmap, alpha blended, pixel by pixel? |
| ||
try drawing your pixmap as image. local pixmap:tpixmap . . . image:timage = loadimage(pixmap) |
| ||
How about this way:SuperStrict Framework brl.blitz Import brl.glmax2d Import brl.retro Import brl.polledinput Import brl.keycodes Graphics 800, 600 SetBlend(ALPHABLEND) SetColor(255, 255, 255) SetAlpha(1) SetClsColor(255, 200, 200) Global img:TImage = CreateImage(256, 256, 0) Global pix:TPixmap = CreatePixmap(256, 256, PF_RGBA8888) ClearPixels(pix, $BBBBBBBB) For Local xx:Int = 0 To 255 For Local yy:Int = 0 To 255 WritePixel(pix, xx, yy, MakeCol(xx, 0, yy, 255)) Next Next img = LoadImage(pix,0) While Not AppTerminate() Cls If MouseX() >= 20 And MouseX() < 276 And MouseY() >= 20 And MouseY() < 276 DrawText(Hex:String(ReadPixel(pix, MouseX() - 20, MouseY() - 20)), 310, 40) If MouseDown(MOUSE_LEFT) DrawBrush() 'DrawPixmap(pix, 20, 20) DrawImage(img, 20, 20) Flip Wend Function MakeCol:Int(a:Byte, r:Byte, g:Byte, b:Byte) Local n:Int Local m:Byte Ptr = Varptr n m[0] = b m[1] = g m[2] = r m[3] = a Return n EndFunction Function DrawBrush() Local rx:Int = MouseX() - 20 Local ry:Int = MouseY() - 20 For Local aa:Int = 0 To 360 Step 2 For Local d:Int = 0 To 17 writepix(pix, rx + Ceil(d * Cos(aa)), ry + Ceil(d * Sin(aa)), MakeCol(Ceil(255 - (255 / 17) * d), 0, 255, 0)) Next Next img = LoadImage(pix,0) End Function Function writepix(pixmap:TPixmap, x:Int, y:Int, argb:Int) If x >= 0 And x < pixmap.width And y >= 0 And y < pixmap.height And pixmap <> Null WritePixel(pixmap, x, y, argb) EndFunction |
| ||
Damn... I can't believe I didn't notice that. Thanks :D |
| ||
I suppose you could GrabPixmap from the backbuffer, do a manual alpha blend with your other pixmap, then DrawPixmap. But Images will be WAY faster to draw. |
| ||
I do what Jesse says. |