Archived

This topic is now archived and is closed to further replies.

King9999

Help! Bitmap problem

Recommended Posts

I don't understand why my bitmaps aren't loading properly. I just want to make a simple Pong game, but the bitmaps are all screwed up. Here's an image displaying the problem: And here's Bitmap.cpp:
#include "Bitmap.h"

Bitmap::Bitmap()
  : m_hBitmap(NULL), m_iWidth(0), m_iHeight(0)
{
}

// Create a bitmap from a file

Bitmap::Bitmap(HDC hDC, LPTSTR szFileName)
  : m_hBitmap(NULL), m_iWidth(0), m_iHeight(0)
{
  Create(hDC, szFileName);
}

// Create a bitmap from a resource

Bitmap::Bitmap(HDC hDC, UINT uiResID, HINSTANCE hInstance)
  : m_hBitmap(NULL), m_iWidth(0), m_iHeight(0)
{
  Create(hDC, uiResID, hInstance);
}

// Create a blank bitmap from scratch

Bitmap::Bitmap(HDC hDC, int iWidth, int iHeight, COLORREF crColor)
  : m_hBitmap(NULL), m_iWidth(0), m_iHeight(0)
{
  Create(hDC, iWidth, iHeight, crColor);
}

Bitmap::~Bitmap()
{
  Free();
}

//-----------------------------------------------------------------

// Bitmap Helper Methods

//-----------------------------------------------------------------

void Bitmap::Free()
{
  // Delete the bitmap graphics object

  if (m_hBitmap != NULL)
  {
    DeleteObject(m_hBitmap);
    m_hBitmap = NULL;
  }
}

//-----------------------------------------------------------------

// Bitmap General Methods

//-----------------------------------------------------------------

BOOL Bitmap::Create(HDC hDC, LPTSTR szFileName)
{
  // Free any previous bitmap info

  Free();

  // Open the bitmap file

  HANDLE hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hFile == INVALID_HANDLE_VALUE)
    return FALSE;

  // Read the bitmap file header

  BITMAPFILEHEADER  bmfHeader;
  DWORD             dwBytesRead;
  BOOL bOK = ReadFile(hFile, &bmfHeader, sizeof(BITMAPFILEHEADER),
    &dwBytesRead, NULL);
  if ((!bOK) || (dwBytesRead != sizeof(BITMAPFILEHEADER)) ||
    (bmfHeader.bfType != 0x4D42))
  {
    CloseHandle(hFile);
    return FALSE;
  }

  BITMAPINFO* pBitmapInfo = (BITMAPINFO*)(new BITMAPINFO_256);
  if (pBitmapInfo != NULL)
  {
    // Read the bitmap info header

    bOK = ReadFile(hFile, pBitmapInfo, sizeof(BITMAPINFOHEADER),
      &dwBytesRead, NULL);
    if ((!bOK) || (dwBytesRead != sizeof(BITMAPINFOHEADER)))
    {
      CloseHandle(hFile);
      Free();
      return FALSE;
    }

    // Store the width and height of the bitmap

    m_iWidth = (int)pBitmapInfo->bmiHeader.biWidth;
    m_iHeight = (int)pBitmapInfo->bmiHeader.biHeight;

    // Skip (forward or backward) to the color info, if necessary

    if (pBitmapInfo->bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
      SetFilePointer(hFile, pBitmapInfo->bmiHeader.biSize - sizeof
        (BITMAPINFOHEADER), NULL, FILE_CURRENT);

    // Read the color info

    bOK = ReadFile(hFile, pBitmapInfo->bmiColors,
      pBitmapInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD), &dwBytesRead,
      NULL);

    // Get a handle to the bitmap and copy the image bits

    PBYTE pBitmapBits;
    m_hBitmap = CreateDIBSection(hDC, pBitmapInfo, DIB_RGB_COLORS,
      (PVOID*)&pBitmapBits, NULL, 0);
    if ((m_hBitmap != NULL) && (pBitmapBits != NULL))
    {
      SetFilePointer(hFile, bmfHeader.bfOffBits, NULL, FILE_BEGIN);
      bOK = ReadFile(hFile, pBitmapBits, pBitmapInfo->bmiHeader.biSizeImage,
        &dwBytesRead, NULL);
      if (bOK)
        return TRUE;
    }
  }

  // Something went wrong, so cleanup everything

  Free();
  return FALSE;
}

BOOL Bitmap::Create(HDC hDC, UINT uiResID, HINSTANCE hInstance)
{
  // Free any previous DIB info

  Free();

  // Find the bitmap resource

  HRSRC hResInfo = FindResource(hInstance, MAKEINTRESOURCE(uiResID), RT_BITMAP);
  if (hResInfo == NULL)
    return FALSE;

  // Load the bitmap resource

  HGLOBAL hMemBitmap = LoadResource(hInstance, hResInfo);
  if (hMemBitmap == NULL)
    return FALSE;

  // Lock the resource and access the entire bitmap image

  PBYTE pBitmapImage = (BYTE*)LockResource(hMemBitmap);
  if (pBitmapImage == NULL)
  {
    FreeResource(hMemBitmap);
    return FALSE;
  }

  // Store the width and height of the bitmap

  BITMAPINFO* pBitmapInfo = (BITMAPINFO*)pBitmapImage;
  m_iWidth = (int)pBitmapInfo->bmiHeader.biWidth;
  m_iHeight = (int)pBitmapInfo->bmiHeader.biHeight;

  // Get a handle to the bitmap and copy the image bits

  PBYTE pBitmapBits;
  m_hBitmap = CreateDIBSection(hDC, pBitmapInfo, DIB_RGB_COLORS,
    (PVOID*)&pBitmapBits, NULL, 0);
  if ((m_hBitmap != NULL) && (pBitmapBits != NULL))
  {
    const PBYTE pTempBits = pBitmapImage + pBitmapInfo->bmiHeader.biSize +
      pBitmapInfo->bmiHeader.biClrUsed * sizeof(RGBQUAD);
    CopyMemory(pBitmapBits, pTempBits, pBitmapInfo->bmiHeader.biSizeImage);

    // Unlock and free the bitmap graphics object

    UnlockResource(hMemBitmap);
    FreeResource(hMemBitmap);
    return TRUE;
  }

  // Something went wrong, so cleanup everything

  UnlockResource(hMemBitmap);
  FreeResource(hMemBitmap);
  Free();
  return FALSE;
}

BOOL Bitmap::Create(HDC hDC, int iWidth, int iHeight, COLORREF crColor)
{
  // Create a blank bitmap

  m_hBitmap = CreateCompatibleBitmap(hDC, iWidth, iHeight);
  if (m_hBitmap == NULL)
    return FALSE;

  // Set the width and height

  m_iWidth = iWidth;
  m_iHeight = iHeight;

  // Create a memory device context to draw on the bitmap

  HDC hMemDC = CreateCompatibleDC(hDC);

  // Create a solid brush to fill the bitmap

  HBRUSH hBrush = CreateSolidBrush(crColor);

  // Select the bitmap into the device context

  HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, m_hBitmap);

  // Fill the bitmap with a solid color

  RECT rcBitmap = { 0, 0, m_iWidth, m_iHeight };
  FillRect(hMemDC, &rcBitmap, hBrush);

  // Cleanup

  SelectObject(hMemDC, hOldBitmap);
  DeleteDC(hMemDC);
  DeleteObject(hBrush);

  return TRUE;
}

void Bitmap::Draw(HDC hDC, int x, int y, BOOL bTrans, COLORREF crTransColor)
{
  DrawPart(hDC, x, y, 0, 0, GetWidth(), GetHeight(), bTrans, crTransColor);
}

