Unify pixel format enums for ImageData, CompressedImageData, and Canvas into a single PixelFormat enum.

Replace love.graphics.getRawImageFormats and love.graphics.getCompressedImageFormats with love.graphics.getImageFormats.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2016-11-27 22:53:23 -04:00
parent cbba8c40a6
commit 0a3adc0839
50 changed files with 1042 additions and 1006 deletions
+20 -255
View File
@@ -113,6 +113,8 @@ Image::Image(const std::vector<love::image::ImageData *> &imagedata, const Flags
for (const auto &id : imagedata)
data.push_back(id);
format = data[0]->getFormat();
preload();
loadVolatile();
@@ -148,6 +150,8 @@ Image::Image(const std::vector<love::image::CompressedImageData *> &compressedda
for (image::CompressedImageData *cd : compresseddata)
cdata.push_back(cd);
format = cdata[0]->getFormat();
preload();
loadVolatile();
@@ -230,7 +234,7 @@ void Image::loadDefaultTexture()
void Image::loadFromCompressedData()
{
GLenum iformat = getCompressedFormat(cdata[0]->getFormat(), sRGB);
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false, sRGB);
if (isGammaCorrect() && !sRGB)
flags.linear = true;
@@ -249,17 +253,15 @@ void Image::loadFromCompressedData()
auto cd = cdata.size() > 1 ? cdata[i].get() : cdata[0].get();
int datamip = cdata.size() > 1 ? 0 : i;
glCompressedTexImage2D(GL_TEXTURE_2D, i, iformat, cd->getWidth(datamip),
cd->getHeight(datamip), 0,
glCompressedTexImage2D(GL_TEXTURE_2D, i, fmt.internalformat,
cd->getWidth(datamip), cd->getHeight(datamip), 0,
(GLsizei) cd->getSize(datamip), cd->getData(datamip));
}
}
void Image::loadFromImageData()
{
GLenum glformat = GL_RGBA;
GLenum gltype = GL_UNSIGNED_BYTE;
GLenum iformat = getFormat(data[0]->getFormat(), glformat, gltype, sRGB);
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false, sRGB);
if (isGammaCorrect() && !sRGB)
flags.linear = true;
@@ -271,8 +273,8 @@ void Image::loadFromImageData()
love::image::ImageData *id = data[i].get();
love::thread::Lock lock(id->getMutex());
glTexImage2D(GL_TEXTURE_2D, i, iformat, id->getWidth(), id->getHeight(),
0, glformat, gltype, id->getData());
glTexImage2D(GL_TEXTURE_2D, i, fmt.internalformat, id->getWidth(), id->getHeight(),
0, fmt.externalformat, fmt.type, id->getData());
}
if (data.size() <= 1)
@@ -286,13 +288,13 @@ bool Image::loadVolatile()
OpenGL::TempDebugGroup debuggroup("Image load");
if (isCompressed() && !hasCompressedTextureSupport(cdata[0]->getFormat(), sRGB))
if (!OpenGL::isPixelFormatSupported(format, false, sRGB))
{
const char *str;
if (image::CompressedImageData::getConstant(cdata[0]->getFormat(), str))
if (love::getConstant(format, str))
{
throw love::Exception("Cannot create image: "
"%s%s compressed images are not supported on this system.", sRGB ? "sRGB " : "", str);
"%s%s images are not supported on this system.", sRGB ? "sRGB " : "", str);
}
else
throw love::Exception("cannot create image: format is not supported on this system.");
@@ -417,9 +419,8 @@ bool Image::refresh(int xoffset, int yoffset, int w, int h)
return true;
}
GLenum glformat = GL_RGBA;
GLenum gltype = GL_UNSIGNED_BYTE;
getFormat(data[0]->getFormat(), glformat, gltype, sRGB);
bool isSRGB = sRGB;
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false, isSRGB);
int mipcount = flags.mipmaps ? (int) data.size() : 1;
@@ -430,8 +431,8 @@ bool Image::refresh(int xoffset, int yoffset, int w, int h)
pdata += yoffset * data[i]->getWidth() + xoffset;
thread::Lock lock(data[i]->getMutex());
glTexSubImage2D(GL_TEXTURE_2D, i, xoffset, yoffset, w, h, glformat,
gltype, pdata);
glTexSubImage2D(GL_TEXTURE_2D, i, xoffset, yoffset, w, h,
fmt.externalformat, fmt.type, pdata);
xoffset /= 2;
yoffset /= 2;
@@ -501,7 +502,7 @@ void Image::setFilter(const Texture::Filter &f)
filter = f;
if (!data.empty() && !hasTextureFilteringSupport(data[0]->getFormat()))
if (!data.empty() && !OpenGL::hasTextureFilteringSupport(data[0]->getFormat()))
{
filter.mag = filter.min = FILTER_NEAREST;
@@ -599,245 +600,9 @@ bool Image::isCompressed() const
return compressed;
}
GLenum Image::getFormat(image::ImageData::Format format, GLenum &glformat, GLenum &gltype, bool &isSRGB) const
bool Image::isFormatSupported(PixelFormat pixelformat)
{
using image::ImageData;
GLenum internalformat = GL_RGBA8;
glformat = GL_RGBA;
gltype = GL_UNSIGNED_BYTE;
switch (format)
{
case ImageData::FORMAT_RGBA8:
if (isSRGB)
{
internalformat = GL_SRGB8_ALPHA8;
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
glformat = GL_SRGB_ALPHA;
}
break;
case ImageData::FORMAT_RGBA16:
internalformat = GL_RGBA16;
gltype = GL_UNSIGNED_SHORT;
isSRGB = false;
break;
case ImageData::FORMAT_RGBA16F:
internalformat = GL_RGBA16F;
// HALF_FLOAT_OES has a different value than HALF_FLOAT... of course
if (GLAD_OES_texture_half_float && !GLAD_ES_VERSION_3_0)
gltype = GL_HALF_FLOAT_OES;
else
gltype = GL_HALF_FLOAT;
isSRGB = false;
break;
case ImageData::FORMAT_RGBA32F:
internalformat = GL_RGBA32F;
gltype = GL_FLOAT;
isSRGB = false;
break;
default:
break;
}
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
internalformat = glformat;
return internalformat;
}
GLenum Image::getCompressedFormat(image::CompressedImageData::Format cformat, bool &isSRGB) const
{
using image::CompressedImageData;
switch (cformat)
{
case CompressedImageData::FORMAT_DXT1:
return isSRGB ? GL_COMPRESSED_SRGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
case CompressedImageData::FORMAT_DXT3:
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
case CompressedImageData::FORMAT_DXT5:
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
case CompressedImageData::FORMAT_BC4:
isSRGB = false;
return GL_COMPRESSED_RED_RGTC1;
case CompressedImageData::FORMAT_BC4s:
isSRGB = false;
return GL_COMPRESSED_SIGNED_RED_RGTC1;
case CompressedImageData::FORMAT_BC5:
isSRGB = false;
return GL_COMPRESSED_RG_RGTC2;
case CompressedImageData::FORMAT_BC5s:
isSRGB = false;
return GL_COMPRESSED_SIGNED_RG_RGTC2;
case CompressedImageData::FORMAT_BC6H:
isSRGB = false;
return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
case CompressedImageData::FORMAT_BC6Hs:
isSRGB = false;
return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
case CompressedImageData::FORMAT_BC7:
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM : GL_COMPRESSED_RGBA_BPTC_UNORM;
case CompressedImageData::FORMAT_PVR1_RGB2:
return isSRGB ? GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT : GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
case CompressedImageData::FORMAT_PVR1_RGB4:
return isSRGB ? GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT : GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
case CompressedImageData::FORMAT_PVR1_RGBA2:
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT : GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
case CompressedImageData::FORMAT_PVR1_RGBA4:
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT : GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
case CompressedImageData::FORMAT_ETC1:
// The ETC2 format can load ETC1 textures.
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility)
return isSRGB ? GL_COMPRESSED_SRGB8_ETC2 : GL_COMPRESSED_RGB8_ETC2;
else
{
isSRGB = false;
return GL_ETC1_RGB8_OES;
}
case CompressedImageData::FORMAT_ETC2_RGB:
return isSRGB ? GL_COMPRESSED_SRGB8_ETC2 : GL_COMPRESSED_RGB8_ETC2;
case CompressedImageData::FORMAT_ETC2_RGBA:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : GL_COMPRESSED_RGBA8_ETC2_EAC;
case CompressedImageData::FORMAT_ETC2_RGBA1:
return isSRGB ? GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
case CompressedImageData::FORMAT_EAC_R:
isSRGB = false;
return GL_COMPRESSED_R11_EAC;
case CompressedImageData::FORMAT_EAC_Rs:
isSRGB = false;
return GL_COMPRESSED_SIGNED_R11_EAC;
case CompressedImageData::FORMAT_EAC_RG:
isSRGB = false;
return GL_COMPRESSED_RG11_EAC;
case CompressedImageData::FORMAT_EAC_RGs:
isSRGB = false;
return GL_COMPRESSED_SIGNED_RG11_EAC;
case CompressedImageData::FORMAT_ASTC_4x4:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
case CompressedImageData::FORMAT_ASTC_5x4:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
case CompressedImageData::FORMAT_ASTC_5x5:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
case CompressedImageData::FORMAT_ASTC_6x5:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
case CompressedImageData::FORMAT_ASTC_6x6:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
case CompressedImageData::FORMAT_ASTC_8x5:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
case CompressedImageData::FORMAT_ASTC_8x6:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
case CompressedImageData::FORMAT_ASTC_8x8:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
case CompressedImageData::FORMAT_ASTC_10x5:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
case CompressedImageData::FORMAT_ASTC_10x6:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
case CompressedImageData::FORMAT_ASTC_10x8:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
case CompressedImageData::FORMAT_ASTC_10x10:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
case CompressedImageData::FORMAT_ASTC_12x10:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
case CompressedImageData::FORMAT_ASTC_12x12:
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
default:
return isSRGB ? GL_SRGB8_ALPHA8 : GL_RGBA8;
}
}
bool Image::hasAnisotropicFilteringSupport()
{
return GLAD_EXT_texture_filter_anisotropic != GL_FALSE;
}
bool Image::hasTextureSupport(image::ImageData::Format format)
{
using image::ImageData;
switch (format)
{
case ImageData::FORMAT_RGBA8:
return true;
case ImageData::FORMAT_RGBA16:
return GLAD_VERSION_1_1 || GLAD_EXT_texture_norm16;
case ImageData::FORMAT_RGBA16F:
return GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel) || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float;
case ImageData::FORMAT_RGBA32F:
return GLAD_VERSION_3_0 || GLAD_ARB_texture_float || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_float;
default:
return false;
}
}
bool Image::hasTextureFilteringSupport(image::ImageData::Format format)
{
switch (format)
{
case image::ImageData::FORMAT_RGBA16F:
return GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear;
case image::ImageData::FORMAT_RGBA32F:
return GLAD_VERSION_1_1;
default:
return true;
}
}
bool Image::hasCompressedTextureSupport(image::CompressedImageData::Format format, bool sRGB)
{
using image::CompressedImageData;
switch (format)
{
case CompressedImageData::FORMAT_DXT1:
return GLAD_EXT_texture_compression_s3tc || GLAD_EXT_texture_compression_dxt1;
case CompressedImageData::FORMAT_DXT3:
return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt3;
case CompressedImageData::FORMAT_DXT5:
return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt5;
case CompressedImageData::FORMAT_BC4:
case CompressedImageData::FORMAT_BC4s:
case CompressedImageData::FORMAT_BC5:
case CompressedImageData::FORMAT_BC5s:
return (GLAD_VERSION_3_0 || GLAD_ARB_texture_compression_rgtc || GLAD_EXT_texture_compression_rgtc);
case CompressedImageData::FORMAT_BC6H:
case CompressedImageData::FORMAT_BC6Hs:
case CompressedImageData::FORMAT_BC7:
return GLAD_VERSION_4_2 || GLAD_ARB_texture_compression_bptc;
case CompressedImageData::FORMAT_PVR1_RGB2:
case CompressedImageData::FORMAT_PVR1_RGB4:
case CompressedImageData::FORMAT_PVR1_RGBA2:
case CompressedImageData::FORMAT_PVR1_RGBA4:
return sRGB ? GLAD_EXT_pvrtc_sRGB : GLAD_IMG_texture_compression_pvrtc;
case CompressedImageData::FORMAT_ETC1:
// ETC2 support guarantees ETC1 support as well.
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility || GLAD_OES_compressed_ETC1_RGB8_texture;
case CompressedImageData::FORMAT_ETC2_RGB:
case CompressedImageData::FORMAT_ETC2_RGBA:
case CompressedImageData::FORMAT_ETC2_RGBA1:
case CompressedImageData::FORMAT_EAC_R:
case CompressedImageData::FORMAT_EAC_Rs:
case CompressedImageData::FORMAT_EAC_RG:
case CompressedImageData::FORMAT_EAC_RGs:
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility;
case CompressedImageData::FORMAT_ASTC_4x4:
case CompressedImageData::FORMAT_ASTC_5x4:
case CompressedImageData::FORMAT_ASTC_5x5:
case CompressedImageData::FORMAT_ASTC_6x5:
case CompressedImageData::FORMAT_ASTC_6x6:
case CompressedImageData::FORMAT_ASTC_8x5:
case CompressedImageData::FORMAT_ASTC_8x6:
case CompressedImageData::FORMAT_ASTC_8x8:
case CompressedImageData::FORMAT_ASTC_10x5:
case CompressedImageData::FORMAT_ASTC_10x6:
case CompressedImageData::FORMAT_ASTC_10x8:
case CompressedImageData::FORMAT_ASTC_10x10:
case CompressedImageData::FORMAT_ASTC_12x10:
case CompressedImageData::FORMAT_ASTC_12x12:
return GLAD_ES_VERSION_3_2 || GLAD_KHR_texture_compression_astc_ldr;
default:
return false;
}
return OpenGL::isPixelFormatSupported(pixelformat, false, false);
}
bool Image::hasSRGBSupport()