⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mrrgbaimage.cpp

📁 Games programming all in one code chapter 20
💻 CPP
字号:
 /* 'mrRGBAImage.cpp' */

 /* Complement header file */
#include "mrRGBAImage.h"

 /* Default constructor */
mrRGBAImage::mrRGBAImage (void)
{
 m_iWidth        = 0;
 m_iHeight       = 0;
 m_piImageBuffer = NULL;
}

 /* Default destructor */
mrRGBAImage::~mrRGBAImage (void)
{
 m_iWidth        = 0;
 m_iHeight       = 0;

  /* If memory was allocated, release it */
 if (NULL != m_piImageBuffer)
 {
  delete [] m_piImageBuffer;
  m_piImageBuffer = NULL;
 }
}

 /* Copy this image to another */
mrRGBAImage & mrRGBAImage::operator = (mrRGBAImage & rkImage)
{
 m_iWidth  = rkImage.GetWidth ();
 m_iHeight = rkImage.GetHeight ();
 SetImageBuffer (rkImage.GetImageBuffer ());

  /* Return an instance of this class */
 return * this;
}

 /* Load image from a windows bitmap file */
mrError32 mrRGBAImage::LoadFromBitmap (LPSTR lpszFilename)
{
 fstream      kBitmap;

 kBitmap.open (lpszFilename, ios::binary | ios::in);

	if (kBitmap.is_open ())
	{
		mrUInt16     iType;
		kBitmap.read ((char *) &iType, sizeof (mrUInt16));

			/* Get bitmap signature */
		if (0x4D42 != iType)
		{
			return mrErrorNotBitmapFile;
		}

			/* Ignore eight bytes */
		kBitmap.seekg (8, ios::cur);

			/* Get the position of the start of the bitmap buffer */
		mrUInt32     iStartBuffer;
		kBitmap.read ((char *) &iStartBuffer, sizeof (mrUInt32));

			/* Ignore four bytes */
		kBitmap.seekg (4, ios::cur);

			/* Get width and height of bitmap */
		kBitmap.read ((char *) &m_iWidth, sizeof (mrUInt32));
		kBitmap.read ((char *) &m_iHeight, sizeof (mrUInt32));
 
			/* Ignore two bytes */
		kBitmap.seekg (2, ios::cur);

			/* Get bit count */
		mrUInt16     iBitCount;
		kBitmap.read ((char *) &iBitCount, sizeof (mrUInt16));

			/* If not 24 mode not supported, return error */
		if (iBitCount != 24)
		{
			return mrErrorBitmapNotSupported;
		}
			/* Get compression */
		mrUInt32     iCompression;
		kBitmap.read ((char *) &iCompression, sizeof (mrUInt32));

			/* If compressed not supported, return error */
		if (iCompression != BI_RGB)
		{
			return mrErrorBitmapNotSupported;
		}
 
			/* Move to bitmap buffer */
		kBitmap.seekg (iStartBuffer, ios::beg);

			/* Read image buffer from file */
		mrUInt8 * piBuffer = new mrUInt8 [m_iWidth * m_iHeight * 3];
		kBitmap.read ((char *) piBuffer, m_iWidth * m_iHeight * 3 * 
																sizeof (mrUInt8));

			/* Allocate memory for image buffer */
		if (NULL != m_piImageBuffer)
		{
			delete [] m_piImageBuffer;
		}
		m_piImageBuffer = new mrUInt32 [m_iWidth * m_iHeight];

			/* Get each pixel color components and fill image buffer */ 
		mrUInt32 iX, iY;

		for (iY = 0; iY < m_iHeight; iY++)
		{
			for (iX = 0; iX < m_iWidth; iX++)
			{
					/* Needs to be flipped */
				if (m_iHeight > 0)
				{
						m_piImageBuffer [iX + (m_iHeight - 1 - iY) * (m_iWidth)] = 255 |
												(piBuffer [(iX + iY * (m_iWidth)) * 3 + 0] << 8) |
												(piBuffer [(iX + iY * (m_iWidth)) * 3 + 1] << 16) |
												(piBuffer [(iX + iY * (m_iWidth)) * 3 + 2] << 24);
				}
					/* Doesn't need to be flipped */
				else
				{
					m_piImageBuffer [iX + (iY * m_iWidth)] =  255 |
												(piBuffer [iX + (iY * m_iWidth) * 3 + 0] << 8) |
												(piBuffer [iX + (iY * m_iWidth) * 3 + 1] << 16) |
												(piBuffer [iX + (iY * m_iWidth) * 3 + 2] << 24);
				}
			}
		}

			/* Close file, release memory and return no error */
		if (NULL != piBuffer)
		{
			delete [] piBuffer;
		}

		kBitmap.close ();
	}

 return mrNoError;
}

 /* Load image from TARGA file */
mrError32 mrRGBAImage::LoadFromTarga (LPSTR lpszFilename)
{
 fstream      kTarga;

 kTarga.open (lpszFilename, ios::binary | ios::in);
	
	if (kTarga.is_open ())
	{
			/* Read field description size */
		mrUInt8      iFieldDescSize;
		kTarga.read ((char *) &iFieldDescSize, sizeof (mrUInt8));

			/* Ignore one byte */
		kTarga.seekg (1, ios::cur);

			/* Read image color code */
		mrUInt8      iImageCode;
		kTarga.read ((char *) &iImageCode, sizeof (mrUInt8));

		if (2 != iImageCode)
		{
			return mrErrorTargaNotSupported;
		}

			/* Ignore two bytes */
		kTarga.seekg (2, ios::cur);

			/* Read color map */
		mrUInt16      iMapLength;
		kTarga.read ((char *) &iMapLength, sizeof (mrUInt16));

			/* Ignore one byte */
		kTarga.seekg (1, ios::cur);

			/* Read image start positions */
		mrUInt16      iXStart;
		kTarga.read ((char *) &iXStart, sizeof (mrUInt16));
		mrUInt16      iYStart;
		kTarga.read ((char *) &iYStart, sizeof (mrUInt16));

			/* Read image size */
		mrUInt16      iWidth;
		kTarga.read ((char *) &iWidth, sizeof (mrUInt16));
		mrUInt16      iHeight;
		kTarga.read ((char *) &iHeight, sizeof (mrUInt16));

		m_iWidth  = iWidth;
		m_iHeight = iHeight;

			/* Read image bit depth */
		mrUInt8      iImageBits;

		kTarga.read ((char *) &iImageBits, sizeof (mrUInt8));
		if (32 != iImageBits)
		{
			return mrErrorTargaNotSupported;
		}

			/* Read image description */
		mrUInt8      iImageDesc;
		kTarga.read ((char *) &iImageDesc, sizeof (mrUInt8));
 
			/* Ignore field description */
		kTarga.seekg (iFieldDescSize, ios::cur);
			/* Ignore color map */
		kTarga.seekg (iMapLength * 4, ios::cur);
 
			/* Read image buffer from file */
		mrUInt32 * piBuffer = new mrUInt32 [m_iWidth * m_iHeight];
		kTarga.read ((char *) piBuffer, m_iWidth * m_iHeight * 4 * 
																sizeof (mrUInt8));

			/* Allocate memory for image buffer */
		if (NULL != m_piImageBuffer)
		{
			delete [] m_piImageBuffer;
		}
		m_piImageBuffer = new mrUInt32 [m_iWidth * m_iHeight];

		mrUInt8  iRed, iGreen, iBlue, iAlpha;
		mrUInt32 iColor;

			/* Get each pixel color components and fill image buffer */ 
		mrUInt32 iX, iY;

		for (iY = 0; iY < m_iHeight; iY++)
		{
			for (iX = 0; iX < m_iWidth; iX++)
			{
					/* Doens't need to be flipped */
				if ((iImageDesc & 1) << 4)
				{
						/* Get color components */
					iColor = piBuffer [iX + (iY * m_iWidth)];

					iAlpha = (mrUInt8)((iColor & 0xFF000000) >> 24);
					iRed   = (mrUInt8)((iColor & 0x00FF0000) >> 16);
					iGreen = (mrUInt8)((iColor & 0x0000FF00) >> 8);
					iBlue  = (mrUInt8)((iColor & 0x000000FF));

						/* Copy flipped position */
					m_piImageBuffer [iX + (iY * m_iWidth)] = 
												iAlpha << 0 | iBlue << 8 | iGreen << 16 | iRed << 24;
				}
					/* Needs to be flipped */
				else
				{
						/* Get color components */
					iColor = piBuffer [iX + (iY * m_iWidth)];

					iAlpha = (mrUInt8)((iColor & 0xFF000000) >> 24);
					iRed   = (mrUInt8)((iColor & 0x00FF0000) >> 16);
					iGreen = (mrUInt8)((iColor & 0x0000FF00) >> 8);
					iBlue  = (mrUInt8)((iColor & 0x000000FF));

						/* Copy position */
					m_piImageBuffer [iX + (m_iHeight - 1 - iY) * (m_iWidth)] = 
												iAlpha << 0 | iBlue << 8 | iGreen << 16 | iRed << 24;
				}
			}
		}

			/* Close file, release memory and return no error */
		if (NULL != piBuffer)
		{
			delete [] piBuffer;
		}

		kTarga.close ();
		}

 return mrNoError;

}


 /* Set image color key for rendering */
