Update GFXTextureManager and GBitmap

GBitmap Changes:
Added all other formats to gbitmap that we support
gbitmap now supports cubemaps
added converters for all these other formats
added stb_image_resize for extrudemips so we can extrude mipmaps for all other formats

GFXTextureManager
Can now directly make cubemaps and texture arrays based on the GFXTextureProfile
API implementations for all functions that cubemaps and arrays needed
This commit is contained in:
marauder2k7 2025-12-22 10:29:01 +00:00
parent 975fc924cc
commit 3aef90a6bc
66 changed files with 4235 additions and 2590 deletions

View file

@ -652,6 +652,12 @@ Resource<DDSFile> DDSFile::load( const Torque::Path &path, U32 dropMipCount )
//------------------------------------------------------------------------------
bool DDSFile::isCompressedFormat(GFXFormat fmt)
{
return (fmt >= GFXFormatBC1 && fmt <= GFXFormatBC5) ||
(fmt >= GFXFormatBC1_SRGB && fmt <= GFXFormatBC3_SRGB);
}
DDSFile *DDSFile::createDDSFileFromGBitmap( const GBitmap *gbmp )
{
if( gbmp == NULL )
@ -666,6 +672,11 @@ DDSFile *DDSFile::createDDSFileFromGBitmap( const GBitmap *gbmp )
ret->mDepth = 0;
ret->mFormat = gbmp->getFormat();
ret->mFlags.set(RGBData);
if (gbmp->getNumFaces() == 6)
{
ret->mFlags.set(RGBData | CubeMapFlag | CubeMap_PosX_Flag | CubeMap_NegX_Flag | CubeMap_PosY_Flag |
CubeMap_NegY_Flag | CubeMap_PosZ_Flag | CubeMap_NegZ_Flag);
}
ret->mBytesPerPixel = gbmp->getBytesPerPixel();
ret->mMipMapCount = gbmp->getNumMipLevels();
ret->mHasTransparency = gbmp->getHasTransparency();
@ -685,36 +696,39 @@ DDSFile *DDSFile::createDDSFileFromGBitmap( const GBitmap *gbmp )
if( ret->mMipMapCount > 1 )
ret->mFlags.set(MipMapsFlag);
// One surface per GBitmap
ret->mSurfaces.push_back( new SurfaceData() );
// Load the mips
for( S32 i = 0; i < ret->mMipMapCount; i++ )
for (U32 face = 0; face < gbmp->getNumFaces(); face++)
{
const U32 mipSz = ret->getSurfaceSize(i);
ret->mSurfaces.last()->mMips.push_back( new U8[mipSz] );
// One surface per GBitmap
ret->mSurfaces.push_back(new SurfaceData());
U8 *mipMem = ret->mSurfaces.last()->mMips.last();
// If this is a straight copy, just do it, otherwise (ugh)
if( ret->mFormat == gbmp->getFormat() )
dMemcpy( mipMem, gbmp->getBits(i), mipSz );
else
// Load the mips
for (S32 i = 0; i < ret->mMipMapCount; i++)
{
// Assumption:
AssertFatal( gbmp->getBytesPerPixel() + 1 == ret->mBytesPerPixel, "Assumption failed, not 24->32 bit straight convert." );
const U32 mipSz = ret->getSurfaceSize(i);
ret->mSurfaces.last()->mMips.push_back(new U8[mipSz]);
for( S32 pxl = 0; pxl < gbmp->getWidth(i) * gbmp->getHeight(i); pxl++ )
U8* mipMem = ret->mSurfaces.last()->mMips.last();
// If this is a straight copy, just do it, otherwise (ugh)
if (ret->mFormat == gbmp->getFormat())
dMemcpy(mipMem, gbmp->getBits(i, face), mipSz);
else
{
U8 *dst = &mipMem[pxl * ret->mBytesPerPixel];
const U8 *src = &gbmp->getBits(i)[pxl * gbmp->getBytesPerPixel()];
dMemcpy( dst, src, gbmp->getBytesPerPixel() * sizeof(U8) );
dst[ret->mBytesPerPixel - 1] = 255;
}
}
// Assumption:
AssertFatal(gbmp->getBytesPerPixel() + 1 == ret->mBytesPerPixel, "Assumption failed, not 24->32 bit straight convert.");
// Uncomment to debug-dump each mip level
//ret->mSurfaces.last()->dumpImage( ret, i, avar( "%d_Gbmp_xmip%d", ret, i ) );
for (S32 pxl = 0; pxl < gbmp->getWidth(i) * gbmp->getHeight(i); pxl++)
{
U8* dst = &mipMem[pxl * ret->mBytesPerPixel];
const U8* src = &gbmp->getBits(i, face)[pxl * gbmp->getBytesPerPixel()];
dMemcpy(dst, src, gbmp->getBytesPerPixel() * sizeof(U8));
dst[ret->mBytesPerPixel - 1] = 255;
}
}
// Uncomment to debug-dump each mip level
//ret->mSurfaces.last()->dumpImage( ret, i, avar( "%d_Gbmp_xmip%d", ret, i ) );
}
}
return ret;
@ -777,22 +791,50 @@ DDSFile *DDSFile::createDDSCubemapFileFromGBitmaps(GBitmap **gbmps)
bool DDSFile::decompressToGBitmap(GBitmap *dest)
{
const bool isCube = isCubemap();
const U32 numFaces = isCube ? 6 : 1;
// TBD: do we support other formats?
if (mFormat != GFXFormatBC1 && mFormat != GFXFormatBC2 && mFormat != GFXFormatBC3)
return false;
if (!isCompressedFormat(mFormat))
{
dest->allocateBitmapWithMips(getWidth(), getHeight(), getMipLevels(), mFormat, numFaces);
U32 numMips = getMipLevels();
dest->allocateBitmapWithMips(getWidth(), getHeight(), getMipLevels(), GFXFormatR8G8B8A8);
for (U32 face = 0; face < numFaces; face++)
{
for (U32 i = 0; i < numMips; i++)
{
U8* addr = dest->getAddress(0, 0, i, face);
const U8* mipBuffer = mSurfaces[face]->mMips[i];
const U32 mipWidth = getWidth(i);
const U32 mipHeight = getHeight(i);
const U32 bpp = dest->getBytesPerPixel();
const U32 rowBytes = mipWidth * bpp;
for (U32 y = 0; y < mipHeight; ++y)
{
dMemcpy(addr + y * rowBytes, mipBuffer + y * rowBytes, rowBytes);
}
}
}
return true;
}
dest->allocateBitmapWithMips(getWidth(), getHeight(), getMipLevels(), GFXFormatR8G8B8A8, numFaces);
// Decompress and copy mips...
U32 numMips = getMipLevels();
for (U32 i = 0; i < numMips; i++)
for (U32 face = 0; face < numFaces; face++)
{
U8 *addr = dest->getAddress(0, 0, i);
const U8 *mipBuffer = mSurfaces[0]->mMips[i];
ImageUtil::decompress(mipBuffer, addr, getWidth(i), getHeight(i), mFormat);
for (U32 i = 0; i < numMips; i++)
{
U8* addr = dest->getAddress(0, 0, i, face);
const U8* mipBuffer = mSurfaces[face]->mMips[i];
ImageUtil::decompress(mipBuffer, addr, getWidth(i), getHeight(i), mFormat);
}
}
return true;