void Bitmap::DrawPart(HDC hDC, int x, int y, int xPart, int yPart,
  int wPart, int hPart, BOOL bTrans, COLORREF crTransColor)
{
  if (m_hBitmap != NULL)
  {
    // Create a memory device context for the bitmap

    HDC hMemDC = CreateCompatibleDC(hDC);

    // Select the bitmap into the device context

    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, m_hBitmap);

    // Draw the bitmap to the destination device context

    if (bTrans)
      TransparentBlt(hDC, x, y, wPart, hPart, hMemDC, xPart, yPart,
        wPart, hPart, crTransColor);
    else
      BitBlt(hDC, x, y, wPart, hPart, hMemDC, xPart, yPart, SRCCOPY);

    // Restore and delete the memory device context

    SelectObject(hMemDC, hOldBitmap);
    DeleteDC(hMemDC);
  }
}
The thing in the middle is supposed to be the ball, and the other two things are supposed to be the paddles. I have no idea why the images are being displayed like that. Help! [edited by - King9999 on January 23, 2004 8:58:20 PM] [edited by - King9999 on January 23, 2004 9:00:09 PM] [edited by - King9999 on January 23, 2004 9:02:36 PM]

Share this post


Link to post
Share on other sites
Looks like you are using Win 98, based on the grey color of the window in the screen shot. If your game executes the TransparentBlt, won't work in Win 98 (memory leak I heard), eventually you will get gibberish or nothing displayed. Appears to be cleaned up in Win ME and Win XP. I had this problem with TransparentBlt displaying bitmaps for my Pacman (only works in Win ME or Win XP, not Win 98). Also you don't need transparency unless you intend to have something in the background. With pong game and black back, BitBlt will be fine.

Second, looks like way too much code for a Pong game. Good that you are starting with a simple game, but I suggest you go simpler and use just FillRect for your paddles, and Ellipse for your ball, then your bitmap problem is solved since you won't be using bitmaps.

Third, overkill with C++ in my opinion. Here are my GDI demos, see my cat animation for bitmaps. All my games are straight C, nothing fancy

VazGames.com

Phil P

[edited by - PhilVaz on January 24, 2004 5:28:55 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by PhilVaz
Looks like you are using Win 98, based on the grey color of the window in the screen shot. If your game executes the TransparentBlt, won''t work in Win 98 (memory leak I heard), eventually you will get gibberish or nothing displayed. Appears to be cleaned up in Win ME and Win XP. I had this problem with TransparentBlt displaying bitmaps for my Pacman (only works in Win ME or Win XP, not Win 98). Also you don''t need transparency unless you intend to have something in the background. With pong game and black back, BitBlt will be fine.

Second, looks like way too much code for a Pong game. Good that you are starting with a simple game, but I suggest you go simpler and use just FillRect for your paddles, and Ellipse for your ball, then your bitmap problem is solved since you won''t be using bitmaps.

Third, overkill with C++ in my opinion. Here are my GDI demos, see my cat animation for bitmaps. All my games are straight C, nothing fancy

VazGames.com

Phil P

[edited by - PhilVaz on January 24, 2004 5:28:55 AM]


I didn''t know Win98 had a problem with TransparentBlt. I just had my bro run the game on WinXP, but the graphics were still messed up.

I guess I can use FillRect and Ellipse for now, but I''m not sure what I''m going to do when I want to use more complex bitmaps.

Share this post


Link to post
Share on other sites
<< I guess I can use FillRect and Ellipse for now, but I''m not sure what I''m going to do when I want to use more complex bitmaps. >>

No problem, just learn what you need as you make more complex games....

Right now, Pong with GDI FillRect (paddle) and Ellipse (ball) is fine. Get it done and over with. Won''t look much different with bitmaps. Then your next game maybe GDI with bitmaps, but first get a simple bitmap displayed with no bugs. I mean real simple, no animation, no fancy C++. Then move to DirectDraw and do bitmaps there. Then your 3D with OpenGL, then your 3D with DirectX.

There, I''ve just mapped out your next 5 game projects for the next 2 years. Wait that''s my path.... I''m at the DirectDraw stage.

VazGames.com

Phil P

Share this post


Link to post
Share on other sites