📄 gbitmap.cc
字号:
#if defined(TORQUE_OS_MAC)
*dst++ = (1 << 15) | (b << 10) | (g << 5) | (r << 0);
#else
*dst++ = (b << 1) | (g << 6) | (r << 11) | 1;
#endif
src += 3;
}
}
void (*bitmapConvertRGB_to_5551)(U8 *src, U32 pixels) = bitmapConvertRGB_to_5551_c;
//--------------------------------------------------------------------------
bool GBitmap::setFormat(BitmapFormat fmt)
{
if (getFormat() == fmt)
return true;
// this is a nasty pointer math hack
// is there a quick way to calc pixels of a fully mipped bitmap?
U32 pixels = 0;
for (U32 i=0; i < numMipLevels; i++)
pixels += getHeight(i) * getWidth(i);
switch (getFormat())
{
case RGB:
switch (fmt)
{
case RGB5551:
bitmapConvertRGB_to_5551(pBits, pixels);
internalFormat = RGB5551;
bytesPerPixel = 2;
break;
}
break;
default:
AssertWarn(0, "GBitmap::setFormat: unable to convert bitmap to requested format.");
return false;
}
U32 offset = 0;
for (U32 j=0; j < numMipLevels; j++)
{
mipLevelOffsets[j] = offset;
offset += getHeight(j) * getWidth(j) * bytesPerPixel;
}
return true;
}
//--------------------------------------------------------------------------
bool GBitmap::getColorBGRA(const U32 x, const U32 y, ColorI& rColor) const
{
if(!getColor(x, y, rColor))
return false;
//jk - swap red and blue...
U8 r = rColor.red;
rColor.red = rColor.blue;
rColor.blue = r;
return true;
}
bool GBitmap::setColorBGRA(const U32 x, const U32 y, ColorI& rColor)
{
//jk - copy then swap red and blue...
//jk - using a copy so the color object provided by the caller isn't swapped...
ColorI temp = rColor;
U8 r = temp.red;
temp.red = temp.blue;
temp.blue = r;
return setColor(x, y, temp);
}
bool GBitmap::getColor(const U32 x, const U32 y, ColorI& rColor) const
{
if (x >= width || y >= height)
return false;
if (internalFormat == Palettized && pPalette == NULL)
return false;
const U8* pLoc = getAddress(x, y);
switch (internalFormat) {
case Palettized:
rColor = pPalette->getColor(*pLoc);
break;
case Alpha:
case Intensity:
case Luminance:
rColor.set( *pLoc, *pLoc, *pLoc, *pLoc );
break;
case RGB:
rColor.set( pLoc[0], pLoc[1], pLoc[2], 255 );
break;
case RGBA:
rColor.set( pLoc[0], pLoc[1], pLoc[2], pLoc[3] );
break;
case RGB5551:
#if defined(TORQUE_OS_MAC)
rColor.red = (*((U16*)pLoc) >> 0) & 0x1F;
rColor.green = (*((U16*)pLoc) >> 5) & 0x1F;
rColor.blue = (*((U16*)pLoc) >> 10) & 0x1F;
rColor.alpha = ((*((U16*)pLoc) >> 15) & 0x01) ? 255 : 0;
#else
rColor.red = *((U16*)pLoc) >> 11;
rColor.green = (*((U16*)pLoc) >> 6) & 0x1f;
rColor.blue = (*((U16*)pLoc) >> 1) & 0x1f;
rColor.alpha = (*((U16*)pLoc) & 1) ? 255 : 0;
#endif
break;
default:
AssertFatal(false, "Bad internal format");
return false;
}
return true;
}
//--------------------------------------------------------------------------
bool GBitmap::setColor(const U32 x, const U32 y, ColorI& rColor)
{
if (x >= width || y >= height)
return false;
if (internalFormat == Palettized && pPalette == NULL)
return false;
U8* pLoc = getAddress(x, y);
switch (internalFormat) {
case Palettized:
rColor = pPalette->getColor(*pLoc);
break;
case Alpha:
case Intensity:
case Luminance:
*pLoc = rColor.alpha;
break;
case RGB:
dMemcpy( pLoc, &rColor, 3 * sizeof( U8 ) );
break;
case RGBA:
dMemcpy( pLoc, &rColor, 4 * sizeof( U8 ) );
break;
case RGB5551:
#if defined(TORQUE_OS_MAC)
*((U16*)pLoc) = (((rColor.alpha>0) ? 1 : 0)<<15) | (rColor.blue << 10) | (rColor.green << 5) | (rColor.red << 0);
#else
*((U16*)pLoc) = (rColor.blue << 1) | (rColor.green << 6) | (rColor.red << 11) | ((rColor.alpha>0) ? 1 : 0);
#endif
break;
default:
AssertFatal(false, "Bad internal format");
return false;
}
return true;
}
//------------------------------------------------------------------------------
void GBitmap::alphaBlend(const GBitmap& rBlend)
{
for (U32 yy=0; (yy<height) && (yy<rBlend.height); yy++)
{
for (U32 xx=0; (xx<width) && (xx<rBlend.width); xx++)
{
ColorI sColor, dColor;
rBlend.getColor(xx,yy,sColor);
if (sColor.alpha==255)
setColor(xx,yy,sColor);
else if (sColor.alpha>0)
{
getColor(xx,yy,dColor);
dColor.red=((sColor.alpha*(sColor.red-dColor.red))/255)+dColor.red;
dColor.green=((sColor.alpha*(sColor.green-dColor.green))/255)+dColor.green;
dColor.blue=((sColor.alpha*(sColor.blue-dColor.blue))/255)+dColor.blue;
setColor(xx,yy,dColor);
}
}
}
}
void GBitmap::alphaCopy(const GBitmap& rCopy)
{
for (U32 yy=0; (yy<height) && (yy<rCopy.height); yy++)
{
for (U32 xx=0; (xx<width) && (xx<rCopy.width); xx++)
{
ColorI sColor, dColor;
rCopy.getColor(xx,yy,sColor);
getColor(xx,yy,dColor);
dColor.alpha=sColor.alpha;
setColor(xx,yy,dColor);
}
}
}
//------------------------------------------------------------------------------
void GBitmap::blt(const GBitmap& rBlt, const U32 bltx, const U32 blty)
{
ColorI sColor;
for (U32 dy=blty, sy=0; (dy<height) && (sy<rBlt.height); dy++, sy++)
{
for (U32 dx=bltx, sx=0; (dx<width) && (sx<rBlt.width); dx++, sx++)
{
rBlt.getColor(sx,sy,sColor);
setColor(dx,dy,sColor);
}
}
}
void GBitmap::tile(const GBitmap& rTile)
{
for (U32 yy=0; (yy<height); yy+=rTile.height)
{
for (U32 xx=0; (xx<height); xx+=rTile.width)
{
blt(rTile,xx,yy);
}
}
}
//-----------------------------------------------------------------------------
GBitmap* GBitmap::createPaddedBitmap()
{
if (isPow2(getWidth()) && isPow2(getHeight()))
return NULL;
AssertFatal(getNumMipLevels() == 1,
"Cannot have non-pow2 bitmap with miplevels");
U32 width = getWidth();
U32 height = getHeight();
U32 newWidth = getNextPow2(getWidth());
U32 newHeight = getNextPow2(getHeight());
GBitmap* pReturn = new GBitmap(newWidth, newHeight, false, getFormat());
for (U32 i = 0; i < height; i++)
{
U8* pDest = (U8*)pReturn->getAddress(0, i);
const U8* pSrc = (const U8*)getAddress(0, i);
dMemcpy(pDest, pSrc, width * bytesPerPixel);
pDest += width * bytesPerPixel;
// set the src pixel to the last pixel in the row
const U8 *pSrcPixel = pDest - bytesPerPixel;
for(U32 j = width; j < newWidth; j++)
for(U32 k = 0; k < bytesPerPixel; k++)
*pDest++ = pSrcPixel[k];
}
for(U32 i = height; i < newHeight; i++)
{
U8* pDest = (U8*)pReturn->getAddress(0, i);
U8* pSrc = (U8*)pReturn->getAddress(0, height-1);
dMemcpy(pDest, pSrc, newWidth * bytesPerPixel);
}
//if (pBitmap->getFormat() == GBitmap::Palettized)
//{
// pReturn->pPalette = new GPalette;
// dMemcpy(pReturn->pPalette->getColors(), pBitmap->pPalette->getColors(), sizeof(ColorI) * 256);
// pReturn->pPalette->setPaletteType(pBitmap->pPalette->getPaletteType());
//}
return pReturn;
}
//------------------------------------------------------------------------------
//-------------------------------------- Persistent I/O
//
#define EXT_ARRAY_SIZE 5
static const char* extArray[EXT_ARRAY_SIZE] = { "", ".jpg", ".png", ".gif", ".bmp" };
ResourceObject * GBitmap::findBmpResource(const char * path)
{
char fileNameBuffer[512];
dStrcpy( fileNameBuffer, path );
// Try some different possible filenames.
U32 len = dStrlen( fileNameBuffer );
for( U32 i = 0; i < EXT_ARRAY_SIZE; i++ )
{
dStrcpy( fileNameBuffer + len, extArray[i] );
ResourceObject * ret = ResourceManager->find( fileNameBuffer );
if (ret)
return ret;
}
return NULL;
}
GBitmap *GBitmap::load(const char *path)
{
ResourceObject * ro = findBmpResource(path);
if (ro)
{
GBitmap *bmp = (GBitmap*)ResourceManager->loadInstance(ro);
return bmp;
}
// If unable to load texture in current directory
// look in the parent directory. But never look in the root.
char fileNameBuffer[512];
dStrcpy( fileNameBuffer, path );
char *name = dStrrchr( fileNameBuffer, '/' );
if( name )
{
*name++ = 0;
char *parent = dStrrchr( fileNameBuffer, '/' );
if( parent )
{
parent[1] = 0;
dStrcat( fileNameBuffer, name );
return load( fileNameBuffer );
}
}
return NULL;
}
bool GBitmap::read(Stream& io_rStream)
{
// Handle versioning
U32 version;
io_rStream.read(&version);
AssertFatal(version == csFileVersion, "Bitmap::read: incorrect file version");
//-------------------------------------- Read the object
U32 fmt;
io_rStream.read(&fmt);
internalFormat = BitmapFormat(fmt);
bytesPerPixel = 1;
switch (internalFormat) {
case Alpha:
case Palettized:
case Luminance:
case Intensity: bytesPerPixel = 1;
break;
case RGB: bytesPerPixel = 3;
break;
case RGBA: bytesPerPixel = 4;
break;
case RGB565:
case RGB5551: bytesPerPixel = 2;
break;
default:
AssertFatal(false, "GBitmap::GBitmap: misunderstood format specifier");
break;
}
io_rStream.read(&byteSize);
pBits = new U8[byteSize];
io_rStream.read(byteSize, pBits);
io_rStream.read(&width);
io_rStream.read(&height);
io_rStream.read(&numMipLevels);
for (U32 i = 0; i < c_maxMipLevels; i++)
io_rStream.read(&mipLevelOffsets[i]);
if (internalFormat == Palettized) {
pPalette = new GPalette;
pPalette->read(io_rStream);
}
return (io_rStream.getStatus() == Stream::Ok);
}
bool GBitmap::write(Stream& io_rStream) const
{
// Handle versioning
io_rStream.write(csFileVersion);
//-------------------------------------- Write the object
io_rStream.write(U32(internalFormat));
io_rStream.write(byteSize);
io_rStream.write(byteSize, pBits);
io_rStream.write(width);
io_rStream.write(height);
io_rStream.write(numMipLevels);
for (U32 i = 0; i < c_maxMipLevels; i++)
io_rStream.write(mipLevelOffsets[i]);
if (internalFormat == Palettized) {
AssertFatal(pPalette != NULL,
"GBitmap::write: cannot write a palettized bitmap wo/ a palette");
pPalette->write(io_rStream);
}
return (io_rStream.getStatus() == Stream::Ok);
}
//-------------------------------------- GFXBitmap
ResourceInstance* constructBitmapJPEG(Stream &stream)
{
GBitmap* bmp = new GBitmap;
if (bmp->readJPEG(stream))
return bmp;
else
{
delete bmp;
return NULL;
}
}
ResourceInstance* constructBitmapPNG(Stream &stream)
{
GBitmap* bmp = new GBitmap;
if (bmp->readPNG(stream))
return bmp;
else
{
delete bmp;
return NULL;
}
}
ResourceInstance* constructBitmapBM8(Stream &stream)
{
GBitmap* bmp = new GBitmap;
if (bmp->readBmp8(stream))
return bmp;
else
{
delete bmp;
return NULL;
}
}
ResourceInstance* constructBitmapBMP(Stream &stream)
{
GBitmap *bmp = new GBitmap;
if(bmp->readMSBmp(stream))
return bmp;
else
{
delete bmp;
return NULL;
}
}
ResourceInstance* constructBitmapGIF(Stream &stream)
{
GBitmap *bmp = new GBitmap;
if(bmp->readGIF(stream))
return bmp;
else
{
delete bmp;
return NULL;
}
}
ResourceInstance* constructBitmapDBM(Stream &stream)
{
GBitmap* bmp = new GBitmap;
if (bmp->read(stream))
return bmp;
else
{
delete bmp;
return NULL;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -