Difference between revisions of "Drawing sprites using any colour as transparent"
m (Reverted edit of LigetDarli, changed back to last version by Spammer-CnadrOncna)
|(7 intermediate revisions by 4 users not shown)|
Latest revision as of 11:27, 8 October 2009
One of the problems with the method that many sites will propose for drawing sprites is that you are forced to either use one particular colour for the mask colour, or have a separate picture stored for the mask. Or both. Unfortunately, this is often not very practical, and so you might think of using the conveniently existent TransparentBlt API. Annoyingly, the nice people at MS who wrote this function overlooked the fact that there's a horrible memory leak in it, and so it's a bad idea to use it. So what do you do? Well, you could either get the pixels using GetDIBits and 'blit' manually, or you can use several BitBlt calls and a couple of extra memory DCs to draw your image transparently.
Here's the code to do so:
Private Sub TransparentBlt(ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal lTransparentColor As Long) Dim mDC As Long, mBmp As Long Dim hTmpDC As Long, hTmpBmp As Long Dim hMonoDC As Long, hMonoBmp As Long Dim lOldBkColor As Long mDC = CreateCompatibleDC(hDestDC) mBmp = CreateCompatibleBitmap(hDestDC, cx, cy) DeleteObject SelectObject(mDC, mBmp) hTmpDC = CreateCompatibleDC(hDestDC) hTmpBmp = CreateCompatibleBitmap(hDestDC, cx, cy) DeleteObject SelectObject(hTmpDC, hTmpBmp) hMonoDC = CreateCompatibleDC(hDestDC) hMonoBmp = CreateBitmap(cx, cy, 1, 1, ByVal 0&) DeleteObject SelectObject(hMonoDC, hMonoBmp) '-- Set the backcolor so we can get a monochrome bitmap of the source lOldBkColor = SetBkColor(hSrcDC, lTransparentColor) '-- Copy the source into our monochrome bitmap BitBlt hMonoDC, 0, 0, cx, cy, hSrcDC, xSrc, ySrc, vbSrcCopy '-- Set the backcolor back to its original value SetBkColor hSrcDC, lOldBkColor '-- Get the background and draw the mask onto the background transparently with maskblt MaskBlt mDC, 0, 0, cx, cy, hDestDC, x, y, hMonoBmp, 0, 0, vbSrcCopy '-- Invert the mask BitBlt hMonoDC, 0, 0, cx, cy, hMonoDC, 0, 0, vbNotSrcCopy '-- Get the foreground and draw the inverted mask onto it transparently with maskblt MaskBlt hTmpDC, 0, 0, cx, cy, hSrcDC, xSrc, ySrc, hMonoBmp, 0, 0, vbSrcCopy '-- XOR the two together BitBlt mDC, 0, 0, cx, cy, hTmpDC, 0, 0, vbSrcInvert '-- Output the result BitBlt hDestDC, x, y, cx, cy, mDC, 0, 0, vbSrcCopy DeleteObject hMonoBmp DeleteDC hMonoDC DeleteObject hTmpBmp DeleteDC hTmpDC DeleteObject mBmp DeleteDC mDC End Sub
The comments explain the code. If you don't understand the comments, tough.