Improved support for non-PVRTC compressed texture formats in .pvr files.

This commit is contained in:
Alex Szpakowski
2015-11-28 10:33:17 -04:00
parent 890e8f1086
commit 7265f891de
3 changed files with 118 additions and 11 deletions
+2 -2
View File
@@ -165,7 +165,7 @@ Variant *Variant::fromLua(lua_State *L, int n, bool allowTables)
if (allowTables)
{
bool success = true;
std::vector<std::pair<Variant*, Variant*> > *table = new std::vector<std::pair<Variant*, Variant*> >();
std::vector<std::pair<Variant*, Variant*>> *table = new std::vector<std::pair<Variant*, Variant*>>();
lua_pushnil(L);
while (lua_next(L, n))
{
@@ -230,7 +230,7 @@ void Variant::toLua(lua_State *L)
// I can do (at the moment).
break;
case TABLE:
lua_newtable(L);
lua_createtable(L, 0, (int) data.table->size());
for (size_t i = 0; i < data.table->size(); ++i)
{
std::pair<Variant*, Variant*> &kv = data.table->at(i);
+1 -1
View File
@@ -71,7 +71,7 @@ public:
size_t len;
} string;
void *userdata;
std::vector<std::pair<Variant*, Variant*> > *table;
std::vector<std::pair<Variant*, Variant*>> *table;
} data;
private:
+115 -8
View File
@@ -59,19 +59,59 @@ struct PVRTexHeaderV3
enum PVRV3PixelFormat
{
ePVRTPF_PVRTCI_2bpp_RGB = 0x00,
ePVRTPF_PVRTCI_2bpp_RGB = 0,
ePVRTPF_PVRTCI_2bpp_RGBA,
ePVRTPF_PVRTCI_4bpp_RGB,
ePVRTPF_PVRTCI_4bpp_RGBA,
ePVRTPF_PVRTCII_2bpp,
ePVRTPF_PVRTCII_2bpp = 4,
ePVRTPF_PVRTCII_4bpp,
ePVRTPF_ETC1 = 0x06,
ePVRTPF_DXT1,
ePVRTPF_ETC1 = 6,
ePVRTPF_DXT1 = 7,
ePVRTPF_DXT2,
ePVRTPF_DXT3,
ePVRTPF_DXT4,
ePVRTPF_DXT5,
ePVRTF_UNKNOWN_FORMAT = 0x7F
ePVRTPF_BC4,
ePVRTPF_BC5,
ePVRTPF_BC6,
ePVRTPF_BC7,
ePVRTPF_ETC2_RGB = 22,
ePVRTPF_ETC2_RGBA,
ePVRTPF_ETC2_RGBA1,
ePVRTPF_EAC_R = 25,
ePVRTPF_EAC_RG,
ePVRTPF_ASTC_4x4 = 27,
ePVRTPF_ASTC_5x4,
ePVRTPF_ASTC_5x5,
ePVRTPF_ASTC_6x5,
ePVRTPF_ASTC_6x6,
ePVRTPF_ASTC_8x5,
ePVRTPF_ASTC_8x6,
ePVRTPF_ASTC_8x8,
ePVRTPF_ASTC_10x5,
ePVRTPF_ASTC_10x6,
ePVRTPF_ASTC_10x8,
ePVRTPF_ASTC_10x10,
ePVRTPF_ASTC_12x10,
ePVRTPF_ASTC_12x12,
ePVRTPF_UNKNOWN_FORMAT = 0x7F
};
enum PVRV3ChannelType
{
ePVRTCT_UNORM8 = 0,
ePVRTCT_SNORM8,
ePVRTCT_UINT8,
ePVRTCT_SINT8,
ePVRTCT_UNORM16,
ePVRTCT_SNORM16,
ePVRTCT_UINT16,
ePVRTCT_SINT16,
ePVRTCT_UNORM32,
ePVRTCT_SNORM32,
ePVRTCT_UINT32,
ePVRTCT_SINT32,
ePVRTCT_FLOAT
};
// 'P' 'V' 'R' '!'
@@ -158,13 +198,26 @@ void ConvertPVRHeader(PVRTexHeaderV2 header2, PVRTexHeaderV3 *header3)
header3->pixelFormat = ePVRTPF_ETC1;
break;
default:
header3->pixelFormat = ePVRTF_UNKNOWN_FORMAT;
header3->pixelFormat = ePVRTPF_UNKNOWN_FORMAT;
break;
}
}
static CompressedImageData::Format convertFormat(PVRV3PixelFormat format)
static CompressedImageData::Format convertFormat(PVRV3PixelFormat format, PVRV3ChannelType channeltype)
{
bool snorm = false;
switch (channeltype)
{
case ePVRTCT_SNORM8:
case ePVRTCT_SNORM16:
case ePVRTCT_SNORM32:
snorm = true;
break;
default:
break;
}
switch (format)
{
case ePVRTPF_PVRTCI_2bpp_RGB:
@@ -183,6 +236,39 @@ static CompressedImageData::Format convertFormat(PVRV3PixelFormat format)
return CompressedImageData::FORMAT_DXT3;
case ePVRTPF_DXT5:
return CompressedImageData::FORMAT_DXT5;
case ePVRTPF_BC4:
if (snorm)
return CompressedImageData::FORMAT_BC4s;
else
return CompressedImageData::FORMAT_BC4;
case ePVRTPF_BC5:
if (snorm)
return CompressedImageData::FORMAT_BC5s;
else
return CompressedImageData::FORMAT_BC5;
case ePVRTPF_BC6:
if (snorm)
return CompressedImageData::FORMAT_BC6Hs;
else
return CompressedImageData::FORMAT_BC6H;
case ePVRTPF_BC7:
return CompressedImageData::FORMAT_BC7;
case ePVRTPF_ETC2_RGB:
return CompressedImageData::FORMAT_ETC2_RGB;
case ePVRTPF_ETC2_RGBA:
return CompressedImageData::FORMAT_ETC2_RGBA;
case ePVRTPF_ETC2_RGBA1:
return CompressedImageData::FORMAT_ETC2_RGBA1;
case ePVRTPF_EAC_R:
if (snorm)
return CompressedImageData::FORMAT_EAC_Rs;
else
return CompressedImageData::FORMAT_EAC_R;
case ePVRTPF_EAC_RG:
if (snorm)
return CompressedImageData::FORMAT_EAC_RGs;
else
return CompressedImageData::FORMAT_EAC_RG;
default:
return CompressedImageData::FORMAT_UNKNOWN;
}
@@ -208,11 +294,20 @@ int getBitsPerPixel(uint64 pixelformat)
case ePVRTPF_PVRTCII_4bpp:
case ePVRTPF_ETC1:
case ePVRTPF_DXT1:
case ePVRTPF_BC4:
case ePVRTPF_ETC2_RGB:
case ePVRTPF_ETC2_RGBA1:
case ePVRTPF_EAC_R:
return 4;
case ePVRTPF_DXT2:
case ePVRTPF_DXT3:
case ePVRTPF_DXT4:
case ePVRTPF_DXT5:
case ePVRTPF_BC5:
case ePVRTPF_BC6:
case ePVRTPF_BC7:
case ePVRTPF_ETC2_RGBA:
case ePVRTPF_EAC_RG:
return 8;
default:
return 0;
@@ -244,7 +339,16 @@ void getFormatMinDimensions(uint64 pixelformat, int &minX, int &minY)
case ePVRTPF_DXT3:
case ePVRTPF_DXT4:
case ePVRTPF_DXT5:
case ePVRTPF_BC4:
case ePVRTPF_BC5:
case ePVRTPF_BC6:
case ePVRTPF_BC7:
case ePVRTPF_ETC1:
case ePVRTPF_ETC2_RGB:
case ePVRTPF_ETC2_RGBA:
case ePVRTPF_ETC2_RGBA1:
case ePVRTPF_EAC_R:
case ePVRTPF_EAC_RG:
minX = minY = 4;
break;
default: // We don't handle all possible formats, but that's fine.
@@ -324,7 +428,10 @@ uint8 *PVRHandler::parse(filesystem::FileData *filedata, std::vector<CompressedI
if (header3.depth > 1)
throw love::Exception("Image depths greater than 1 in PVR files are unsupported.");
CompressedImageData::Format cformat = convertFormat((PVRV3PixelFormat) header3.pixelFormat);
PVRV3PixelFormat pixelformat = (PVRV3PixelFormat) header3.pixelFormat;
PVRV3ChannelType channeltype = (PVRV3ChannelType) header3.channelType;
CompressedImageData::Format cformat = convertFormat(pixelformat, channeltype);
if (cformat == CompressedImageData::FORMAT_UNKNOWN)
throw love::Exception("Could not parse PVR file: unsupported image format.");