Thread: drawing sprites with the windows gdi

  1. #1
    Registered User
    Join Date
    Aug 2001
    Posts
    380

    drawing sprites with the windows gdi

    This code draws a bitmap to the screen with the transparent color skipped. It sort of works, except the background shows through the image as shown in the attachment. Also, a red border is drawn between two sprites when two sprites are drawn over each other.

    What's wrong with my code this time?

    Code:
    int DrawSprite(HDC hdc, HBITMAP hbmColour,int x, int y, COLORREF crTransparent)
    {
    	HDC hdcMem, hdcMem2;
    	HBITMAP hbmMask, hOldBitmap, hOldBitmap2;
    	BITMAP bm;
    	GetObject(hbmColour, sizeof(BITMAP), &bm);
    	hbmMask = CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);
    
    	hdcMem = CreateCompatibleDC(hdc);
    	hdcMem2 = CreateCompatibleDC(hdc);
    
    	hOldBitmap = SelectObject(hdcMem, hbmColour);
    	hOldBitmap2 = SelectObject(hdcMem2, hbmMask);
    
    	SetBkColor(hdcMem, crTransparent);
    
    	BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
    
    	BitBlt(hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem2, 0, 0, SRCINVERT);
    
       BitBlt(hdc, x, y, bm.bmWidth, bm.bmHeight, hdcMem2, 0, 0, SRCAND);
    
    	BitBlt(hdc, x, y, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCPAINT);
    
       SelectObject(hdcMem, hOldBitmap);
       SelectObject(hdcMem2, hOldBitmap2);
    	DeleteDC(hdcMem);
    	DeleteDC(hdcMem2);
       DeleteObject(hbmMask);
    	return 0;
    }
    Don't you dare hit me on the head, you know I'm not normal.
    A Stooge Site
    Green Frog Software

  2. #2
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Sorry, I can't say for sure (I can't even tell what the problem is because the screenshot is so small lol). I'm thinking it's probably something about the mask, maybe it's not generating properly or something (I think I once had a problem with a translucent sprite, it was because I tried using a mask that I didn't generate). Also, I believe it's generally better to generate the mask and store it somewhere, then just use it when it's needed, instead of generating a new one every time - it's somewhat faster.

    Try testing to see if your mask generates properly, i.e. just take out the blitting of the sprite itself and draw the mask with SRCCOPY on a white screen.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  3. #3
    Registered User
    Join Date
    Aug 2001
    Posts
    380
    I have tried debugging the code myself and still havent found the problem. Maybe you or some else could look over it?

    Also, I tried storing the mask images instead of generating each time and this causes the game runs slower.
    Don't you dare hit me on the head, you know I'm not normal.
    A Stooge Site
    Green Frog Software

  4. #4
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Hmm, don't know how that would work. If you stored the mask images, it would take a bit more memory, but it would mean 1/2 the number of blits needed, and also you wouldn't need to allocate the memory for a bitmap each time.

    I'll take a look at the game in a minute...

    **EDIT**
    Just downloaded your code. A few problems:
    "unknown pragma" (#pragma resource)... compiler specific.
    You didn't include the header
    You didn't include the resource file
    Last edited by Hunter2; 08-13-2003 at 09:32 AM.
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  5. #5
    Registered User
    Join Date
    Aug 2001
    Posts
    380
    Here's the attachment with all the required files. The code as it is doesn't store masked images. Not that I see any, but there could be memory leaks somewhere that causes this method to be slow.
    Don't you dare hit me on the head, you know I'm not normal.
    A Stooge Site
    Green Frog Software

  6. #6
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    I was right, there's something wrong with your masks. To see the problem, comment out the 2nd, 3rd, and 5th BitBlt()'s in your DrawSprite function, and change the 4th BitBlt to a SRCCOPY instead of SRCAND. This should show you what the mask is, i.e. what you generated.

    I can give you the code I have for generating masks if you want; I'm pretty sure it doesn't have any (major) bugs

    **EDIT**
    Actually, to tell you the truth, I can't figure out what the 2nd and 3rd BitBlt's are supposed to accomplish...
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  7. #7
    Registered User
    Join Date
    Aug 2001
    Posts
    380
    Sure I'll try to use your code. Is the problem with my masks that you saw was that it had red where it should be black?
    Don't you dare hit me on the head, you know I'm not normal.
    A Stooge Site
    Green Frog Software

  8. #8
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Yes
    This is my code, it basically loops through every pixel and if the pixel is black, it turns it white, otherwise it sets it to black. You can change that around, make it look for a colour you choose, but I've never needed anything but black so... yeah. Also, I made this a while ago, and it's not exactly 100% up to date, you could probably improve it a lot if you tried (like, instead of relying on the parameters for width and height find it yourself or something).
    Code:
    HBITMAP GenerateMask(HDC hDC, int width, int height, int srcX, int srcY)
    {
        //hDC already has the colour bitmap selected in
        unsigned char* imageBits;
        static BITMAPINFO bi = {0};
        
        bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
        bi.bmiHeader.biBitCount = 24;
        bi.bmiHeader.biClrUsed = 0;
        bi.bmiHeader.biCompression = BI_RGB;
        bi.bmiHeader.biPlanes = 1;
        bi.bmiHeader.biWidth = width;
        bi.bmiHeader.biHeight = height;
        
        HBITMAP bitmap, oldBitmap;
        HDC compDC = CreateCompatibleDC(hDC);
        
        bitmap = CreateDIBSection(hDC, &bi, DIB_RGB_COLORS, (void**)&imageBits, 0, 0);
        oldBitmap = (HBITMAP)SelectObject(compDC, bitmap);
        
        BitBlt(compDC, 0, 0, width, height, hDC, srcX, srcY, SRCCOPY); //copy the bitmap to compDC
        
        for(int i = 0; i < width * height * 3; i += 3)
        {
            if(imageBits[i] == 0 && imageBits[i + 1] == 0 && imageBits[i + 2] == 0)
            {	//if it's black, make it white
                imageBits[i] = 255;
                imageBits[i + 1] = 255;
                imageBits[i + 2] = 255;
            }
            else
            {	//if it's not, make it black
                imageBits[i] = 0;
                imageBits[i + 1] = 0;
                imageBits[i + 2] = 0;
            }
        }
        
        SelectObject(compDC, oldBitmap);
        
        return bitmap;
    }
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  9. #9
    Registered User
    Join Date
    Aug 2001
    Posts
    380
    Thanks for your code. I have found out that changing the text color affects the mask color.
    Don't you dare hit me on the head, you know I'm not normal.
    A Stooge Site
    Green Frog Software

  10. #10
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    Great And it all works fine now?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  11. #11
    Registered User
    Join Date
    Aug 2001
    Posts
    380
    Yes
    Don't you dare hit me on the head, you know I'm not normal.
    A Stooge Site
    Green Frog Software

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. LoadFromFile() causes Windows 98 to freeze?
    By MidnightlyCoder in forum Windows Programming
    Replies: 8
    Last Post: 03-17-2006, 02:23 PM
  2. Question..
    By pode in forum Windows Programming
    Replies: 12
    Last Post: 12-19-2004, 07:05 PM
  3. IE 6 status bar
    By DavidP in forum Tech Board
    Replies: 15
    Last Post: 10-23-2002, 05:31 PM
  4. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM