diff --git a/CMakeLists.txt b/CMakeLists.txt index b1d3a3f39..2f1ae98b9 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,6 +274,8 @@ set(LOVE_SRC_COMMON src/common/Module.h src/common/Object.cpp src/common/Object.h + src/common/pixelformat.cpp + src/common/pixelformat.h src/common/Reference.cpp src/common/Reference.h src/common/runtime.cpp diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index 914319054..a7584ad7f 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -954,6 +954,9 @@ FA91591F1CF1ED7500A7053F /* halffloat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA91591C1CF1ED7500A7053F /* halffloat.cpp */; }; FA9159201CF1ED7500A7053F /* halffloat.h in Headers */ = {isa = PBXBuildFile; fileRef = FA91591D1CF1ED7500A7053F /* halffloat.h */; }; FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; }; + FA9D8DD11DEB56C3002CD881 /* pixelformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */; }; + FA9D8DD21DEB56C3002CD881 /* pixelformat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */; }; + FA9D8DD31DEB56C3002CD881 /* pixelformat.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9D8DD01DEB56C3002CD881 /* pixelformat.h */; }; FAA3A9AE1B7D465A00CED060 /* android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA3A9AC1B7D465A00CED060 /* android.cpp */; }; FAA3A9AF1B7D465A00CED060 /* android.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAA3A9AC1B7D465A00CED060 /* android.cpp */; }; FAA3A9B01B7D465A00CED060 /* android.h in Headers */ = {isa = PBXBuildFile; fileRef = FAA3A9AD1B7D465A00CED060 /* android.h */; }; @@ -1662,6 +1665,8 @@ FA91591C1CF1ED7500A7053F /* halffloat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = halffloat.cpp; sourceTree = ""; }; FA91591D1CF1ED7500A7053F /* halffloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halffloat.h; sourceTree = ""; }; FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = ""; }; + FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pixelformat.cpp; sourceTree = ""; }; + FA9D8DD01DEB56C3002CD881 /* pixelformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pixelformat.h; sourceTree = ""; }; FAA3A9AC1B7D465A00CED060 /* android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = android.cpp; sourceTree = ""; }; FAA3A9AD1B7D465A00CED060 /* android.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = android.h; sourceTree = ""; }; FAA627CD18E7E1560080752D /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; @@ -1799,6 +1804,8 @@ FA0B79071A958E3B000E1D17 /* Module.h */, FA0B79081A958E3B000E1D17 /* Object.cpp */, FA0B79091A958E3B000E1D17 /* Object.h */, + FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */, + FA9D8DD01DEB56C3002CD881 /* pixelformat.h */, FA0B790C1A958E3B000E1D17 /* Reference.cpp */, FA0B790D1A958E3B000E1D17 /* Reference.h */, FA0B790E1A958E3B000E1D17 /* runtime.cpp */, @@ -3402,6 +3409,7 @@ 217DFBE01D9F6D490055D849 /* except.h in Headers */, FA0B79311A958E3B000E1D17 /* Module.h in Headers */, 217DFBF51D9F6D490055D849 /* mime.lua.h in Headers */, + FA9D8DD31DEB56C3002CD881 /* pixelformat.h in Headers */, FA0B7D5A1A95902C000E1D17 /* wrap_Canvas.h in Headers */, FA0B7E4A1A95902C000E1D17 /* wrap_DistanceJoint.h in Headers */, FA0B7D2E1A95902C000E1D17 /* Color.h in Headers */, @@ -3750,6 +3758,7 @@ FA0B7CF51A95902C000E1D17 /* File.cpp in Sources */, FA0B7E341A95902C000E1D17 /* WeldJoint.cpp in Sources */, FA4F2C091DE936E200CA37D7 /* luasocket.c in Sources */, + FA9D8DD21DEB56C3002CD881 /* pixelformat.cpp in Sources */, FA0B7D5C1A95902C000E1D17 /* wrap_Font.cpp in Sources */, FA0B7B221A958EA3000E1D17 /* luasocket.cpp in Sources */, FA0B7D311A95902C000E1D17 /* Graphics.cpp in Sources */, @@ -4058,6 +4067,7 @@ FA0B7EB21A95902C000E1D17 /* System.cpp in Sources */, FA0B7D1B1A95902C000E1D17 /* GlyphData.cpp in Sources */, FA0B7AD11A958EA3000E1D17 /* protocol.c in Sources */, + FA9D8DD11DEB56C3002CD881 /* pixelformat.cpp in Sources */, FA0B7E661A95902C000E1D17 /* wrap_PrismaticJoint.cpp in Sources */, FA0B7DCD1A95902C000E1D17 /* wrap_Keyboard.cpp in Sources */, FA0B7EE51A95902D000E1D17 /* Window.cpp in Sources */, diff --git a/src/common/pixelformat.cpp b/src/common/pixelformat.cpp new file mode 100644 index 000000000..2a939b533 --- /dev/null +++ b/src/common/pixelformat.cpp @@ -0,0 +1,146 @@ +/** + * Copyright (c) 2006-2016 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "pixelformat.h" +#include "StringMap.h" + +namespace love +{ + +static StringMap::Entry formatEntries[] = +{ + { "unknown", PIXELFORMAT_UNKNOWN }, + + { "normal", PIXELFORMAT_NORMAL }, + { "hdr", PIXELFORMAT_HDR }, + + { "r8", PIXELFORMAT_R8 }, + { "rg8", PIXELFORMAT_RG8 }, + { "rgba8", PIXELFORMAT_RGBA8 }, + { "srgba8", PIXELFORMAT_sRGBA8 }, + { "r16", PIXELFORMAT_R16 }, + { "rg16", PIXELFORMAT_RG16 }, + { "rgba16", PIXELFORMAT_RGBA16 }, + { "r16f", PIXELFORMAT_R16F }, + { "rg16f", PIXELFORMAT_RG16F }, + { "rgba16f", PIXELFORMAT_RGBA16F }, + { "r32f", PIXELFORMAT_R32F }, + { "rg32f", PIXELFORMAT_RG32F }, + { "rgba32f", PIXELFORMAT_RGBA32F }, + + { "rgba4", PIXELFORMAT_RGBA4 }, + { "rgb5a1", PIXELFORMAT_RGB5A1 }, + { "rgb565", PIXELFORMAT_RGB565 }, + { "rgb10a2", PIXELFORMAT_RGB10A2 }, + { "rg11b10f", PIXELFORMAT_RG11B10F }, + + { "DXT1", PIXELFORMAT_DXT1 }, + { "DXT3", PIXELFORMAT_DXT3 }, + { "DXT5", PIXELFORMAT_DXT5 }, + { "BC4", PIXELFORMAT_BC4 }, + { "BC4s", PIXELFORMAT_BC4s }, + { "BC5", PIXELFORMAT_BC5 }, + { "BC5s", PIXELFORMAT_BC5s }, + { "BC6h", PIXELFORMAT_BC6H }, + { "BC6hs", PIXELFORMAT_BC6Hs }, + { "BC7", PIXELFORMAT_BC7 }, + { "PVR1rgb2", PIXELFORMAT_PVR1_RGB2 }, + { "PVR1rgb4", PIXELFORMAT_PVR1_RGB4 }, + { "PVR1rgba2", PIXELFORMAT_PVR1_RGBA2 }, + { "PVR1rgba4", PIXELFORMAT_PVR1_RGBA4 }, + { "ETC1", PIXELFORMAT_ETC1 }, + { "ETC2rgb", PIXELFORMAT_ETC2_RGB }, + { "ETC2rgba", PIXELFORMAT_ETC2_RGBA }, + { "ETC2rgba1", PIXELFORMAT_ETC2_RGBA1 }, + { "EACr", PIXELFORMAT_EAC_R }, + { "EACrs", PIXELFORMAT_EAC_Rs }, + { "EACrg", PIXELFORMAT_EAC_RG }, + { "EACrgs", PIXELFORMAT_EAC_RGs }, + { "ASTC4x4", PIXELFORMAT_ASTC_4x4 }, + { "ASTC5x4", PIXELFORMAT_ASTC_5x4 }, + { "ASTC5x5", PIXELFORMAT_ASTC_5x5 }, + { "ASTC6x5", PIXELFORMAT_ASTC_6x5 }, + { "ASTC6x6", PIXELFORMAT_ASTC_6x6 }, + { "ASTC8x5", PIXELFORMAT_ASTC_8x5 }, + { "ASTC8x6", PIXELFORMAT_ASTC_8x6 }, + { "ASTC8x8", PIXELFORMAT_ASTC_8x8 }, + { "ASTC10x5", PIXELFORMAT_ASTC_10x5 }, + { "ASTC10x6", PIXELFORMAT_ASTC_10x6 }, + { "ASTC10x8", PIXELFORMAT_ASTC_10x8 }, + { "ASTC10x10", PIXELFORMAT_ASTC_10x10 }, + { "ASTC12x10", PIXELFORMAT_ASTC_12x10 }, + { "ASTC12x12", PIXELFORMAT_ASTC_12x12 }, +}; + +static_assert(sizeof(formatEntries) / sizeof(formatEntries[0]) == (size_t) PIXELFORMAT_MAX_ENUM, "pixel format string map is missing entries!"); + +static StringMap formats(formatEntries, sizeof(formatEntries)); + +bool getConstant(const char *in, PixelFormat &out) +{ + return formats.find(in, out); +} + +bool getConstant(PixelFormat in, const char *&out) +{ + return formats.find(in, out); +} + +bool isPixelFormatCompressed(PixelFormat format) +{ + // I'm lazy + int iformat = (int) format; + return iformat >= (int) PIXELFORMAT_DXT1 && iformat < (int) PIXELFORMAT_MAX_ENUM; +} + +size_t getPixelFormatSize(PixelFormat format) +{ + switch (format) + { + case PIXELFORMAT_R8: + return 1; + case PIXELFORMAT_RG8: + case PIXELFORMAT_R16: + case PIXELFORMAT_R16F: + case PIXELFORMAT_RGBA4: + case PIXELFORMAT_RGB5A1: + case PIXELFORMAT_RGB565: + return 2; + case PIXELFORMAT_RGBA8: + case PIXELFORMAT_sRGBA8: + case PIXELFORMAT_RG16: + case PIXELFORMAT_RG16F: + case PIXELFORMAT_R32F: + case PIXELFORMAT_RGB10A2: + case PIXELFORMAT_RG11B10F: + return 4; + case PIXELFORMAT_RGBA16: + case PIXELFORMAT_RGBA16F: + case PIXELFORMAT_RG32F: + return 8; + case PIXELFORMAT_RGBA32F: + return 16; + default: + // TODO: compressed formats + return 0; + } +} + +} // love diff --git a/src/common/pixelformat.h b/src/common/pixelformat.h new file mode 100644 index 000000000..1faf1ec7b --- /dev/null +++ b/src/common/pixelformat.h @@ -0,0 +1,113 @@ +/** + * Copyright (c) 2006-2016 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#pragma once + +#include "stddef.h" + +namespace love +{ + +enum PixelFormat +{ + PIXELFORMAT_UNKNOWN, + + // these are converted to an actual format by love + PIXELFORMAT_NORMAL, + PIXELFORMAT_HDR, + + // "regular" formats + PIXELFORMAT_R8, + PIXELFORMAT_RG8, + PIXELFORMAT_RGBA8, + PIXELFORMAT_sRGBA8, + PIXELFORMAT_R16, + PIXELFORMAT_RG16, + PIXELFORMAT_RGBA16, + PIXELFORMAT_R16F, + PIXELFORMAT_RG16F, + PIXELFORMAT_RGBA16F, + PIXELFORMAT_R32F, + PIXELFORMAT_RG32F, + PIXELFORMAT_RGBA32F, + + // packed formats + PIXELFORMAT_RGBA4, + PIXELFORMAT_RGB5A1, + PIXELFORMAT_RGB565, + PIXELFORMAT_RGB10A2, + PIXELFORMAT_RG11B10F, + + // compressed formats + PIXELFORMAT_DXT1, + PIXELFORMAT_DXT3, + PIXELFORMAT_DXT5, + PIXELFORMAT_BC4, + PIXELFORMAT_BC4s, + PIXELFORMAT_BC5, + PIXELFORMAT_BC5s, + PIXELFORMAT_BC6H, + PIXELFORMAT_BC6Hs, + PIXELFORMAT_BC7, + PIXELFORMAT_PVR1_RGB2, + PIXELFORMAT_PVR1_RGB4, + PIXELFORMAT_PVR1_RGBA2, + PIXELFORMAT_PVR1_RGBA4, + PIXELFORMAT_ETC1, + PIXELFORMAT_ETC2_RGB, + PIXELFORMAT_ETC2_RGBA, + PIXELFORMAT_ETC2_RGBA1, + PIXELFORMAT_EAC_R, + PIXELFORMAT_EAC_Rs, + PIXELFORMAT_EAC_RG, + PIXELFORMAT_EAC_RGs, + PIXELFORMAT_ASTC_4x4, + PIXELFORMAT_ASTC_5x4, + PIXELFORMAT_ASTC_5x5, + PIXELFORMAT_ASTC_6x5, + PIXELFORMAT_ASTC_6x6, + PIXELFORMAT_ASTC_8x5, + PIXELFORMAT_ASTC_8x6, + PIXELFORMAT_ASTC_8x8, + PIXELFORMAT_ASTC_10x5, + PIXELFORMAT_ASTC_10x6, + PIXELFORMAT_ASTC_10x8, + PIXELFORMAT_ASTC_10x10, + PIXELFORMAT_ASTC_12x10, + PIXELFORMAT_ASTC_12x12, + + PIXELFORMAT_MAX_ENUM +}; + +bool getConstant(PixelFormat in, const char *&out); +bool getConstant(const char *in, PixelFormat &out); + +/** + * Gets whether the specified pixel format is a compressed type. + **/ +bool isPixelFormatCompressed(PixelFormat format); + +/** + * Gets the size in bytes of the specified pixel format. + * NOTE: Currently returns 0 for compressed formats. + **/ +size_t getPixelFormatSize(PixelFormat format); + +} // love diff --git a/src/modules/font/BMFontRasterizer.cpp b/src/modules/font/BMFontRasterizer.cpp index b737473d6..bb9a22b90 100644 --- a/src/modules/font/BMFontRasterizer.cpp +++ b/src/modules/font/BMFontRasterizer.cpp @@ -204,7 +204,7 @@ void BMFontRasterizer::parseConfig(const std::string &configtext) ImageData *imagedata = imagemodule->newImageData(data.get()); - if (imagedata->getFormat() != ImageData::FORMAT_RGBA8) + if (imagedata->getFormat() != PIXELFORMAT_RGBA8) { imagedata->release(); throw love::Exception("Only 32-bit RGBA images are supported in BMFonts."); diff --git a/src/modules/font/ImageRasterizer.cpp b/src/modules/font/ImageRasterizer.cpp index 8cdb75d2f..a1da11da4 100644 --- a/src/modules/font/ImageRasterizer.cpp +++ b/src/modules/font/ImageRasterizer.cpp @@ -40,7 +40,7 @@ ImageRasterizer::ImageRasterizer(love::image::ImageData *data, uint32 *glyphs, i , numglyphs(numglyphs) , extraSpacing(extraspacing) { - if (data->getFormat() != image::ImageData::FORMAT_RGBA8) + if (data->getFormat() != PIXELFORMAT_RGBA8) throw love::Exception("Only 32-bit RGBA images are supported in Image Fonts!"); load(); diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 0da22e6bb..ad8908392 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -28,7 +28,8 @@ namespace graphics Texture::Filter Texture::defaultFilter; Texture::Texture() - : width(0) + : format(PIXELFORMAT_UNKNOWN) + , width(0) , height(0) , filter(getDefaultFilter()) , wrap() @@ -40,6 +41,11 @@ Texture::~Texture() { } +PixelFormat Texture::getPixelFormat() const +{ + return format; +} + int Texture::getWidth() const { return width; diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 70fc932a2..a558c8335 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -24,6 +24,7 @@ // LOVE #include "common/StringMap.h" #include "common/math.h" +#include "common/pixelformat.h" #include "Drawable.h" #include "Quad.h" @@ -79,6 +80,8 @@ public: **/ virtual void drawq(Quad *quad, const Matrix4 &m) = 0; + PixelFormat getPixelFormat() const; + virtual int getWidth() const; virtual int getHeight() const; @@ -106,6 +109,8 @@ public: protected: + PixelFormat format; + int width; int height; diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index f5cc027ca..75dc08861 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -56,8 +56,11 @@ static GLenum createFBO(GLuint &framebuffer, GLuint texture) return status; } -static bool createMSAABuffer(int width, int height, int &samples, GLenum iformat, GLuint &buffer) +static bool createMSAABuffer(int width, int height, int &samples, PixelFormat pixelformat, GLuint &buffer) { + bool unusedSRGB = false; + OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(pixelformat, true, unusedSRGB); + GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL); // Temporary FBO used to clear the renderbuffer. @@ -68,7 +71,7 @@ static bool createMSAABuffer(int width, int height, int &samples, GLenum iformat glGenRenderbuffers(1, &buffer); glBindRenderbuffer(GL_RENDERBUFFER, buffer); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, iformat, width, height); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, fmt.internalformat, width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, buffer); glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); @@ -98,11 +101,11 @@ static bool createMSAABuffer(int width, int height, int &samples, GLenum iformat int Canvas::canvasCount = 0; -Canvas::Canvas(int width, int height, Format format, int msaa) +Canvas::Canvas(int width, int height, PixelFormat format, int msaa) : fbo(0) , texture(0) , msaa_buffer(0) - , format(format) + , requested_format(format) , requested_samples(msaa) , actual_samples(0) , texture_memory(0) @@ -138,6 +141,8 @@ Canvas::Canvas(int width, int height, Format format, int msaa) vertices[3].s = 1; vertices[3].t = 1; + this->format = getSizedFormat(requested_format); + loadVolatile(); ++canvasCount; @@ -181,22 +186,14 @@ bool Canvas::loadVolatile() setFilter(filter); setWrap(wrap); - GLenum internalformat = GL_RGBA; - GLenum externalformat = GL_RGBA; - GLenum textype = GL_UNSIGNED_BYTE; - - convertFormat(format, internalformat, externalformat, textype); - - // in GLES2, the internalformat and format params of TexImage have to match. - GLint iformat = (GLint) internalformat; - if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0) - iformat = (GLint) externalformat; + bool unusedSRGB = false; + OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false, unusedSRGB); while (glGetError() != GL_NO_ERROR) /* Clear the error buffer. */; - glTexImage2D(GL_TEXTURE_2D, 0, iformat, width, height, 0, externalformat, - textype, nullptr); + glTexImage2D(GL_TEXTURE_2D, 0, fmt.internalformat, width, height, 0, + fmt.externalformat, fmt.type, nullptr); if (glGetError() != GL_NO_ERROR) { @@ -221,12 +218,12 @@ bool Canvas::loadVolatile() actual_samples = requested_samples == 1 ? 0 : requested_samples; - if (actual_samples > 0 && !createMSAABuffer(width, height, actual_samples, internalformat, msaa_buffer)) + if (actual_samples > 0 && !createMSAABuffer(width, height, actual_samples, format, msaa_buffer)) actual_samples = 0; size_t prevmemsize = texture_memory; - texture_memory = ((getFormatBitsPerPixel(format) * width) / 8) * height; + texture_memory = getPixelFormatSize(format) * width * height; if (msaa_buffer != 0) texture_memory += (texture_memory * actual_samples); @@ -338,149 +335,25 @@ const void *Canvas::getHandle() const return &texture; } -Canvas::Format Canvas::getSizedFormat(Canvas::Format format) +PixelFormat Canvas::getSizedFormat(PixelFormat format) { switch (format) { - case FORMAT_NORMAL: + case PIXELFORMAT_NORMAL: if (isGammaCorrect()) - return FORMAT_SRGB; - else if (GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_rgb8_rgba8 || GLAD_ARM_rgba8)) + return PIXELFORMAT_sRGBA8; + else if (!OpenGL::isPixelFormatSupported(PIXELFORMAT_RGBA8, true, false)) // 32-bit render targets don't have guaranteed support on GLES2. - return FORMAT_RGBA4; + return PIXELFORMAT_RGBA4; else - return FORMAT_RGBA8; - case FORMAT_HDR: - return FORMAT_RGBA16F; + return PIXELFORMAT_RGBA8; + case PIXELFORMAT_HDR: + return PIXELFORMAT_RGBA16F; default: return format; } } -void Canvas::convertFormat(Canvas::Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type) -{ - format = getSizedFormat(format); - externalformat = GL_RGBA; - - switch (format) - { - case FORMAT_RGBA4: - internalformat = GL_RGBA4; - type = GL_UNSIGNED_SHORT_4_4_4_4; - break; - case FORMAT_RGB5A1: - internalformat = GL_RGB5_A1; - type = GL_UNSIGNED_SHORT_5_5_5_1; - break; - case FORMAT_RGB565: - internalformat = GL_RGB565; - externalformat = GL_RGB; - type = GL_UNSIGNED_SHORT_5_6_5; - break; - case FORMAT_R8: - internalformat = GL_R8; - externalformat = GL_RED; - type = GL_UNSIGNED_BYTE; - break; - case FORMAT_RG8: - internalformat = GL_RG8; - externalformat = GL_RG; - type = GL_UNSIGNED_BYTE; - break; - case FORMAT_RGBA8: - default: - internalformat = GL_RGBA8; - type = GL_UNSIGNED_BYTE; - break; - case FORMAT_RGB10A2: - internalformat = GL_RGB10_A2; - type = GL_UNSIGNED_INT_2_10_10_10_REV; - break; - case FORMAT_RG11B10F: - internalformat = GL_R11F_G11F_B10F; - externalformat = GL_RGB; - type = GL_UNSIGNED_INT_10F_11F_11F_REV; - break; - case FORMAT_R16F: - internalformat = GL_R16F; - externalformat = GL_RED; - if (GLAD_OES_texture_half_float) - type = GL_HALF_FLOAT_OES; - else if (GLAD_VERSION_1_0) - type = GL_FLOAT; - else - type = GL_HALF_FLOAT; - break; - case FORMAT_RG16F: - internalformat = GL_RG16F; - externalformat = GL_RG; - if (GLAD_OES_texture_half_float) - type = GL_HALF_FLOAT_OES; - else if (GLAD_VERSION_1_0) - type = GL_FLOAT; - else - type = GL_HALF_FLOAT; - break; - case FORMAT_RGBA16F: - internalformat = GL_RGBA16F; - if (GLAD_OES_texture_half_float) - type = GL_HALF_FLOAT_OES; - else if (GLAD_VERSION_1_0) - type = GL_FLOAT; - else - type = GL_HALF_FLOAT; - break; - case FORMAT_R32F: - internalformat = GL_R32F; - externalformat = GL_RED; - type = GL_FLOAT; - break; - case FORMAT_RG32F: - internalformat = GL_RG32F; - externalformat = GL_RG; - type = GL_FLOAT; - break; - case FORMAT_RGBA32F: - internalformat = GL_RGBA32F; - type = GL_FLOAT; - break; - case FORMAT_SRGB: - internalformat = GL_SRGB8_ALPHA8; - type = GL_UNSIGNED_BYTE; - if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0) - externalformat = GL_SRGB_ALPHA; - break; - } -} - -size_t Canvas::getFormatBitsPerPixel(Format format) -{ - switch (getSizedFormat(format)) - { - case FORMAT_R8: - return 8; - case FORMAT_RGBA4: - case FORMAT_RGB5A1: - case FORMAT_RGB565: - case FORMAT_RG8: - case FORMAT_R16F: - return 16; - case FORMAT_RGBA8: - case FORMAT_RGB10A2: - case FORMAT_RG11B10F: - case FORMAT_RG16F: - case FORMAT_R32F: - case FORMAT_SRGB: - default: - return 32; - case FORMAT_RGBA16F: - case FORMAT_RG32F: - return 64; - case FORMAT_RGBA32F: - return 128; - } -} - bool Canvas::isSupported() { return GLAD_ES_VERSION_2_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object || GLAD_EXT_framebuffer_object; @@ -494,7 +367,7 @@ bool Canvas::isMultiFormatMultiCanvasSupported() bool Canvas::supportedFormats[] = {false}; bool Canvas::checkedFormats[] = {false}; -bool Canvas::isFormatSupported(Canvas::Format format) +bool Canvas::isFormatSupported(PixelFormat format) { if (!isSupported()) return false; @@ -502,66 +375,7 @@ bool Canvas::isFormatSupported(Canvas::Format format) bool supported = true; format = getSizedFormat(format); - switch (format) - { - case FORMAT_RGBA4: - case FORMAT_RGB5A1: - supported = true; - break; - case FORMAT_RGB565: - supported = GLAD_ES_VERSION_2_0 || GLAD_VERSION_4_2 || GLAD_ARB_ES2_compatibility; - break; - case FORMAT_R8: - case FORMAT_RG8: - if (GLAD_VERSION_1_0) - supported = GLAD_VERSION_3_0 || GLAD_ARB_texture_rg; - else if (GLAD_ES_VERSION_2_0) - supported = GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg; - break; - case FORMAT_RGBA8: - supported = GLAD_VERSION_1_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_rgb8_rgba8 || GLAD_ARM_rgba8; - break; - case FORMAT_RGB10A2: - supported = GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0; - break; - case FORMAT_RG11B10F: - supported = GLAD_VERSION_3_0 || GLAD_EXT_packed_float || GLAD_APPLE_color_buffer_packed_float; - break; - case FORMAT_R16F: - case FORMAT_RG16F: - if (GLAD_VERSION_1_0) - supported = GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_texture_rg); - else - supported = GLAD_EXT_color_buffer_half_float && (GLAD_ES_VERSION_3_0 || (GLAD_OES_texture_half_float && GLAD_EXT_texture_rg)); - break; - case FORMAT_RGBA16F: - if (GLAD_VERSION_1_0) - supported = GLAD_VERSION_3_0 || GLAD_ARB_texture_float; - else if (GLAD_ES_VERSION_2_0) - supported = GLAD_EXT_color_buffer_half_float && (GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float); - break; - case FORMAT_R32F: - case FORMAT_RG32F: - supported = GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_texture_rg); - break; - case FORMAT_RGBA32F: - supported = GLAD_VERSION_3_0 || GLAD_ARB_texture_float; - break; - case FORMAT_SRGB: - if (GLAD_VERSION_1_0) - { - supported = GLAD_VERSION_3_0 || ((GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB) - && (GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB)); - } - else - supported = GLAD_ES_VERSION_3_0 || GLAD_EXT_sRGB; - break; - default: - supported = false; - break; - } - - if (!supported) + if (!OpenGL::isPixelFormatSupported(format, true, false)) return false; if (checkedFormats[format]) @@ -572,15 +386,6 @@ bool Canvas::isFormatSupported(Canvas::Format format) // a texture to a FBO whose format the driver doesn't like. So we should // test with an actual FBO. - GLenum internalformat = GL_RGBA; - GLenum externalformat = GL_RGBA; - GLenum textype = GL_UNSIGNED_BYTE; - convertFormat(format, internalformat, externalformat, textype); - - // in GLES2, the internalformat and format params of TexImage have to match. - if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0) - internalformat = externalformat; - GLuint texture = 0; glGenTextures(1, &texture); gl.bindTextureToUnit(texture, 0, false); @@ -592,7 +397,10 @@ bool Canvas::isFormatSupported(Canvas::Format format) Texture::Wrap w; gl.setTextureWrap(w); - glTexImage2D(GL_TEXTURE_2D, 0, internalformat, 2, 2, 0, externalformat, textype, nullptr); + bool unusedSRGB = false; + OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false, unusedSRGB); + + glTexImage2D(GL_TEXTURE_2D, 0, fmt.internalformat, 2, 2, 0, fmt.externalformat, fmt.type, nullptr); GLuint fbo = 0; supported = (createFBO(fbo, texture) == GL_FRAMEBUFFER_COMPLETE); @@ -607,39 +415,6 @@ bool Canvas::isFormatSupported(Canvas::Format format) return supported; } -bool Canvas::getConstant(const char *in, Format &out) -{ - return formats.find(in, out); -} - -bool Canvas::getConstant(Format in, const char *&out) -{ - return formats.find(in, out); -} - -StringMap::Entry Canvas::formatEntries[] = -{ - {"normal", FORMAT_NORMAL}, - {"hdr", FORMAT_HDR}, - {"rgba4", FORMAT_RGBA4}, - {"rgb5a1", FORMAT_RGB5A1}, - {"rgb565", FORMAT_RGB565}, - {"r8", FORMAT_R8}, - {"rg8", FORMAT_RG8}, - {"rgba8", FORMAT_RGBA8}, - {"rgb10a2", FORMAT_RGB10A2}, - {"rg11b10f", FORMAT_RG11B10F}, - {"r16f", FORMAT_R16F}, - {"rg16f", FORMAT_RG16F}, - {"rgba16f", FORMAT_RGBA16F}, - {"r32f", FORMAT_R32F}, - {"rg32f", FORMAT_RG32F}, - {"rgba32f", FORMAT_RGBA32F}, - {"srgb", FORMAT_SRGB}, -}; - -StringMap Canvas::formats(Canvas::formatEntries, sizeof(Canvas::formatEntries)); - } // opengl } // graphics } // love diff --git a/src/modules/graphics/opengl/Canvas.h b/src/modules/graphics/opengl/Canvas.h index e67800c62..80ca636b0 100644 --- a/src/modules/graphics/opengl/Canvas.h +++ b/src/modules/graphics/opengl/Canvas.h @@ -43,30 +43,7 @@ class Canvas : public Texture, public Volatile { public: - // Different Canvas render target formats. - enum Format - { - FORMAT_NORMAL, // Usually SRGB, RGBA8 or a similar fallback. Always supported. - FORMAT_HDR, // Usually RGBA16F. Not always supported. - FORMAT_RGBA4, // RGBA with 4 bits per channel. - FORMAT_RGB5A1, // RGB with 5 bits per channel, and A with 1 bit. - FORMAT_RGB565, // RGB with 5, 6, and 5 bits each, respectively. - FORMAT_R8, // Single (red) 8-bit channel. - FORMAT_RG8, // Two-channel (red and green) with 8 bits per channel. - FORMAT_RGBA8, // RGBA with 8 bits per channel. - FORMAT_RGB10A2, // RGB with 10 bits each, and A with 2 bits. - FORMAT_RG11B10F, // Floating point [0, +65024]. RG with 11 FP bits each, and B with 10 FP bits. - FORMAT_R16F, // Floating point [-65504, +65504]. R with 16 FP bits. - FORMAT_RG16F, // Floating point [-65504, +65504]. RG with 16 FP bits per channel. - FORMAT_RGBA16F, // Floating point [-65504, +65504]. RGBA with 16 FP bits per channel. - FORMAT_R32F, // Floating point [-65504, +65504]. R with 32 FP bits. - FORMAT_RG32F, // Floating point [-65504, +65504]. RG with 32 FP bits per channel. - FORMAT_RGBA32F, // Floating point [-65504, +65504]. RGBA with 32 FP bits per channel. - FORMAT_SRGB, // sRGB with 8 bits per channel, plus 8 bit linear A. - FORMAT_MAX_ENUM - }; - - Canvas(int width, int height, Format format = FORMAT_NORMAL, int msaa = 0); + Canvas(int width, int height, PixelFormat format = PIXELFORMAT_NORMAL, int msaa = 0); virtual ~Canvas(); // Implements Volatile. @@ -87,11 +64,6 @@ public: return status; } - inline Format getTextureFormat() const - { - return format; - } - inline int getMSAA() const { return actual_samples; @@ -112,29 +84,23 @@ public: return fbo; } - static Format getSizedFormat(Format format); + static PixelFormat getSizedFormat(PixelFormat format); static bool isSupported(); static bool isMultiFormatMultiCanvasSupported(); - static bool isFormatSupported(Format format); + static bool isFormatSupported(PixelFormat format); static int canvasCount; - static bool getConstant(const char *in, Format &out); - static bool getConstant(Format in, const char *&out); - private: void drawv(const Matrix4 &t, const Vertex *v); - static void convertFormat(Format format, GLenum &internalformat, GLenum &externalformat, GLenum &type); - static size_t getFormatBitsPerPixel(Format format); - GLuint fbo; GLuint texture; GLuint msaa_buffer; - Format format; + PixelFormat requested_format; GLenum status; @@ -143,11 +109,8 @@ private: size_t texture_memory; - static bool supportedFormats[FORMAT_MAX_ENUM]; - static bool checkedFormats[FORMAT_MAX_ENUM]; - - static StringMap::Entry formatEntries[]; - static StringMap formats; + static bool supportedFormats[PIXELFORMAT_MAX_ENUM]; + static bool checkedFormats[PIXELFORMAT_MAX_ENUM]; }; // Canvas diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 1408e3373..f4c87a96e 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -492,9 +492,9 @@ void Graphics::beginPass(const PassInfo &info) Canvas *firstcanvas = info.colorAttachments[0].canvas; bool multiformatsupported = isSupported(Feature::FEATURE_MULTI_CANVAS_FORMATS); - Canvas::Format firstformat = firstcanvas->getTextureFormat(); + PixelFormat firstformat = firstcanvas->getPixelFormat(); - bool hasSRGBcanvas = Canvas::getSizedFormat(firstformat) == Canvas::FORMAT_SRGB; + bool hasSRGBcanvas = firstformat == PIXELFORMAT_sRGBA8; for (int i = 1; i < info.colorAttachmentCount; i++) { @@ -503,13 +503,13 @@ void Graphics::beginPass(const PassInfo &info) if (c->getWidth() != firstcanvas->getWidth() || c->getHeight() != firstcanvas->getHeight()) throw love::Exception("All canvases in a render pass must have the same dimensions."); - if (!multiformatsupported && c->getTextureFormat() != firstformat) + if (!multiformatsupported && c->getPixelFormat() != firstformat) throw love::Exception("This system doesn't support multi-canvas rendering with different canvas formats."); if (c->getRequestedMSAA() != firstcanvas->getRequestedMSAA()) throw love::Exception("All Canvases in a render pass must have the same requested MSAA value."); - if (Canvas::getSizedFormat(c->getTextureFormat()) == Canvas::FORMAT_SRGB) + if (c->getPixelFormat() == PIXELFORMAT_sRGBA8) hasSRGBcanvas = true; } @@ -639,25 +639,25 @@ void Graphics::endPass(int sX, int sY, int sW, int sH, const ScreenshotInfo *inf if (imagemodule == nullptr) throw love::Exception("The love.image module must be loaded to capture a Canvas' contents."); - image::ImageData::Format format; - switch (Canvas::getSizedFormat(attachments[0].canvas->getTextureFormat())) + PixelFormat format; + switch (attachments[0].canvas->getPixelFormat()) { - case Canvas::FORMAT_RGB10A2: // FIXME: Conversions aren't supported in GLES - format = image::ImageData::FORMAT_RGBA16; + case PIXELFORMAT_RGB10A2: // FIXME: Conversions aren't supported in GLES + format = PIXELFORMAT_RGBA16; break; - case Canvas::FORMAT_R16F: - case Canvas::FORMAT_RG16F: - case Canvas::FORMAT_RGBA16F: - case Canvas::FORMAT_RG11B10F: // FIXME: Conversions aren't supported in GLES - format = image::ImageData::FORMAT_RGBA16F; + case PIXELFORMAT_R16F: + case PIXELFORMAT_RG16F: + case PIXELFORMAT_RGBA16F: + case PIXELFORMAT_RG11B10F: // FIXME: Conversions aren't supported in GLES + format = PIXELFORMAT_RGBA16F; break; - case Canvas::FORMAT_R32F: - case Canvas::FORMAT_RG32F: - case Canvas::FORMAT_RGBA32F: - format = image::ImageData::FORMAT_RGBA32F; + case PIXELFORMAT_R32F: + case PIXELFORMAT_RG32F: + case PIXELFORMAT_RGBA32F: + format = PIXELFORMAT_RGBA32F; break; default: - format = image::ImageData::FORMAT_RGBA8; + format = PIXELFORMAT_RGBA8; break; } @@ -695,13 +695,13 @@ void Graphics::endPass(int sX, int sY, int sW, int sH, const ScreenshotInfo *inf GLenum datatype; switch (imagedata->getFormat()) { - case image::ImageData::FORMAT_RGBA16: + case PIXELFORMAT_RGBA16: datatype = GL_UNSIGNED_SHORT; break; - case image::ImageData::FORMAT_RGBA16F: + case PIXELFORMAT_RGBA16F: datatype = GL_HALF_FLOAT; break; - case image::ImageData::FORMAT_RGBA32F: + case PIXELFORMAT_RGBA32F: datatype = GL_FLOAT; break; default: @@ -831,7 +831,7 @@ void Graphics::bindCachedFBOForPass(const PassInfo &pass) if (drawbuffers.size() > 1) glDrawBuffers(1, &drawbuffers[0]); - GLuint stencil = attachCachedStencilBuffer(w, h, msaa); + GLuint stencil = attachCachedStencilBuffer(w, h, info.canvases[0]->getRequestedMSAA()); if (stencil == 0) { @@ -1011,7 +1011,7 @@ void Graphics::present(void *screenshotCallbackData) try { - img = imagemodule->newImageData(w, h, image::ImageData::FORMAT_RGBA8, screenshot); + img = imagemodule->newImageData(w, h, PIXELFORMAT_RGBA8, screenshot); } catch (love::Exception &) { @@ -1303,7 +1303,7 @@ ParticleSystem *Graphics::newParticleSystem(Texture *texture, int size) return new ParticleSystem(texture, size); } -Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int msaa) +Canvas *Graphics::newCanvas(int width, int height, PixelFormat format, int msaa) { if (!Canvas::isSupported()) throw love::Exception("Canvases are not supported by your OpenGL drivers!"); @@ -1311,7 +1311,7 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::Format format, int ms if (!Canvas::isFormatSupported(format)) { const char *fstr = "rgba8"; - Canvas::getConstant(Canvas::getSizedFormat(format), fstr); + love::getConstant(Canvas::getSizedFormat(format), fstr); throw love::Exception("The %s canvas format is not supported by your OpenGL drivers.", fstr); } diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 265b4db7d..2440f9f11 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -226,7 +226,7 @@ public: ParticleSystem *newParticleSystem(Texture *texture, int size); - Canvas *newCanvas(int width, int height, Canvas::Format format = Canvas::FORMAT_NORMAL, int msaa = 0); + Canvas *newCanvas(int width, int height, PixelFormat format = PIXELFORMAT_NORMAL, int msaa = 0); Shader *newShader(const Shader::ShaderSource &source); diff --git a/src/modules/graphics/opengl/Image.cpp b/src/modules/graphics/opengl/Image.cpp index 0d0e8c7d3..bb33641a1 100644 --- a/src/modules/graphics/opengl/Image.cpp +++ b/src/modules/graphics/opengl/Image.cpp @@ -113,6 +113,8 @@ Image::Image(const std::vector &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 &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() diff --git a/src/modules/graphics/opengl/Image.h b/src/modules/graphics/opengl/Image.h index 0df3df0cf..ce0aa63ec 100644 --- a/src/modules/graphics/opengl/Image.h +++ b/src/modules/graphics/opengl/Image.h @@ -127,10 +127,7 @@ public: static void setDefaultMipmapFilter(FilterMode f); static FilterMode getDefaultMipmapFilter(); - static bool hasAnisotropicFilteringSupport(); - static bool hasTextureSupport(image::ImageData::Format format); - static bool hasTextureFilteringSupport(image::ImageData::Format format); - static bool hasCompressedTextureSupport(image::CompressedImageData::Format format, bool sRGB); + static bool isFormatSupported(PixelFormat pixelformat); static bool hasSRGBSupport(); static bool getConstant(const char *in, FlagType &out); @@ -149,9 +146,6 @@ private: void loadFromCompressedData(); void loadFromImageData(); - GLenum getFormat(image::ImageData::Format format, GLenum &glformat, GLenum &gltype, bool &isSRGB) const; - GLenum getCompressedFormat(image::CompressedImageData::Format cformat, bool &isSRGB) const; - // The ImageData from which the texture is created. May be empty if // Compressed image data was used to create the texture. // Each element in the array is a mipmap level. diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index f5a44775c..80a8d429b 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -772,6 +772,413 @@ OpenGL::Vendor OpenGL::getVendor() const return vendor; } +OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool renderbuffer, bool &isSRGB) +{ + TextureFormat f; + + if (pixelformat == PIXELFORMAT_RGBA8 && isSRGB) + pixelformat = PIXELFORMAT_sRGBA8; + else if (pixelformat == PIXELFORMAT_ETC1) + { + // The ETC2 format can load ETC1 textures. + if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility) + pixelformat = PIXELFORMAT_ETC2_RGB; + } + + switch (pixelformat) + { + case PIXELFORMAT_R8: + f.internalformat = GL_R8; + f.externalformat = GL_RED; + f.type = GL_UNSIGNED_BYTE; + break; + case PIXELFORMAT_RG8: + f.internalformat = GL_RG8; + f.externalformat = GL_RG; + f.type = GL_UNSIGNED_BYTE; + break; + case PIXELFORMAT_RGBA8: + f.internalformat = GL_RGBA8; + f.externalformat = GL_RGBA; + f.type = GL_UNSIGNED_BYTE; + break; + case PIXELFORMAT_sRGBA8: + f.internalformat = GL_SRGB8_ALPHA8; + f.type = GL_UNSIGNED_BYTE; + if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0) + f.externalformat = GL_SRGB_ALPHA; + else + f.externalformat = GL_RGBA; + break; + case PIXELFORMAT_R16: + f.internalformat = GL_R16; + f.externalformat = GL_RED; + f.type = GL_UNSIGNED_SHORT; + break; + case PIXELFORMAT_RG16: + f.internalformat = GL_RG16; + f.externalformat = GL_RG; + f.type = GL_UNSIGNED_SHORT; + break; + case PIXELFORMAT_RGBA16: + f.internalformat = GL_RGBA16; + f.externalformat = GL_RGBA; + f.type = GL_UNSIGNED_SHORT; + break; + case PIXELFORMAT_R16F: + f.internalformat = GL_R16F; + f.externalformat = GL_RED; + if (GLAD_OES_texture_half_float) + f.type = GL_HALF_FLOAT_OES; + else + f.type = GL_HALF_FLOAT; + break; + case PIXELFORMAT_RG16F: + f.internalformat = GL_RG16F; + f.externalformat = GL_RG; + if (GLAD_OES_texture_half_float) + f.type = GL_HALF_FLOAT_OES; + else + f.type = GL_HALF_FLOAT; + break; + case PIXELFORMAT_RGBA16F: + f.internalformat = GL_RGBA16F; + f.externalformat = GL_RGBA; + if (GLAD_OES_texture_half_float) + f.type = GL_HALF_FLOAT_OES; + else + f.type = GL_HALF_FLOAT; + break; + case PIXELFORMAT_R32F: + f.internalformat = GL_R32F; + f.externalformat = GL_RED; + f.type = GL_FLOAT; + break; + case PIXELFORMAT_RG32F: + f.internalformat = GL_RG32F; + f.externalformat = GL_RG; + f.type = GL_FLOAT; + break; + case PIXELFORMAT_RGBA32F: + f.internalformat = GL_RGBA32F; + f.externalformat = GL_RGBA; + f.type = GL_FLOAT; + break; + + case PIXELFORMAT_RGBA4: + f.internalformat = GL_RGBA4; + f.externalformat = GL_RGBA; + f.type = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case PIXELFORMAT_RGB5A1: + f.internalformat = GL_RGB5_A1; + f.externalformat = GL_RGBA; + f.type = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case PIXELFORMAT_RGB565: + f.internalformat = GL_RGB565; + f.externalformat = GL_RGB; + f.type = GL_UNSIGNED_SHORT_5_6_5; + break; + case PIXELFORMAT_RGB10A2: + f.internalformat = GL_RGB10_A2; + f.externalformat = GL_RGBA; + f.type = GL_UNSIGNED_INT_2_10_10_10_REV; + break; + case PIXELFORMAT_RG11B10F: + f.internalformat = GL_R11F_G11F_B10F; + f.externalformat = GL_RGB; + f.type = GL_UNSIGNED_INT_10F_11F_11F_REV; + break; + + case PIXELFORMAT_DXT1: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + break; + case PIXELFORMAT_DXT3: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + case PIXELFORMAT_DXT5: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + case PIXELFORMAT_BC4: + isSRGB = false; + f.internalformat = GL_COMPRESSED_RED_RGTC1; + break; + case PIXELFORMAT_BC4s: + isSRGB = false; + f.internalformat = GL_COMPRESSED_SIGNED_RED_RGTC1; + break; + case PIXELFORMAT_BC5: + isSRGB = false; + f.internalformat = GL_COMPRESSED_RG_RGTC2; + break; + case PIXELFORMAT_BC5s: + isSRGB = false; + f.internalformat = GL_COMPRESSED_SIGNED_RG_RGTC2; + break; + case PIXELFORMAT_BC6H: + isSRGB = false; + f.internalformat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT; + break; + case PIXELFORMAT_BC6Hs: + isSRGB = false; + f.internalformat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT; + break; + case PIXELFORMAT_BC7: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM : GL_COMPRESSED_RGBA_BPTC_UNORM; + break; + case PIXELFORMAT_PVR1_RGB2: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT : GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG; + break; + case PIXELFORMAT_PVR1_RGB4: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT : GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + break; + case PIXELFORMAT_PVR1_RGBA2: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT : GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + break; + case PIXELFORMAT_PVR1_RGBA4: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT : GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + break; + case PIXELFORMAT_ETC1: + isSRGB = false; + f.internalformat = GL_ETC1_RGB8_OES; + break; + case PIXELFORMAT_ETC2_RGB: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ETC2 : GL_COMPRESSED_RGB8_ETC2; + break; + case PIXELFORMAT_ETC2_RGBA: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : GL_COMPRESSED_RGBA8_ETC2_EAC; + break; + case PIXELFORMAT_ETC2_RGBA1: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2; + break; + case PIXELFORMAT_EAC_R: + isSRGB = false; + f.internalformat = GL_COMPRESSED_R11_EAC; + break; + case PIXELFORMAT_EAC_Rs: + isSRGB = false; + f.internalformat = GL_COMPRESSED_SIGNED_R11_EAC; + break; + case PIXELFORMAT_EAC_RG: + isSRGB = false; + f.internalformat = GL_COMPRESSED_RG11_EAC; + break; + case PIXELFORMAT_EAC_RGs: + isSRGB = false; + f.internalformat = GL_COMPRESSED_SIGNED_RG11_EAC; + break; + case PIXELFORMAT_ASTC_4x4: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : GL_COMPRESSED_RGBA_ASTC_4x4_KHR; + break; + case PIXELFORMAT_ASTC_5x4: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : GL_COMPRESSED_RGBA_ASTC_5x4_KHR; + break; + case PIXELFORMAT_ASTC_5x5: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : GL_COMPRESSED_RGBA_ASTC_5x5_KHR; + break; + case PIXELFORMAT_ASTC_6x5: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : GL_COMPRESSED_RGBA_ASTC_6x5_KHR; + break; + case PIXELFORMAT_ASTC_6x6: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : GL_COMPRESSED_RGBA_ASTC_6x6_KHR; + break; + case PIXELFORMAT_ASTC_8x5: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : GL_COMPRESSED_RGBA_ASTC_8x5_KHR; + break; + case PIXELFORMAT_ASTC_8x6: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : GL_COMPRESSED_RGBA_ASTC_8x6_KHR; + break; + case PIXELFORMAT_ASTC_8x8: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : GL_COMPRESSED_RGBA_ASTC_8x8_KHR; + break; + case PIXELFORMAT_ASTC_10x5: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : GL_COMPRESSED_RGBA_ASTC_10x5_KHR; + break; + case PIXELFORMAT_ASTC_10x6: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : GL_COMPRESSED_RGBA_ASTC_10x6_KHR; + break; + case PIXELFORMAT_ASTC_10x8: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : GL_COMPRESSED_RGBA_ASTC_10x8_KHR; + break; + case PIXELFORMAT_ASTC_10x10: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : GL_COMPRESSED_RGBA_ASTC_10x10_KHR; + break; + case PIXELFORMAT_ASTC_12x10: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : GL_COMPRESSED_RGBA_ASTC_12x10_KHR; + break; + case PIXELFORMAT_ASTC_12x12: + f.internalformat = isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : GL_COMPRESSED_RGBA_ASTC_12x12_KHR; + break; + + default: + printf("Unhandled pixel format when converting to OpenGL enums!"); + break; + } + + if (!isPixelFormatCompressed(pixelformat)) + { + if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0 && !renderbuffer) + f.internalformat = f.externalformat; + + if (pixelformat != PIXELFORMAT_sRGBA8) + isSRGB = false; + } + + return f; +} + +bool OpenGL::isPixelFormatSupported(PixelFormat pixelformat, bool rendertarget, bool isSRGB) +{ + if (rendertarget && isPixelFormatCompressed(pixelformat)) + return false; + + if (pixelformat == PIXELFORMAT_RGBA8 && isSRGB) + pixelformat = PIXELFORMAT_sRGBA8; + + switch (pixelformat) + { + case PIXELFORMAT_R8: + case PIXELFORMAT_RG8: + return GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg; + case PIXELFORMAT_RGBA8: + if (rendertarget) + return GLAD_VERSION_1_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_rgb8_rgba8 || GLAD_ARM_rgba8; + else + return true; + case PIXELFORMAT_sRGBA8: + if (rendertarget) + { + if (GLAD_VERSION_1_0) + { + return GLAD_VERSION_3_0 || ((GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB) + && (GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB)); + } + else + return GLAD_ES_VERSION_3_0 || GLAD_EXT_sRGB; + } + else + return GLAD_ES_VERSION_3_0 || GLAD_EXT_sRGB || GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB; + case PIXELFORMAT_R16: + case PIXELFORMAT_RG16: + if (rendertarget) + return false; + else + return (GLAD_VERSION_1_1 && GLAD_EXT_texture_rg) || (GLAD_EXT_texture_norm16 && (GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg)); + case PIXELFORMAT_RGBA16: + if (rendertarget) + return false; + else + return GLAD_VERSION_1_1 || GLAD_EXT_texture_norm16; + case PIXELFORMAT_R16F: + case PIXELFORMAT_RG16F: + if (GLAD_VERSION_1_0) + return GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel && GLAD_ARB_texture_rg); + else if (rendertarget && !GLAD_EXT_color_buffer_half_float) + return false; + else + return GLAD_ES_VERSION_3_0 || (GLAD_OES_texture_half_float && GLAD_EXT_texture_rg); + case PIXELFORMAT_RGBA16F: + if (GLAD_VERSION_1_0) + return GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel); + else if (rendertarget && !GLAD_EXT_color_buffer_half_float) + return false; + else + return GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float; + case PIXELFORMAT_R32F: + case PIXELFORMAT_RG32F: + if (GLAD_VERSION_1_0) + return GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_texture_rg); + else if (!rendertarget) + return GLAD_ES_VERSION_3_0 || (GLAD_OES_texture_float && GLAD_EXT_texture_rg); + else + return false; + case PIXELFORMAT_RGBA32F: + if (GLAD_VERSION_1_0) + return GLAD_VERSION_3_0 || GLAD_ARB_texture_float; + else if (!rendertarget) + return GLAD_ES_VERSION_3_0 || GLAD_OES_texture_float; + else + return false; + + case PIXELFORMAT_RGBA4: + case PIXELFORMAT_RGB5A1: + return true; + case PIXELFORMAT_RGB565: + return GLAD_ES_VERSION_2_0 || GLAD_VERSION_4_2 || GLAD_ARB_ES2_compatibility; + case PIXELFORMAT_RGB10A2: + return GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0; + case PIXELFORMAT_RG11B10F: + if (rendertarget) + return GLAD_VERSION_3_0 || GLAD_EXT_packed_float || GLAD_APPLE_color_buffer_packed_float; + else + return GLAD_VERSION_3_0 || GLAD_EXT_packed_float || GLAD_APPLE_texture_packed_float; + + case PIXELFORMAT_DXT1: + return GLAD_EXT_texture_compression_s3tc || GLAD_EXT_texture_compression_dxt1; + case PIXELFORMAT_DXT3: + return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt3; + case PIXELFORMAT_DXT5: + return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt5; + case PIXELFORMAT_BC4: + case PIXELFORMAT_BC4s: + case PIXELFORMAT_BC5: + case PIXELFORMAT_BC5s: + return (GLAD_VERSION_3_0 || GLAD_ARB_texture_compression_rgtc || GLAD_EXT_texture_compression_rgtc); + case PIXELFORMAT_BC6H: + case PIXELFORMAT_BC6Hs: + case PIXELFORMAT_BC7: + return GLAD_VERSION_4_2 || GLAD_ARB_texture_compression_bptc; + case PIXELFORMAT_PVR1_RGB2: + case PIXELFORMAT_PVR1_RGB4: + case PIXELFORMAT_PVR1_RGBA2: + case PIXELFORMAT_PVR1_RGBA4: + return isSRGB ? GLAD_EXT_pvrtc_sRGB : GLAD_IMG_texture_compression_pvrtc; + case PIXELFORMAT_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 PIXELFORMAT_ETC2_RGB: + case PIXELFORMAT_ETC2_RGBA: + case PIXELFORMAT_ETC2_RGBA1: + case PIXELFORMAT_EAC_R: + case PIXELFORMAT_EAC_Rs: + case PIXELFORMAT_EAC_RG: + case PIXELFORMAT_EAC_RGs: + return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility; + case PIXELFORMAT_ASTC_4x4: + case PIXELFORMAT_ASTC_5x4: + case PIXELFORMAT_ASTC_5x5: + case PIXELFORMAT_ASTC_6x5: + case PIXELFORMAT_ASTC_6x6: + case PIXELFORMAT_ASTC_8x5: + case PIXELFORMAT_ASTC_8x6: + case PIXELFORMAT_ASTC_8x8: + case PIXELFORMAT_ASTC_10x5: + case PIXELFORMAT_ASTC_10x6: + case PIXELFORMAT_ASTC_10x8: + case PIXELFORMAT_ASTC_10x10: + case PIXELFORMAT_ASTC_12x10: + case PIXELFORMAT_ASTC_12x12: + return GLAD_ES_VERSION_3_2 || GLAD_KHR_texture_compression_astc_ldr; + + default: + return false; + } +} + +bool OpenGL::hasTextureFilteringSupport(PixelFormat pixelformat) +{ + switch (pixelformat) + { + case PIXELFORMAT_RGBA16F: + return GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear; + case PIXELFORMAT_RGBA32F: + return GLAD_VERSION_1_1; + default: + return true; + } +} + const char *OpenGL::errorString(GLenum errorcode) { switch (errorcode) diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 099ed07f9..e94ae096f 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -123,6 +123,13 @@ public: } }; + struct TextureFormat + { + GLenum internalformat = 0; + GLenum externalformat = 0; + GLenum type = 0; + }; + struct { std::vector transform; @@ -427,6 +434,10 @@ public: static GLenum getGLBufferType(BufferType type); static GLint getGLWrapMode(Texture::WrapMode wmode); + static TextureFormat convertPixelFormat(PixelFormat pixelformat, bool renderbuffer, bool &isSRGB); + static bool isPixelFormatSupported(PixelFormat pixelformat, bool rendertarget, bool isSRGB); + static bool hasTextureFilteringSupport(PixelFormat pixelformat); + static const char *errorString(GLenum errorcode); static const char *framebufferStatusString(GLenum status); diff --git a/src/modules/graphics/opengl/wrap_Canvas.cpp b/src/modules/graphics/opengl/wrap_Canvas.cpp index 50ad2d752..b5eaf3a1b 100644 --- a/src/modules/graphics/opengl/wrap_Canvas.cpp +++ b/src/modules/graphics/opengl/wrap_Canvas.cpp @@ -36,10 +36,10 @@ Canvas *luax_checkcanvas(lua_State *L, int idx) int w_Canvas_getFormat(lua_State *L) { Canvas *canvas = luax_checkcanvas(L, 1); - Canvas::Format format = canvas->getTextureFormat(); + PixelFormat format = canvas->getPixelFormat(); const char *str; - if (!Canvas::getConstant(format, str)) - return luaL_error(L, "Unknown Canvas format."); + if (!getConstant(format, str)) + return luaL_error(L, "Unknown pixel format."); lua_pushstring(L, str); return 1; diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index 8bcdd7c82..18ea96800 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -749,9 +749,9 @@ int w_newCanvas(lua_State *L) const char *str = luaL_optstring(L, 3, "normal"); int msaa = (int) luaL_optnumber(L, 4, 0); - Canvas::Format format; - if (!Canvas::getConstant(str, format)) - return luaL_error(L, "Invalid Canvas format: %s", str); + PixelFormat format; + if (!getConstant(str, format)) + return luaL_error(L, "Invalid pixel format: %s", str); Canvas *canvas = nullptr; luax_catchexcept(L, @@ -1524,64 +1524,38 @@ int w_getSupported(lua_State *L) return 1; } +static int w__getFormats(lua_State *L, bool (*isFormatSupported)(PixelFormat), bool (*ignore)(PixelFormat)) +{ + lua_createtable(L, 0, (int) PIXELFORMAT_MAX_ENUM); + + for (int i = 0; i < (int) PIXELFORMAT_MAX_ENUM; i++) + { + PixelFormat format = (PixelFormat) i; + const char *name = nullptr; + + if (format == PIXELFORMAT_UNKNOWN || !love::getConstant(format, name) || ignore(format)) + continue; + + luax_pushboolean(L, isFormatSupported(format)); + lua_setfield(L, -2, name); + } + + return 1; +} + int w_getCanvasFormats(lua_State *L) { - lua_createtable(L, 0, (int) Canvas::FORMAT_MAX_ENUM); - - for (int i = 0; i < (int) Canvas::FORMAT_MAX_ENUM; i++) - { - Canvas::Format format = (Canvas::Format) i; - const char *name = nullptr; - - if (!Canvas::getConstant(format, name)) - continue; - - luax_pushboolean(L, Canvas::isFormatSupported(format)); - lua_setfield(L, -2, name); - } - - return 1; + return w__getFormats(L, Canvas::isFormatSupported, isPixelFormatCompressed); } -int w_getRawImageFormats(lua_State *L) +int w_getImageFormats(lua_State *L) { - lua_createtable(L, 0, (int) image::ImageData::FORMAT_MAX_ENUM); - - for (int i = 0; i < (int) image::ImageData::FORMAT_MAX_ENUM; i++) + const auto ignore = [](PixelFormat format) { - auto format = (image::ImageData::Format) i; - const char *name = nullptr; + return !(image::ImageData::validPixelFormat(format) || isPixelFormatCompressed(format)); + }; - if (!image::ImageData::getConstant(format, name)) - continue; - - luax_pushboolean(L, Image::hasTextureSupport(format)); - lua_setfield(L, -2, name); - } - - return 1; -} - -int w_getCompressedImageFormats(lua_State *L) -{ - lua_createtable(L, 0, (int) image::CompressedImageData::FORMAT_MAX_ENUM); - - for (int i = 0; i < (int) image::CompressedImageData::FORMAT_MAX_ENUM; i++) - { - auto format = (image::CompressedImageData::Format) i; - const char *name = nullptr; - - if (format == image::CompressedImageData::FORMAT_UNKNOWN) - continue; - - if (!image::CompressedImageData::getConstant(format, name)) - continue; - - luax_pushboolean(L, Image::hasCompressedTextureSupport(format, false)); - lua_setfield(L, -2, name); - } - - return 1; + return w__getFormats(L, Image::isFormatSupported, ignore); } int w_getRendererInfo(lua_State *L) @@ -2214,8 +2188,7 @@ static const luaL_Reg functions[] = { "getSupported", w_getSupported }, { "getCanvasFormats", w_getCanvasFormats }, - { "getRawImageFormats", w_getRawImageFormats }, - { "getCompressedImageFormats", w_getCompressedImageFormats }, + { "getImageFormats", w_getImageFormats }, { "getRendererInfo", w_getRendererInfo }, { "getSystemLimits", w_getSystemLimits }, { "getStats", w_getStats }, diff --git a/src/modules/image/CompressedImageData.cpp b/src/modules/image/CompressedImageData.cpp index 4912bf259..3fc3a43c5 100644 --- a/src/modules/image/CompressedImageData.cpp +++ b/src/modules/image/CompressedImageData.cpp @@ -26,7 +26,7 @@ namespace image { CompressedImageData::CompressedImageData() - : format(FORMAT_UNKNOWN) + : format(PIXELFORMAT_UNKNOWN) , sRGB(false) , data(nullptr) , dataSize(0) @@ -80,7 +80,7 @@ int CompressedImageData::getHeight(int miplevel) const return dataImages[miplevel].height; } -CompressedImageData::Format CompressedImageData::getFormat() const +PixelFormat CompressedImageData::getFormat() const { return format; } @@ -96,58 +96,5 @@ void CompressedImageData::checkMipmapLevelExists(int miplevel) const throw love::Exception("Mipmap level %d does not exist", miplevel + 1); } -bool CompressedImageData::getConstant(const char *in, CompressedImageData::Format &out) -{ - return formats.find(in, out); -} - -bool CompressedImageData::getConstant(CompressedImageData::Format in, const char *&out) -{ - return formats.find(in, out); -} - -StringMap::Entry CompressedImageData::formatEntries[] = -{ - {"unknown", FORMAT_UNKNOWN}, - {"DXT1", FORMAT_DXT1}, - {"DXT3", FORMAT_DXT3}, - {"DXT5", FORMAT_DXT5}, - {"BC4", FORMAT_BC4}, - {"BC4s", FORMAT_BC4s}, - {"BC5", FORMAT_BC5}, - {"BC5s", FORMAT_BC5s}, - {"BC6h", FORMAT_BC6H}, - {"BC6hs", FORMAT_BC6Hs}, - {"BC7", FORMAT_BC7}, - {"PVR1rgb2", FORMAT_PVR1_RGB2}, - {"PVR1rgb4", FORMAT_PVR1_RGB4}, - {"PVR1rgba2", FORMAT_PVR1_RGBA2}, - {"PVR1rgba4", FORMAT_PVR1_RGBA4}, - {"ETC1", FORMAT_ETC1}, - {"ETC2rgb", FORMAT_ETC2_RGB}, - {"ETC2rgba", FORMAT_ETC2_RGBA}, - {"ETC2rgba1", FORMAT_ETC2_RGBA1}, - {"EACr", FORMAT_EAC_R}, - {"EACrs", FORMAT_EAC_Rs}, - {"EACrg", FORMAT_EAC_RG}, - {"EACrgs", FORMAT_EAC_RGs}, - {"ASTC4x4", FORMAT_ASTC_4x4}, - {"ASTC5x4", FORMAT_ASTC_5x4}, - {"ASTC5x5", FORMAT_ASTC_5x5}, - {"ASTC6x5", FORMAT_ASTC_6x5}, - {"ASTC6x6", FORMAT_ASTC_6x6}, - {"ASTC8x5", FORMAT_ASTC_8x5}, - {"ASTC8x6", FORMAT_ASTC_8x6}, - {"ASTC8x8", FORMAT_ASTC_8x8}, - {"ASTC10x5", FORMAT_ASTC_10x5}, - {"ASTC10x6", FORMAT_ASTC_10x6}, - {"ASTC10x8", FORMAT_ASTC_10x8}, - {"ASTC10x10", FORMAT_ASTC_10x10}, - {"ASTC12x10", FORMAT_ASTC_12x10}, - {"ASTC12x12", FORMAT_ASTC_12x12}, -}; - -StringMap CompressedImageData::formats(CompressedImageData::formatEntries, sizeof(CompressedImageData::formatEntries)); - } // image } // love diff --git a/src/modules/image/CompressedImageData.h b/src/modules/image/CompressedImageData.h index 40bca701f..43ad8f1a7 100644 --- a/src/modules/image/CompressedImageData.h +++ b/src/modules/image/CompressedImageData.h @@ -25,6 +25,7 @@ #include "common/Data.h" #include "common/StringMap.h" #include "common/int.h" +#include "common/pixelformat.h" // STL #include @@ -43,49 +44,6 @@ class CompressedImageData : public Data { public: - // Recognized compressed image data formats. - enum Format - { - FORMAT_UNKNOWN, - FORMAT_DXT1, - FORMAT_DXT3, - FORMAT_DXT5, - FORMAT_BC4, - FORMAT_BC4s, - FORMAT_BC5, - FORMAT_BC5s, - FORMAT_BC6H, - FORMAT_BC6Hs, - FORMAT_BC7, - FORMAT_PVR1_RGB2, - FORMAT_PVR1_RGB4, - FORMAT_PVR1_RGBA2, - FORMAT_PVR1_RGBA4, - FORMAT_ETC1, - FORMAT_ETC2_RGB, - FORMAT_ETC2_RGBA, - FORMAT_ETC2_RGBA1, - FORMAT_EAC_R, - FORMAT_EAC_Rs, - FORMAT_EAC_RG, - FORMAT_EAC_RGs, - FORMAT_ASTC_4x4, - FORMAT_ASTC_5x4, - FORMAT_ASTC_5x5, - FORMAT_ASTC_6x5, - FORMAT_ASTC_6x6, - FORMAT_ASTC_8x5, - FORMAT_ASTC_8x6, - FORMAT_ASTC_8x8, - FORMAT_ASTC_10x5, - FORMAT_ASTC_10x6, - FORMAT_ASTC_10x8, - FORMAT_ASTC_10x10, - FORMAT_ASTC_12x10, - FORMAT_ASTC_12x12, - FORMAT_MAX_ENUM - }; - // Compressed image data can have multiple mipmap levels, each represented // by a sub-image. struct SubImage @@ -131,16 +89,13 @@ public: /** * Gets the format of the compressed data. **/ - Format getFormat() const; + PixelFormat getFormat() const; bool isSRGB() const; - static bool getConstant(const char *in, Format &out); - static bool getConstant(Format in, const char *&out); - protected: - Format format; + PixelFormat format; bool sRGB; @@ -153,11 +108,6 @@ protected: void checkMipmapLevelExists(int miplevel) const; -private: - - static StringMap::Entry formatEntries[]; - static StringMap formats; - }; // CompressedImageData } // image diff --git a/src/modules/image/Image.h b/src/modules/image/Image.h index 905d2cfe3..35977ddcd 100644 --- a/src/modules/image/Image.h +++ b/src/modules/image/Image.h @@ -62,7 +62,7 @@ public: * @param height The height of the ImageData. * @return The new ImageData. **/ - virtual ImageData *newImageData(int width, int height, ImageData::Format format = ImageData::FORMAT_RGBA8) = 0; + virtual ImageData *newImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8) = 0; /** * Creates empty ImageData with the given size. @@ -73,7 +73,7 @@ public: * copy it. * @return The new ImageData. **/ - virtual ImageData *newImageData(int width, int height, ImageData::Format format, void *data, bool own = false) = 0; + virtual ImageData *newImageData(int width, int height, PixelFormat format, void *data, bool own = false) = 0; /** * Creates new CompressedImageData from FileData. diff --git a/src/modules/image/ImageData.cpp b/src/modules/image/ImageData.cpp index 5766c8931..ec6d0c2b4 100644 --- a/src/modules/image/ImageData.cpp +++ b/src/modules/image/ImageData.cpp @@ -28,7 +28,10 @@ namespace image { ImageData::ImageData() - : data(nullptr) + : format(PIXELFORMAT_UNKNOWN) + , width(0) + , height(0) + , data(nullptr) { } @@ -51,7 +54,7 @@ bool ImageData::inside(int x, int y) const return x >= 0 && x < getWidth() && y >= 0 && y < getHeight(); } -ImageData::Format ImageData::getFormat() const +PixelFormat ImageData::getFormat() const { return format; } @@ -166,35 +169,23 @@ love::thread::Mutex *ImageData::getMutex() const size_t ImageData::getPixelSize() const { - return getPixelSize(format); + return getPixelFormatSize(format); } -size_t ImageData::getPixelSize(Format format) +bool ImageData::validPixelFormat(PixelFormat format) { switch (format) { - case FORMAT_RGBA8: - return 4; - case FORMAT_RGBA16: - case FORMAT_RGBA16F: - return 8; - case FORMAT_RGBA32F: - return 16; + case PIXELFORMAT_RGBA8: + case PIXELFORMAT_RGBA16: + case PIXELFORMAT_RGBA16F: + case PIXELFORMAT_RGBA32F: + return true; default: - return 0; + return false; } } -bool ImageData::getConstant(const char *in, Format &out) -{ - return formats.find(in, out); -} - -bool ImageData::getConstant(Format in, const char *&out) -{ - return formats.find(in, out); -} - bool ImageData::getConstant(const char *in, EncodedFormat &out) { return encodedFormats.find(in, out); @@ -205,17 +196,6 @@ bool ImageData::getConstant(EncodedFormat in, const char *&out) return encodedFormats.find(in, out); } -StringMap::Entry ImageData::formatEntries[] = -{ - {"rgba8", FORMAT_RGBA8 }, - {"rgba16", FORMAT_RGBA16 }, - {"rgba16f", FORMAT_RGBA16F}, - {"rgba32f", FORMAT_RGBA32F}, -}; - -StringMap ImageData::formats(ImageData::formatEntries, sizeof(ImageData::formatEntries)); - - StringMap::Entry ImageData::encodedFormatEntries[] = { {"tga", ENCODED_TGA}, diff --git a/src/modules/image/ImageData.h b/src/modules/image/ImageData.h index f78832ec5..8da2589b1 100644 --- a/src/modules/image/ImageData.h +++ b/src/modules/image/ImageData.h @@ -25,6 +25,7 @@ #include "common/Data.h" #include "common/StringMap.h" #include "common/int.h" +#include "common/pixelformat.h" #include "common/halffloat.h" #include "filesystem/FileData.h" #include "thread/threads.h" @@ -58,15 +59,6 @@ class ImageData : public Data { public: - enum Format - { - FORMAT_RGBA8, - FORMAT_RGBA16, - FORMAT_RGBA16F, - FORMAT_RGBA32F, - FORMAT_MAX_ENUM - }; - enum EncodedFormat { ENCODED_TGA, @@ -77,7 +69,7 @@ public: ImageData(); virtual ~ImageData(); - Format getFormat() const; + PixelFormat getFormat() const; /** * Paste part of one ImageData onto another. The subregion defined by the top-left @@ -139,17 +131,14 @@ public: size_t getPixelSize() const; - static size_t getPixelSize(Format format); - - static bool getConstant(const char *in, Format &out); - static bool getConstant(Format in, const char *&out); + static bool validPixelFormat(PixelFormat format); static bool getConstant(const char *in, EncodedFormat &out); static bool getConstant(EncodedFormat in, const char *&out); protected: - Format format; + PixelFormat format; // The width of the image data. int width; @@ -167,9 +156,6 @@ protected: private: - static StringMap::Entry formatEntries[]; - static StringMap formats; - static StringMap::Entry encodedFormatEntries[]; static StringMap encodedFormats; diff --git a/src/modules/image/magpie/ASTCHandler.cpp b/src/modules/image/magpie/ASTCHandler.cpp index 189b1e55b..1bd0c911e 100644 --- a/src/modules/image/magpie/ASTCHandler.cpp +++ b/src/modules/image/magpie/ASTCHandler.cpp @@ -47,41 +47,41 @@ struct ASTCHeader }; #pragma pack(pop) -static CompressedImageData::Format convertFormat(uint32 blockX, uint32 blockY, uint32 blockZ) +static PixelFormat convertFormat(uint32 blockX, uint32 blockY, uint32 blockZ) { if (blockZ > 1) - return CompressedImageData::FORMAT_UNKNOWN; + return PIXELFORMAT_UNKNOWN; if (blockX == 4 && blockY == 4) - return CompressedImageData::FORMAT_ASTC_4x4; + return PIXELFORMAT_ASTC_4x4; else if (blockX == 5 && blockY == 4) - return CompressedImageData::FORMAT_ASTC_5x4; + return PIXELFORMAT_ASTC_5x4; else if (blockX == 5 && blockY == 5) - return CompressedImageData::FORMAT_ASTC_5x5; + return PIXELFORMAT_ASTC_5x5; else if (blockX == 6 && blockY == 5) - return CompressedImageData::FORMAT_ASTC_6x5; + return PIXELFORMAT_ASTC_6x5; else if (blockX == 6 && blockY == 6) - return CompressedImageData::FORMAT_ASTC_6x6; + return PIXELFORMAT_ASTC_6x6; else if (blockX == 8 && blockY == 5) - return CompressedImageData::FORMAT_ASTC_8x5; + return PIXELFORMAT_ASTC_8x5; else if (blockX == 8 && blockY == 6) - return CompressedImageData::FORMAT_ASTC_8x6; + return PIXELFORMAT_ASTC_8x6; else if (blockX == 8 && blockY == 8) - return CompressedImageData::FORMAT_ASTC_8x8; + return PIXELFORMAT_ASTC_8x8; else if (blockX == 10 && blockY == 5) - return CompressedImageData::FORMAT_ASTC_10x5; + return PIXELFORMAT_ASTC_10x5; else if (blockX == 10 && blockY == 6) - return CompressedImageData::FORMAT_ASTC_10x6; + return PIXELFORMAT_ASTC_10x6; else if (blockX == 10 && blockY == 8) - return CompressedImageData::FORMAT_ASTC_10x8; + return PIXELFORMAT_ASTC_10x8; else if (blockX == 10 && blockY == 10) - return CompressedImageData::FORMAT_ASTC_10x10; + return PIXELFORMAT_ASTC_10x10; else if (blockX == 12 && blockY == 10) - return CompressedImageData::FORMAT_ASTC_12x10; + return PIXELFORMAT_ASTC_12x10; else if (blockX == 12 && blockY == 12) - return CompressedImageData::FORMAT_ASTC_12x12; + return PIXELFORMAT_ASTC_12x12; - return CompressedImageData::FORMAT_UNKNOWN; + return PIXELFORMAT_UNKNOWN; } } // Anonymous namespace. @@ -104,16 +104,16 @@ bool ASTCHandler::canParse(const filesystem::FileData *data) return true; } -uint8 *ASTCHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB) +uint8 *ASTCHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB) { if (!canParse(filedata)) throw love::Exception("Could not decode compressed data (not an .astc file?)"); ASTCHeader header = *(const ASTCHeader *) filedata->getData(); - CompressedImageData::Format cformat = convertFormat(header.blockdimX, header.blockdimY, header.blockdimZ); + PixelFormat cformat = convertFormat(header.blockdimX, header.blockdimY, header.blockdimZ); - if (cformat == CompressedImageData::FORMAT_UNKNOWN) + if (cformat == PIXELFORMAT_UNKNOWN) throw love::Exception("Could not parse .astc file: unsupported ASTC format %dx%dx%d.", header.blockdimX, header.blockdimY, header.blockdimZ); uint32 sizeX = header.sizeX[0] + (header.sizeX[1] << 8) + (header.sizeX[2] << 16); diff --git a/src/modules/image/magpie/ASTCHandler.h b/src/modules/image/magpie/ASTCHandler.h index 324304efe..cce9d2b25 100644 --- a/src/modules/image/magpie/ASTCHandler.h +++ b/src/modules/image/magpie/ASTCHandler.h @@ -43,7 +43,7 @@ public: // Implements CompressedFormatHandler. virtual bool canParse(const filesystem::FileData *data); - virtual uint8 *parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB); + virtual uint8 *parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB); }; // ASTCHandler diff --git a/src/modules/image/magpie/CompressedFormatHandler.h b/src/modules/image/magpie/CompressedFormatHandler.h index 162ebac58..2ce16f4e4 100644 --- a/src/modules/image/magpie/CompressedFormatHandler.h +++ b/src/modules/image/magpie/CompressedFormatHandler.h @@ -65,7 +65,7 @@ public: * @return The single block of memory containing the parsed images. **/ virtual uint8 *parse(filesystem::FileData *filedata, std::vector &images, - size_t &dataSize, CompressedImageData::Format &format, bool &sRGB) = 0; + size_t &dataSize, PixelFormat &format, bool &sRGB) = 0; }; // CompressedFormatHandler diff --git a/src/modules/image/magpie/CompressedImageData.cpp b/src/modules/image/magpie/CompressedImageData.cpp index 3e205b4dd..278de7212 100644 --- a/src/modules/image/magpie/CompressedImageData.cpp +++ b/src/modules/image/magpie/CompressedImageData.cpp @@ -48,7 +48,7 @@ CompressedImageData::CompressedImageData(std::list fo if (data == nullptr) throw love::Exception("Could not parse compressed data."); - if (format == FORMAT_UNKNOWN) + if (format == PIXELFORMAT_UNKNOWN) { delete[] data; throw love::Exception("Could not parse compressed data: Unknown format."); diff --git a/src/modules/image/magpie/EXRHandler.cpp b/src/modules/image/magpie/EXRHandler.cpp index 4bf372009..df6946327 100644 --- a/src/modules/image/magpie/EXRHandler.cpp +++ b/src/modules/image/magpie/EXRHandler.cpp @@ -41,7 +41,7 @@ bool EXRHandler::canDecode(love::filesystem::FileData *data) return ParseEXRVersionFromMemory(&version, (const unsigned char *) data->getData(), data->getSize()) == TINYEXR_SUCCESS; } -bool EXRHandler::canEncode(ImageData::Format /*rawFormat*/, ImageData::EncodedFormat /*encodedFormat*/) +bool EXRHandler::canEncode(PixelFormat /*rawFormat*/, ImageData::EncodedFormat /*encodedFormat*/) { return false; } @@ -141,7 +141,7 @@ FormatHandler::DecodedImage EXRHandler::decode(love::filesystem::FileData *data) if (pixelType == TINYEXR_PIXELTYPE_HALF) { - img.format = ImageData::FORMAT_RGBA16F; + img.format = PIXELFORMAT_RGBA16F; half *rgba[4] = {nullptr}; getEXRChannels(exrHeader, exrImage, rgba); @@ -158,7 +158,7 @@ FormatHandler::DecodedImage EXRHandler::decode(love::filesystem::FileData *data) } else if (pixelType == TINYEXR_PIXELTYPE_FLOAT) { - img.format = ImageData::FORMAT_RGBA32F; + img.format = PIXELFORMAT_RGBA32F; float *rgba[4] = {nullptr}; getEXRChannels(exrHeader, exrImage, rgba); @@ -179,7 +179,7 @@ FormatHandler::DecodedImage EXRHandler::decode(love::filesystem::FileData *data) throw love::Exception("Could not decode EXR image: unknown pixel format."); } - img.size = img.width * img.height * ImageData::getPixelSize(img.format); + img.size = img.width * img.height * getPixelFormatSize(img.format); FreeEXRImage(&exrImage); diff --git a/src/modules/image/magpie/EXRHandler.h b/src/modules/image/magpie/EXRHandler.h index f28091e9e..bc5e28fce 100644 --- a/src/modules/image/magpie/EXRHandler.h +++ b/src/modules/image/magpie/EXRHandler.h @@ -40,7 +40,7 @@ public: // Implements FormatHandler. virtual bool canDecode(love::filesystem::FileData *data); - virtual bool canEncode(ImageData::Format rawFormat, ImageData::EncodedFormat encodedFormat); + virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat); virtual DecodedImage decode(love::filesystem::FileData *data); virtual EncodedImage encode(const DecodedImage &img, ImageData::EncodedFormat format); diff --git a/src/modules/image/magpie/FormatHandler.cpp b/src/modules/image/magpie/FormatHandler.cpp index 11b04b33a..3902add55 100644 --- a/src/modules/image/magpie/FormatHandler.cpp +++ b/src/modules/image/magpie/FormatHandler.cpp @@ -42,7 +42,7 @@ bool FormatHandler::canDecode(love::filesystem::FileData* /*data*/) return false; } -bool FormatHandler::canEncode(ImageData::Format /*rawFormat*/, ImageData::EncodedFormat /*encodedFormat*/) +bool FormatHandler::canEncode(PixelFormat /*rawFormat*/, ImageData::EncodedFormat /*encodedFormat*/) { return false; } diff --git a/src/modules/image/magpie/FormatHandler.h b/src/modules/image/magpie/FormatHandler.h index d87eb376f..75404a356 100644 --- a/src/modules/image/magpie/FormatHandler.h +++ b/src/modules/image/magpie/FormatHandler.h @@ -44,7 +44,7 @@ public: // Raw RGBA pixel data. struct DecodedImage { - ImageData::Format format = ImageData::FORMAT_RGBA8; + PixelFormat format = PIXELFORMAT_RGBA8; int width = 0; int height = 0; size_t size = 0; @@ -76,7 +76,7 @@ public: /** * Whether this format handler can encode to a particular format. **/ - virtual bool canEncode(ImageData::Format rawFormat, ImageData::EncodedFormat encodedFormat); + virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat); /** * Decodes an image from its encoded form into raw pixel data. diff --git a/src/modules/image/magpie/Image.cpp b/src/modules/image/magpie/Image.cpp index 5e3aaa1d8..f74161f33 100644 --- a/src/modules/image/magpie/Image.cpp +++ b/src/modules/image/magpie/Image.cpp @@ -82,12 +82,12 @@ love::image::ImageData *Image::newImageData(love::filesystem::FileData *data) return new ImageData(formatHandlers, data); } -love::image::ImageData *Image::newImageData(int width, int height, ImageData::Format format) +love::image::ImageData *Image::newImageData(int width, int height, PixelFormat format) { return new ImageData(formatHandlers, width, height, format); } -love::image::ImageData *Image::newImageData(int width, int height, ImageData::Format format, void *data, bool own) +love::image::ImageData *Image::newImageData(int width, int height, PixelFormat format, void *data, bool own) { return new ImageData(formatHandlers, width, height, format, data, own); } diff --git a/src/modules/image/magpie/Image.h b/src/modules/image/magpie/Image.h index ee241e07a..4ba263474 100644 --- a/src/modules/image/magpie/Image.h +++ b/src/modules/image/magpie/Image.h @@ -52,8 +52,8 @@ public: const char *getName() const; love::image::ImageData *newImageData(love::filesystem::FileData *data); - love::image::ImageData *newImageData(int width, int height, ImageData::Format format = ImageData::FORMAT_RGBA8); - love::image::ImageData *newImageData(int width, int height, ImageData::Format format, void *data, bool own = false); + love::image::ImageData *newImageData(int width, int height, PixelFormat format = PIXELFORMAT_RGBA8); + love::image::ImageData *newImageData(int width, int height, PixelFormat format, void *data, bool own = false); love::image::CompressedImageData *newCompressedData(love::filesystem::FileData *data); diff --git a/src/modules/image/magpie/ImageData.cpp b/src/modules/image/magpie/ImageData.cpp index 510caa8e9..05774528e 100644 --- a/src/modules/image/magpie/ImageData.cpp +++ b/src/modules/image/magpie/ImageData.cpp @@ -38,12 +38,12 @@ ImageData::ImageData(std::list formatHandlers, love::filesystem decode(data); } -ImageData::ImageData(std::list formatHandlers, int width, int height, Format format) +ImageData::ImageData(std::list formatHandlers, int width, int height, PixelFormat format) : formatHandlers(formatHandlers) , decodeHandler(nullptr) { - for (FormatHandler *handler : formatHandlers) - handler->retain(); + if (!validPixelFormat(format)) + throw love::Exception("Unsupported pixel format for ImageData"); this->width = width; this->height = height; @@ -53,14 +53,17 @@ ImageData::ImageData(std::list formatHandlers, int width, int h // Set to black/transparency. memset(data, 0, getSize()); + + for (FormatHandler *handler : formatHandlers) + handler->retain(); } -ImageData::ImageData(std::list formatHandlers, int width, int height, Format format, void *data, bool own) +ImageData::ImageData(std::list formatHandlers, int width, int height, PixelFormat format, void *data, bool own) : formatHandlers(formatHandlers) , decodeHandler(nullptr) { - for (FormatHandler *handler : formatHandlers) - handler->retain(); + if (!validPixelFormat(format)) + throw love::Exception("Unsupported pixel format for ImageData"); this->width = width; this->height = height; @@ -70,6 +73,9 @@ ImageData::ImageData(std::list formatHandlers, int width, int h this->data = (unsigned char *) data; else create(width, height, format, data); + + for (FormatHandler *handler : formatHandlers) + handler->retain(); } ImageData::~ImageData() @@ -83,9 +89,9 @@ ImageData::~ImageData() handler->release(); } -void ImageData::create(int width, int height, Format format, void *data) +void ImageData::create(int width, int height, PixelFormat format, void *data) { - size_t datasize = width * height * getPixelSize(format); + size_t datasize = width * height * getPixelFormatSize(format); try { @@ -126,7 +132,7 @@ void ImageData::decode(love::filesystem::FileData *data) throw love::Exception("Could not decode file '%s' to ImageData: unsupported file format", name.c_str()); } - if (decodedimage.size != decodedimage.width * decodedimage.height * getPixelSize(decodedimage.format)) + if (decodedimage.size != decodedimage.width * decodedimage.height * getPixelFormatSize(decodedimage.format)) { decoder->free(decodedimage.data); throw love::Exception("Could not convert image!"); @@ -176,7 +182,7 @@ love::filesystem::FileData *ImageData::encode(EncodedFormat encodedFormat, const if (encoder == nullptr || encodedimage.data == nullptr) { const char *fname = "unknown"; - getConstant(format, fname); + love::getConstant(format, fname); throw love::Exception("No suitable image encoder for %s format.", fname); } diff --git a/src/modules/image/magpie/ImageData.h b/src/modules/image/magpie/ImageData.h index 2c8b8f8e4..06d6798ee 100644 --- a/src/modules/image/magpie/ImageData.h +++ b/src/modules/image/magpie/ImageData.h @@ -40,8 +40,8 @@ class ImageData : public love::image::ImageData public: ImageData(std::list formatHandlers, love::filesystem::FileData *data); - ImageData(std::list formatHandlers, int width, int height, Format format = FORMAT_RGBA8); - ImageData(std::list formatHandlers, int width, int height, Format format, void *data, bool own); + ImageData(std::list formatHandlers, int width, int height, PixelFormat format = PIXELFORMAT_RGBA8); + ImageData(std::list formatHandlers, int width, int height, PixelFormat format, void *data, bool own); virtual ~ImageData(); // Implements image::ImageData. @@ -50,7 +50,7 @@ public: private: // Create imagedata. Initialize with data if not null. - void create(int width, int height, Format format, void *data = nullptr); + void create(int width, int height, PixelFormat format, void *data = nullptr); // Decode and load an encoded format. void decode(love::filesystem::FileData *data); diff --git a/src/modules/image/magpie/KTXHandler.cpp b/src/modules/image/magpie/KTXHandler.cpp index 9207895f2..9fe8bfe41 100644 --- a/src/modules/image/magpie/KTXHandler.cpp +++ b/src/modules/image/magpie/KTXHandler.cpp @@ -136,7 +136,7 @@ enum KTXGLInternalFormat KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR = 0x93DD }; -CompressedImageData::Format convertFormat(uint32 glformat, bool &sRGB) +PixelFormat convertFormat(uint32 glformat, bool &sRGB) { sRGB = false; @@ -145,136 +145,136 @@ CompressedImageData::Format convertFormat(uint32 glformat, bool &sRGB) switch (glformat) { case KTX_GL_ETC1_RGB8_OES: - return CompressedImageData::FORMAT_ETC1; + return PIXELFORMAT_ETC1; // EAC and ETC2. case KTX_GL_COMPRESSED_R11_EAC: - return CompressedImageData::FORMAT_EAC_R; + return PIXELFORMAT_EAC_R; case KTX_GL_COMPRESSED_SIGNED_R11_EAC: - return CompressedImageData::FORMAT_EAC_Rs; + return PIXELFORMAT_EAC_Rs; case KTX_GL_COMPRESSED_RG11_EAC: - return CompressedImageData::FORMAT_EAC_RG; + return PIXELFORMAT_EAC_RG; case KTX_GL_COMPRESSED_SIGNED_RG11_EAC: - return CompressedImageData::FORMAT_EAC_RGs; + return PIXELFORMAT_EAC_RGs; case KTX_GL_COMPRESSED_RGB8_ETC2: - return CompressedImageData::FORMAT_ETC2_RGB; + return PIXELFORMAT_ETC2_RGB; case KTX_GL_COMPRESSED_SRGB8_ETC2: sRGB = true; - return CompressedImageData::FORMAT_ETC2_RGB; + return PIXELFORMAT_ETC2_RGB; case KTX_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: - return CompressedImageData::FORMAT_ETC2_RGBA1; + return PIXELFORMAT_ETC2_RGBA1; case KTX_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: sRGB = true; - return CompressedImageData::FORMAT_ETC2_RGBA1; + return PIXELFORMAT_ETC2_RGBA1; case KTX_GL_COMPRESSED_RGBA8_ETC2_EAC: - return CompressedImageData::FORMAT_ETC2_RGBA; + return PIXELFORMAT_ETC2_RGBA; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: sRGB = true; - return CompressedImageData::FORMAT_ETC2_RGBA; + return PIXELFORMAT_ETC2_RGBA; // PVRTC. case KTX_GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG: - return CompressedImageData::FORMAT_PVR1_RGB4; + return PIXELFORMAT_PVR1_RGB4; case KTX_GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG: - return CompressedImageData::FORMAT_PVR1_RGB2; + return PIXELFORMAT_PVR1_RGB2; case KTX_GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: - return CompressedImageData::FORMAT_PVR1_RGBA4; + return PIXELFORMAT_PVR1_RGBA4; case KTX_GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: - return CompressedImageData::FORMAT_PVR1_RGBA2; + return PIXELFORMAT_PVR1_RGBA2; // DXT. case KTX_GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: sRGB = true; case KTX_GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - return CompressedImageData::FORMAT_DXT1; + return PIXELFORMAT_DXT1; case KTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: sRGB = true; case KTX_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - return CompressedImageData::FORMAT_DXT3; + return PIXELFORMAT_DXT3; case KTX_GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: sRGB = true; case KTX_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - return CompressedImageData::FORMAT_DXT5; + return PIXELFORMAT_DXT5; // BC4 and BC5. case KTX_GL_COMPRESSED_RED_RGTC1: - return CompressedImageData::FORMAT_BC4; + return PIXELFORMAT_BC4; case KTX_GL_COMPRESSED_SIGNED_RED_RGTC1: - return CompressedImageData::FORMAT_BC4s; + return PIXELFORMAT_BC4s; case KTX_GL_COMPRESSED_RG_RGTC2: - return CompressedImageData::FORMAT_BC5; + return PIXELFORMAT_BC5; case KTX_GL_COMPRESSED_SIGNED_RG_RGTC2: - return CompressedImageData::FORMAT_BC5s; + return PIXELFORMAT_BC5s; // BC6 and BC7. case KTX_GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: sRGB = true; case KTX_GL_COMPRESSED_RGBA_BPTC_UNORM: - return CompressedImageData::FORMAT_BC7; + return PIXELFORMAT_BC7; case KTX_GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: - return CompressedImageData::FORMAT_BC6Hs; + return PIXELFORMAT_BC6Hs; case KTX_GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: - return CompressedImageData::FORMAT_BC6H; + return PIXELFORMAT_BC6H; // ASTC. case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_4x4_KHR: - return CompressedImageData::FORMAT_ASTC_4x4; + return PIXELFORMAT_ASTC_4x4; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_5x4_KHR: - return CompressedImageData::FORMAT_ASTC_5x4; + return PIXELFORMAT_ASTC_5x4; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_5x5_KHR: - return CompressedImageData::FORMAT_ASTC_5x5; + return PIXELFORMAT_ASTC_5x5; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_6x5_KHR: - return CompressedImageData::FORMAT_ASTC_6x5; + return PIXELFORMAT_ASTC_6x5; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_6x6_KHR: - return CompressedImageData::FORMAT_ASTC_6x6; + return PIXELFORMAT_ASTC_6x6; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_8x5_KHR: - return CompressedImageData::FORMAT_ASTC_8x5; + return PIXELFORMAT_ASTC_8x5; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_8x6_KHR: - return CompressedImageData::FORMAT_ASTC_8x6; + return PIXELFORMAT_ASTC_8x6; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_8x8_KHR: - return CompressedImageData::FORMAT_ASTC_8x8; + return PIXELFORMAT_ASTC_8x8; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_10x5_KHR: - return CompressedImageData::FORMAT_ASTC_10x5; + return PIXELFORMAT_ASTC_10x5; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_10x6_KHR: - return CompressedImageData::FORMAT_ASTC_10x6; + return PIXELFORMAT_ASTC_10x6; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_10x8_KHR: - return CompressedImageData::FORMAT_ASTC_10x8; + return PIXELFORMAT_ASTC_10x8; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_10x10_KHR: - return CompressedImageData::FORMAT_ASTC_10x10; + return PIXELFORMAT_ASTC_10x10; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_12x10_KHR: - return CompressedImageData::FORMAT_ASTC_12x10; + return PIXELFORMAT_ASTC_12x10; case KTX_GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: sRGB = true; case KTX_GL_COMPRESSED_RGBA_ASTC_12x12_KHR: - return CompressedImageData::FORMAT_ASTC_12x12; + return PIXELFORMAT_ASTC_12x12; default: - return CompressedImageData::FORMAT_UNKNOWN; + return PIXELFORMAT_UNKNOWN; } } @@ -297,7 +297,7 @@ bool KTXHandler::canParse(const filesystem::FileData *data) return true; } -uint8 *KTXHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB) +uint8 *KTXHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB) { if (!canParse(filedata)) throw love::Exception("Could not decode compressed data (not a KTX file?)"); @@ -314,9 +314,9 @@ uint8 *KTXHandler::parse(filesystem::FileData *filedata, std::vector 0) diff --git a/src/modules/image/magpie/KTXHandler.h b/src/modules/image/magpie/KTXHandler.h index 8bba0645e..b859edf5a 100644 --- a/src/modules/image/magpie/KTXHandler.h +++ b/src/modules/image/magpie/KTXHandler.h @@ -42,7 +42,7 @@ public: // Implements CompressedFormatHandler. virtual bool canParse(const filesystem::FileData *data); - virtual uint8 *parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB); + virtual uint8 *parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB); }; // KTXHandler diff --git a/src/modules/image/magpie/PKMHandler.cpp b/src/modules/image/magpie/PKMHandler.cpp index 27fa8b17e..317d4f14d 100644 --- a/src/modules/image/magpie/PKMHandler.cpp +++ b/src/modules/image/magpie/PKMHandler.cpp @@ -68,29 +68,29 @@ enum PKMTextureFormat ETC2PACKAGE_RG_SIGNED_NO_MIPMAPS }; -static CompressedImageData::Format convertFormat(uint16 texformat) +static PixelFormat convertFormat(uint16 texformat) { switch (texformat) { case ETC1_RGB_NO_MIPMAPS: - return CompressedImageData::FORMAT_ETC1; + return PIXELFORMAT_ETC1; case ETC2PACKAGE_RGB_NO_MIPMAPS: - return CompressedImageData::FORMAT_ETC2_RGB; + return PIXELFORMAT_ETC2_RGB; case ETC2PACKAGE_RGBA_NO_MIPMAPS_OLD: case ETC2PACKAGE_RGBA_NO_MIPMAPS: - return CompressedImageData::FORMAT_ETC2_RGBA; + return PIXELFORMAT_ETC2_RGBA; case ETC2PACKAGE_RGBA1_NO_MIPMAPS: - return CompressedImageData::FORMAT_ETC2_RGBA1; + return PIXELFORMAT_ETC2_RGBA1; case ETC2PACKAGE_R_NO_MIPMAPS: - return CompressedImageData::FORMAT_EAC_R; + return PIXELFORMAT_EAC_R; case ETC2PACKAGE_RG_NO_MIPMAPS: - return CompressedImageData::FORMAT_EAC_RG; + return PIXELFORMAT_EAC_RG; case ETC2PACKAGE_R_SIGNED_NO_MIPMAPS: - return CompressedImageData::FORMAT_EAC_Rs; + return PIXELFORMAT_EAC_Rs; case ETC2PACKAGE_RG_SIGNED_NO_MIPMAPS: - return CompressedImageData::FORMAT_EAC_RGs; + return PIXELFORMAT_EAC_RGs; default: - return CompressedImageData::FORMAT_UNKNOWN; + return PIXELFORMAT_UNKNOWN; } } @@ -113,7 +113,7 @@ bool PKMHandler::canParse(const filesystem::FileData *data) return true; } -uint8 *PKMHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB) +uint8 *PKMHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB) { if (!canParse(filedata)) throw love::Exception("Could not decode compressed data (not a PKM file?)"); @@ -126,9 +126,9 @@ uint8 *PKMHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB); + virtual uint8 *parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB); }; // PKMHandler diff --git a/src/modules/image/magpie/PNGHandler.cpp b/src/modules/image/magpie/PNGHandler.cpp index 9a67ca65b..1f987319d 100644 --- a/src/modules/image/magpie/PNGHandler.cpp +++ b/src/modules/image/magpie/PNGHandler.cpp @@ -140,10 +140,10 @@ bool PNGHandler::canDecode(love::filesystem::FileData *data) return status == 0 && width > 0 && height > 0; } -bool PNGHandler::canEncode(ImageData::Format rawFormat, ImageData::EncodedFormat encodedFormat) +bool PNGHandler::canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat) { return encodedFormat == ImageData::ENCODED_PNG - && (rawFormat == ImageData::FORMAT_RGBA8 || rawFormat == ImageData::FORMAT_RGBA16); + && (rawFormat == PIXELFORMAT_RGBA8 || rawFormat == PIXELFORMAT_RGBA16); } PNGHandler::DecodedImage PNGHandler::decode(love::filesystem::FileData *fdata) @@ -182,7 +182,7 @@ PNGHandler::DecodedImage PNGHandler::decode(love::filesystem::FileData *fdata) img.width = (int) width; img.height = (int) height; img.size = width * height * (state.info_raw.bitdepth * 4 / 8); - img.format = state.info_raw.bitdepth == 16 ? ImageData::FORMAT_RGBA16 : ImageData::FORMAT_RGBA8; + img.format = state.info_raw.bitdepth == 16 ? PIXELFORMAT_RGBA16 : PIXELFORMAT_RGBA8; // LodePNG keeps raw 16 bit images stored as big-endian. #ifndef LOVE_BIG_ENDIAN @@ -209,7 +209,7 @@ PNGHandler::EncodedImage PNGHandler::encode(const DecodedImage &img, ImageData:: lodepng::State state; state.info_raw.colortype = LCT_RGBA; - state.info_raw.bitdepth = img.format == ImageData::FORMAT_RGBA16 ? 16 : 8; + state.info_raw.bitdepth = img.format == PIXELFORMAT_RGBA16 ? 16 : 8; state.info_png.color.colortype = LCT_RGBA; state.info_png.color.bitdepth = state.info_raw.bitdepth; diff --git a/src/modules/image/magpie/PNGHandler.h b/src/modules/image/magpie/PNGHandler.h index bde312dad..f59fb7eba 100644 --- a/src/modules/image/magpie/PNGHandler.h +++ b/src/modules/image/magpie/PNGHandler.h @@ -41,7 +41,7 @@ public: // Implements FormatHandler. virtual bool canDecode(love::filesystem::FileData *data); - virtual bool canEncode(ImageData::Format rawFormat, ImageData::EncodedFormat encodedFormat); + virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat); virtual DecodedImage decode(love::filesystem::FileData *data); virtual EncodedImage encode(const DecodedImage &img, ImageData::EncodedFormat format); diff --git a/src/modules/image/magpie/PVRHandler.cpp b/src/modules/image/magpie/PVRHandler.cpp index 4dea69414..aa7f6a6d6 100644 --- a/src/modules/image/magpie/PVRHandler.cpp +++ b/src/modules/image/magpie/PVRHandler.cpp @@ -203,7 +203,7 @@ void ConvertPVRHeader(PVRTexHeaderV2 header2, PVRTexHeaderV3 *header3) } } -static CompressedImageData::Format convertFormat(PVRV3PixelFormat format, PVRV3ChannelType channeltype) +static PixelFormat convertFormat(PVRV3PixelFormat format, PVRV3ChannelType channeltype) { bool snorm = false; @@ -221,69 +221,69 @@ static CompressedImageData::Format convertFormat(PVRV3PixelFormat format, PVRV3C switch (format) { case ePVRTPF_PVRTCI_2bpp_RGB: - return CompressedImageData::FORMAT_PVR1_RGB2; + return PIXELFORMAT_PVR1_RGB2; case ePVRTPF_PVRTCI_2bpp_RGBA: - return CompressedImageData::FORMAT_PVR1_RGBA2; + return PIXELFORMAT_PVR1_RGBA2; case ePVRTPF_PVRTCI_4bpp_RGB: - return CompressedImageData::FORMAT_PVR1_RGB4; + return PIXELFORMAT_PVR1_RGB4; case ePVRTPF_PVRTCI_4bpp_RGBA: - return CompressedImageData::FORMAT_PVR1_RGBA4; + return PIXELFORMAT_PVR1_RGBA4; case ePVRTPF_ETC1: - return CompressedImageData::FORMAT_ETC1; + return PIXELFORMAT_ETC1; case ePVRTPF_DXT1: - return CompressedImageData::FORMAT_DXT1; + return PIXELFORMAT_DXT1; case ePVRTPF_DXT3: - return CompressedImageData::FORMAT_DXT3; + return PIXELFORMAT_DXT3; case ePVRTPF_DXT5: - return CompressedImageData::FORMAT_DXT5; + return PIXELFORMAT_DXT5; case ePVRTPF_BC4: - return snorm ? CompressedImageData::FORMAT_BC4s : CompressedImageData::FORMAT_BC4; + return snorm ? PIXELFORMAT_BC4s : PIXELFORMAT_BC4; case ePVRTPF_BC5: - return snorm ? CompressedImageData::FORMAT_BC5s : CompressedImageData::FORMAT_BC5; + return snorm ? PIXELFORMAT_BC5s : PIXELFORMAT_BC5; case ePVRTPF_BC6: - return snorm ? CompressedImageData::FORMAT_BC6Hs : CompressedImageData::FORMAT_BC6H; + return snorm ? PIXELFORMAT_BC6Hs : PIXELFORMAT_BC6H; case ePVRTPF_BC7: - return CompressedImageData::FORMAT_BC7; + return PIXELFORMAT_BC7; case ePVRTPF_ETC2_RGB: - return CompressedImageData::FORMAT_ETC2_RGB; + return PIXELFORMAT_ETC2_RGB; case ePVRTPF_ETC2_RGBA: - return CompressedImageData::FORMAT_ETC2_RGBA; + return PIXELFORMAT_ETC2_RGBA; case ePVRTPF_ETC2_RGBA1: - return CompressedImageData::FORMAT_ETC2_RGBA1; + return PIXELFORMAT_ETC2_RGBA1; case ePVRTPF_EAC_R: - return snorm ? CompressedImageData::FORMAT_EAC_Rs : CompressedImageData::FORMAT_EAC_R; + return snorm ? PIXELFORMAT_EAC_Rs : PIXELFORMAT_EAC_R; case ePVRTPF_EAC_RG: - return snorm ? CompressedImageData::FORMAT_EAC_RGs : CompressedImageData::FORMAT_EAC_RG; + return snorm ? PIXELFORMAT_EAC_RGs : PIXELFORMAT_EAC_RG; case ePVRTPF_ASTC_4x4: - return CompressedImageData::FORMAT_ASTC_4x4; + return PIXELFORMAT_ASTC_4x4; case ePVRTPF_ASTC_5x4: - return CompressedImageData::FORMAT_ASTC_5x4; + return PIXELFORMAT_ASTC_5x4; case ePVRTPF_ASTC_5x5: - return CompressedImageData::FORMAT_ASTC_5x5; + return PIXELFORMAT_ASTC_5x5; case ePVRTPF_ASTC_6x5: - return CompressedImageData::FORMAT_ASTC_6x5; + return PIXELFORMAT_ASTC_6x5; case ePVRTPF_ASTC_6x6: - return CompressedImageData::FORMAT_ASTC_6x6; + return PIXELFORMAT_ASTC_6x6; case ePVRTPF_ASTC_8x5: - return CompressedImageData::FORMAT_ASTC_8x5; + return PIXELFORMAT_ASTC_8x5; case ePVRTPF_ASTC_8x6: - return CompressedImageData::FORMAT_ASTC_8x6; + return PIXELFORMAT_ASTC_8x6; case ePVRTPF_ASTC_8x8: - return CompressedImageData::FORMAT_ASTC_8x8; + return PIXELFORMAT_ASTC_8x8; case ePVRTPF_ASTC_10x5: - return CompressedImageData::FORMAT_ASTC_10x5; + return PIXELFORMAT_ASTC_10x5; case ePVRTPF_ASTC_10x6: - return CompressedImageData::FORMAT_ASTC_10x6; + return PIXELFORMAT_ASTC_10x6; case ePVRTPF_ASTC_10x8: - return CompressedImageData::FORMAT_ASTC_10x8; + return PIXELFORMAT_ASTC_10x8; case ePVRTPF_ASTC_10x10: - return CompressedImageData::FORMAT_ASTC_10x10; + return PIXELFORMAT_ASTC_10x10; case ePVRTPF_ASTC_12x10: - return CompressedImageData::FORMAT_ASTC_12x10; + return PIXELFORMAT_ASTC_12x10; case ePVRTPF_ASTC_12x12: - return CompressedImageData::FORMAT_ASTC_12x12; + return PIXELFORMAT_ASTC_12x12; default: - return CompressedImageData::FORMAT_UNKNOWN; + return PIXELFORMAT_UNKNOWN; } } @@ -474,7 +474,7 @@ bool PVRHandler::canParse(const filesystem::FileData *data) return false; } -uint8 *PVRHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB) +uint8 *PVRHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB) { if (!canParse(filedata)) throw love::Exception("Could not decode compressed data (not a PVR file?)"); @@ -507,9 +507,9 @@ uint8 *PVRHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB); + virtual uint8 *parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB); }; // PVRHandler diff --git a/src/modules/image/magpie/STBHandler.cpp b/src/modules/image/magpie/STBHandler.cpp index 16b8aae80..a49860568 100644 --- a/src/modules/image/magpie/STBHandler.cpp +++ b/src/modules/image/magpie/STBHandler.cpp @@ -60,9 +60,9 @@ bool STBHandler::canDecode(love::filesystem::FileData *data) return status == 1 && w > 0 && h > 0; } -bool STBHandler::canEncode(ImageData::Format rawFormat, ImageData::EncodedFormat encodedFormat) +bool STBHandler::canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat) { - return encodedFormat == ImageData::ENCODED_TGA && rawFormat == ImageData::FORMAT_RGBA8; + return encodedFormat == ImageData::ENCODED_TGA && rawFormat == PIXELFORMAT_RGBA8; } FormatHandler::DecodedImage STBHandler::decode(love::filesystem::FileData *data) @@ -77,13 +77,13 @@ FormatHandler::DecodedImage STBHandler::decode(love::filesystem::FileData *data) { img.data = (unsigned char *) stbi_loadf_from_memory(buffer, bufferlen, &img.width, &img.height, &comp, 4); img.size = img.width * img.height * 4 * sizeof(float); - img.format = ImageData::FORMAT_RGBA32F; + img.format = PIXELFORMAT_RGBA32F; } else { img.data = stbi_load_from_memory(buffer, bufferlen, &img.width, &img.height, &comp, 4); img.size = img.width * img.height * 4; - img.format = ImageData::FORMAT_RGBA8; + img.format = PIXELFORMAT_RGBA8; } if (img.data == nullptr || img.width <= 0 || img.height <= 0) diff --git a/src/modules/image/magpie/STBHandler.h b/src/modules/image/magpie/STBHandler.h index 530dd6a1b..cea75ed5c 100644 --- a/src/modules/image/magpie/STBHandler.h +++ b/src/modules/image/magpie/STBHandler.h @@ -44,7 +44,7 @@ public: // Implements FormatHandler. virtual bool canDecode(love::filesystem::FileData *data); - virtual bool canEncode(ImageData::Format rawFormat, ImageData::EncodedFormat encodedFormat); + virtual bool canEncode(PixelFormat rawFormat, ImageData::EncodedFormat encodedFormat); virtual DecodedImage decode(love::filesystem::FileData *data); virtual EncodedImage encode(const DecodedImage &img, ImageData::EncodedFormat format); diff --git a/src/modules/image/magpie/ddsHandler.cpp b/src/modules/image/magpie/ddsHandler.cpp index 38d3334ff..dea3d5972 100644 --- a/src/modules/image/magpie/ddsHandler.cpp +++ b/src/modules/image/magpie/ddsHandler.cpp @@ -32,12 +32,12 @@ bool DDSHandler::canParse(const filesystem::FileData *data) return dds::isCompressedDDS(data->getData(), data->getSize()); } -uint8 *DDSHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB) +uint8 *DDSHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB) { if (!dds::isDDS(filedata->getData(), filedata->getSize())) throw love::Exception("Could not decode compressed data (not a DDS file?)"); - CompressedImageData::Format texformat = CompressedImageData::FORMAT_UNKNOWN; + PixelFormat texformat = PIXELFORMAT_UNKNOWN; bool isSRGB = false; uint8 *data = nullptr; @@ -51,7 +51,7 @@ uint8 *DDSHandler::parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB); + virtual uint8 *parse(filesystem::FileData *filedata, std::vector &images, size_t &dataSize, PixelFormat &format, bool &sRGB); private: - static CompressedImageData::Format convertFormat(dds::Format ddsformat, bool &sRGB); + static PixelFormat convertFormat(dds::Format ddsformat, bool &sRGB); }; // DDSHandler diff --git a/src/modules/image/wrap_CompressedImageData.cpp b/src/modules/image/wrap_CompressedImageData.cpp index 382013c30..027db05e0 100644 --- a/src/modules/image/wrap_CompressedImageData.cpp +++ b/src/modules/image/wrap_CompressedImageData.cpp @@ -83,10 +83,10 @@ int w_CompressedImageData_getFormat(lua_State *L) { CompressedImageData *t = luax_checkcompressedimagedata(L, 1); - image::CompressedImageData::Format format = t->getFormat(); + PixelFormat format = t->getFormat(); const char *str; - if (image::CompressedImageData::getConstant(format, str)) + if (getConstant(format, str)) lua_pushstring(L, str); else lua_pushstring(L, "unknown"); diff --git a/src/modules/image/wrap_Image.cpp b/src/modules/image/wrap_Image.cpp index 96bcb05a1..14672c529 100644 --- a/src/modules/image/wrap_Image.cpp +++ b/src/modules/image/wrap_Image.cpp @@ -44,13 +44,13 @@ int w_newImageData(lua_State *L) if (w <= 0 || h <= 0) return luaL_error(L, "Invalid image size."); - ImageData::Format format = ImageData::FORMAT_RGBA8; + PixelFormat format = PIXELFORMAT_RGBA8; if (!lua_isnoneornil(L, 3)) { const char *fstr = luaL_checkstring(L, 3); - if (!ImageData::getConstant(fstr, format)) - return luaL_error(L, "Invalid ImageData format: %s", fstr); + if (!getConstant(fstr, format)) + return luaL_error(L, "Invalid pixel format: %s", fstr); } size_t numbytes = 0; diff --git a/src/modules/image/wrap_ImageData.cpp b/src/modules/image/wrap_ImageData.cpp index 7b622bcea..6370a2001 100644 --- a/src/modules/image/wrap_ImageData.cpp +++ b/src/modules/image/wrap_ImageData.cpp @@ -46,11 +46,11 @@ ImageData *luax_checkimagedata(lua_State *L, int idx) int w_ImageData_getFormat(lua_State *L) { ImageData *t = luax_checkimagedata(L, 1); - ImageData::Format format = t->getFormat(); + PixelFormat format = t->getFormat(); const char *fstr = nullptr; - if (!ImageData::getConstant(format, fstr)) - return luaL_error(L, "Unknown ImageData format."); + if (!getConstant(format, fstr)) + return luaL_error(L, "Unknown pixel format."); lua_pushstring(L, fstr); return 1; @@ -143,21 +143,8 @@ static int luax_pushpixel_rgba32f(lua_State *L, const Pixel &p) typedef void(*checkpixel)(lua_State *L, int startidx, Pixel &p); typedef int(*pushpixel)(lua_State *L, const Pixel &p); -static checkpixel checkFormats[ImageData::FORMAT_MAX_ENUM] = -{ - luax_checkpixel_rgba8, - luax_checkpixel_rgba16, - luax_checkpixel_rgba16f, - luax_checkpixel_rgba32f, -}; - -static pushpixel pushFormats[ImageData::FORMAT_MAX_ENUM] = -{ - luax_pushpixel_rgba8, - luax_pushpixel_rgba16, - luax_pushpixel_rgba16f, - luax_pushpixel_rgba32f, -}; +static checkpixel checkFormats[PIXELFORMAT_MAX_ENUM] = {}; +static pushpixel pushFormats[PIXELFORMAT_MAX_ENUM] = {}; int w_ImageData_getPixel(lua_State *L) { @@ -165,7 +152,7 @@ int w_ImageData_getPixel(lua_State *L) int x = (int) luaL_checknumber(L, 2); int y = (int) luaL_checknumber(L, 3); - ImageData::Format format = t->getFormat(); + PixelFormat format = t->getFormat(); Pixel p; luax_catchexcept(L, [&](){ t->getPixel(x, y, p); }); @@ -179,7 +166,7 @@ int w_ImageData_setPixel(lua_State *L) int x = (int) luaL_checknumber(L, 2); int y = (int) luaL_checknumber(L, 3); - ImageData::Format format = t->getFormat(); + PixelFormat format = t->getFormat(); Pixel p; @@ -217,7 +204,7 @@ int w_ImageData__mapPixelUnsafe(lua_State *L) int iw = t->getWidth(); - ImageData::Format format = t->getFormat(); + PixelFormat format = t->getFormat(); auto checkpixel = checkFormats[format]; auto pushpixel = pushFormats[format]; @@ -366,6 +353,16 @@ static const luaL_Reg w_ImageData_functions[] = extern "C" int luaopen_imagedata(lua_State *L) { + checkFormats[PIXELFORMAT_RGBA8] = luax_checkpixel_rgba8; + checkFormats[PIXELFORMAT_RGBA16] = luax_checkpixel_rgba16; + checkFormats[PIXELFORMAT_RGBA16F] = luax_checkpixel_rgba16f; + checkFormats[PIXELFORMAT_RGBA32F] = luax_checkpixel_rgba32f; + + pushFormats[PIXELFORMAT_RGBA8] = luax_pushpixel_rgba8; + pushFormats[PIXELFORMAT_RGBA16] = luax_pushpixel_rgba16; + pushFormats[PIXELFORMAT_RGBA16F] = luax_pushpixel_rgba16f; + pushFormats[PIXELFORMAT_RGBA32F] = luax_pushpixel_rgba32f; + int ret = luax_register_type(L, IMAGE_IMAGE_DATA_ID, "ImageData", w_Data_functions, w_ImageData_functions, nullptr); luax_gettypemetatable(L, IMAGE_IMAGE_DATA_ID);