Jump to content
  • Advertisement
Sign in to follow this  

GDI Color Key issue

This topic is 4472 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

(OS: Win32, Language: C++, API: DirectX, Compiler: Mingw32) I just recently started working on a 2D fighter. I had never worked with sprites or anything similar before, and I figured a tutorial on DirectX was a good place to start. From the tutorial here. I was able to learn quite a bit, and I liked the C++ Class that he created enough I decided I was going to use it. The problem came when it was time to start combining elements. This code draws the background regardless of what is passed to the dwColorKey argument of cSurface::Create. The only exception is that pure black works (although the message board on that site suggests white may work as well). As I understand what is on the MSDN pages for the functions the author used, it should work. On an interesting note, in cSurface::LoadBitmap the call to StretchBlt (at least on my computer) does not seem to perfectly copy the colors from one surface to another. In the example I used, the color 0,128,192 on hdcImage became 0,130,198 on hdc. I tried to account for that by adjusting the keyed color to that one. I also suspected this may be an issue: ddck.dwColorSpaceLowValue = dwColorKey; ddck.dwColorSpaceHighValue = 0; Changing the HighValue to dwColorKey did not fix the problem, though. This problem came up a few times on the board for the page I got this from, but always the people solved the problem by painting the background pure black. That is not a valid option for me, though. Thank you in advance for any help. http://www.codeproject.com/directx/basicdd.asp cSurface.h:
#ifndef CSURFACE_H
#define CSURFACE_H

#include <windows.h>
#include <ddraw.h>

class cSurface
        //cSurface ();
        BOOL Create ( LPDIRECTDRAW7, int, int, COLORREF );
        BOOL LoadBitmap(HINSTANCE, HBITMAP &, int, int, 
            int, int);
        BOOL LoadBitmap(HINSTANCE, char *, int, int,
            int, int );
        BOOL Draw (LPDIRECTDRAWSURFACE7, int, int, int, int, int, int );
        int GetHeight ();
        int GetWidth ();
        void Destroy ();
        COLORREF m_ColorKey;
        UINT m_Height;
        UINT m_Width;
        LPDIRECTDRAWSURFACE7 m_pSurface;
        struct m_Info
            HINSTANCE m_hInstance;
            UINT m_nResource;
            int m_iX;
            int m_iY;
            int m_iWidth;
            int m_iHeight;
        struct m_Info m_srcInfo;


Excerpts from cSurface.cpp:
BOOL cSurface::Create(LPDIRECTDRAW7 hDD, int nWidth, int nHeight, 
                      COLORREF dwColorKey)
    DDSURFACEDESC2    ddsd;
    HRESULT        hRet;
    DDCOLORKEY          ddck;

    ZeroMemory( &ddsd, sizeof( ddsd ) );

    ddsd.dwSize = sizeof( ddsd );
    ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
    ddsd.dwWidth  = nWidth;
    ddsd.dwHeight = nHeight;

    hRet = hDD->CreateSurface(&ddsd, &m_pSurface, NULL );
    if( hRet != DD_OK )
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |
    hRet = hDD->CreateSurface(&ddsd, &m_pSurface, NULL );

    if( hRet != DD_OK )
        return FALSE;

    if((int)dwColorKey != -1)
    ddck.dwColorSpaceLowValue = dwColorKey;
    ddck.dwColorSpaceHighValue = 0;
    m_pSurface->SetColorKey(DDCKEY_SRCBLT, &ddck);

    m_ColorKey = dwColorKey;
    m_Width  = nWidth;
    m_Height = nHeight;

    return TRUE;

BOOL cSurface::LoadBitmap(HINSTANCE hInst, UINT nRes, int nX, int nY, 
                          int nWidth, int nHeight)
    HDC                     hdcImage;
    HDC                     hdc;
    BITMAP                  bm;
    DDSURFACEDESC2          ddsd;
    HRESULT                 hr;

    HBITMAP    hbm;

    hbm = (HBITMAP) LoadImage(hInst, MAKEINTRESOURCE(nRes), 
                              IMAGE_BITMAP, nWidth, nHeight, 0L);

    if (hbm == NULL || m_pSurface == NULL)
        return FALSE;

    // Make sure this surface is restored.

    // Select bitmap into a memoryDC so we can use it.
    hdcImage = CreateCompatibleDC(NULL);
    if (!hdcImage)
        return FALSE;

    SelectObject(hdcImage, hbm);

    // Get size of the bitmap
    GetObject(hbm, sizeof(bm), &bm);

    if(nWidth == 0)
    nWidth = bm.bmWidth;
    if(nHeight == 0)
    nHeight = bm.bmHeight;
    // Get size of surface.
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;

    if ((hr = m_pSurface->GetDC(&hdc)) == DD_OK)
        StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, 
                   nX, nY, nWidth, nHeight, SRCCOPY);

    m_srcInfo.m_hInstance = hInst;
    m_srcInfo.m_nResource = nRes;
    m_srcInfo.m_iX          = nX;
    m_srcInfo.m_iY          = nY;
    m_srcInfo.m_iWidth    = nWidth;
    m_srcInfo.m_iHeight      = nHeight;
    return TRUE;

BOOL cSurface::Draw(LPDIRECTDRAWSURFACE7 lpDest, int iDestX, int iDestY, 
                    int iSrcX, int iSrcY, int nWidth, int nHeight)
    RECT    rcRect;
    HRESULT    hRet;

    if(nWidth == 0)
        nWidth = m_Width;

    if(nHeight == 0)
        nHeight = m_Height;

    rcRect.left   = iSrcX;
    rcRect.top    = iSrcY;
    rcRect.right  = nWidth  + iSrcX;
    rcRect.bottom = nHeight + iSrcY;

        if((int)m_ColorKey < 0)
            hRet = lpDest->BltFast(iDestX, iDestY, m_pSurface, 
                                   &rcRect,  DDBLTFAST_NOCOLORKEY);
            hRet = lpDest->BltFast(iDestX, iDestY, m_pSurface, 
                                   &rcRect,  DDBLTFAST_SRCCOLORKEY);

        if(hRet == DD_OK)

        if(hRet == DDERR_SURFACELOST)
            if(hRet != DDERR_WASSTILLDRAWING)
                return FALSE;

    return TRUE;

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!