void mrRGBAImage::SetColorKey (mrUInt8 iRed, mrUInt8 iGreen, 
                               mrUInt8 iBlue)
{
  /* Get each pixel color components and set color key */ 
 mrUInt32 iX, iY;
 mrUInt8 iOriRed, iOriGreen, iOriBlue;

 for (iY = 0; iY < m_iHeight; iY++)
 {
  for (iX = 0; iX < m_iWidth; iX++)
  {
   iOriRed   = (mrUInt8)((m_piImageBuffer [iX + (iY * m_iWidth)] 
                         & 0xFF000000) >> 24);
   iOriGreen = (mrUInt8)((m_piImageBuffer [iX + (iY * m_iWidth)] 
                         & 0x00FF0000) >> 16);
   iOriBlue  = (mrUInt8)((m_piImageBuffer [iX + (iY * m_iWidth)] 
                         & 0x0000FF00) >> 8);

    /* If color matches, set alpha to 0 */
   if ( (iOriRed == iRed) && (iOriGreen == iGreen) && (iOriBlue == iBlue))
   {
    m_piImageBuffer [iX + (iY * m_iWidth)] = iOriRed   << 24 | 
                                             iOriGreen << 16 | 
                                             iOriBlue  << 8  | 
																																													0;
   }
  }
 }
}

 /* Set image width */
void mrRGBAImage::SetWidth (mrUInt32 iWidth)
{
 m_iWidth = iWidth;
}

 /* Set image height */
void mrRGBAImage::SetHeight (mrUInt32 iHeight)
{
 m_iHeight = iHeight;
}

 /* Set color at given position */
void mrRGBAImage::SetColor (mrUInt32 iX, mrUInt32 iY, mrUInt8 iRed, 
																												mrUInt8 iGreen, mrUInt8 iBlue, 
																												mrUInt8 iAlpha)
{
	mrUInt32 iColor;
	iColor = D3DCOLOR_RGBA (iRed, iGreen, iBlue, iAlpha);

 m_piImageBuffer [iX + (iY * m_iWidth - 1)] = iColor;
}

 /* Set the image buffer */
void mrRGBAImage::SetImageBuffer (mrUInt32 * pImage)
{
 if (NULL != m_piImageBuffer)
 {
  delete [] m_piImageBuffer;
 }
 m_piImageBuffer = new mrUInt32 [m_iWidth * m_iHeight];

 memcpy (m_piImageBuffer, pImage, 
         sizeof (mrUInt32) * m_iWidth * m_iHeight);
}

 /* Returns image width */
mrUInt32 mrRGBAImage::GetWidth (void)
{
 return m_iWidth;
}

 /* Returns image height */
mrUInt32 mrRGBAImage::GetHeight (void)
{
 return m_iHeight;
}

 /* Returns image color at a point */
mrUInt32 mrRGBAImage::GetColor (mrUInt32 iX, mrUInt32 iY)
{
 return m_piImageBuffer [iX + iY * m_iWidth];
}

 /* Returns image buffer */
mrUInt32 * mrRGBAImage::GetImageBuffer (void)
{
 return m_piImageBuffer;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -