Difference between revisions of "Drawing sprites using any colour as transparent"

From HashVB
Jump to: navigation, search
 
m
Line 18: Line 18:
 
          
 
          
 
         hMonoDC = CreateCompatibleDC(hDestDC)
 
         hMonoDC = CreateCompatibleDC(hDestDC)
         hMonoBmp = CreateBitmap(cx, cy, 1, 1, ByVal 0&)
+
         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.
+

Revision as of 12:49, 4 July 2007

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