mirror of
https://github.com/love2d/love.git
synced 2026-08-12 08:30:56 +02:00
Unify pixel format enums for ImageData, CompressedImageData, and Canvas into a single PixelFormat enum.
Replace love.graphics.getRawImageFormats and love.graphics.getCompressedImageFormats with love.graphics.getImageFormats. --HG-- branch : minor
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 = "<group>"; };
|
||||
FA91591D1CF1ED7500A7053F /* halffloat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = halffloat.h; sourceTree = "<group>"; };
|
||||
FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
|
||||
FA9D8DCF1DEB56C3002CD881 /* pixelformat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = pixelformat.cpp; sourceTree = "<group>"; };
|
||||
FA9D8DD01DEB56C3002CD881 /* pixelformat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pixelformat.h; sourceTree = "<group>"; };
|
||||
FAA3A9AC1B7D465A00CED060 /* android.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = android.cpp; sourceTree = "<group>"; };
|
||||
FAA3A9AD1B7D465A00CED060 /* android.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = android.h; sourceTree = "<group>"; };
|
||||
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 */,
|
||||
|
||||
@@ -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<PixelFormat, PIXELFORMAT_MAX_ENUM>::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<PixelFormat, PIXELFORMAT_MAX_ENUM> 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
|
||||
@@ -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
|
||||
@@ -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.");
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<Canvas::Format, Canvas::FORMAT_MAX_ENUM>::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::Format, Canvas::FORMAT_MAX_ENUM> Canvas::formats(Canvas::formatEntries, sizeof(Canvas::formatEntries));
|
||||
|
||||
} // opengl
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -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<Format, FORMAT_MAX_ENUM>::Entry formatEntries[];
|
||||
static StringMap<Format, FORMAT_MAX_ENUM> formats;
|
||||
static bool supportedFormats[PIXELFORMAT_MAX_ENUM];
|
||||
static bool checkedFormats[PIXELFORMAT_MAX_ENUM];
|
||||
|
||||
}; // Canvas
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ Image::Image(const std::vector<love::image::ImageData *> &imagedata, const Flags
|
||||
for (const auto &id : imagedata)
|
||||
data.push_back(id);
|
||||
|
||||
format = data[0]->getFormat();
|
||||
|
||||
preload();
|
||||
loadVolatile();
|
||||
|
||||
@@ -148,6 +150,8 @@ Image::Image(const std::vector<love::image::CompressedImageData *> &compressedda
|
||||
for (image::CompressedImageData *cd : compresseddata)
|
||||
cdata.push_back(cd);
|
||||
|
||||
format = cdata[0]->getFormat();
|
||||
|
||||
preload();
|
||||
loadVolatile();
|
||||
|
||||
@@ -230,7 +234,7 @@ void Image::loadDefaultTexture()
|
||||
|
||||
void Image::loadFromCompressedData()
|
||||
{
|
||||
GLenum iformat = getCompressedFormat(cdata[0]->getFormat(), sRGB);
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false, sRGB);
|
||||
|
||||
if (isGammaCorrect() && !sRGB)
|
||||
flags.linear = true;
|
||||
@@ -249,17 +253,15 @@ void Image::loadFromCompressedData()
|
||||
auto cd = cdata.size() > 1 ? cdata[i].get() : cdata[0].get();
|
||||
int datamip = cdata.size() > 1 ? 0 : i;
|
||||
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, i, iformat, cd->getWidth(datamip),
|
||||
cd->getHeight(datamip), 0,
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, i, fmt.internalformat,
|
||||
cd->getWidth(datamip), cd->getHeight(datamip), 0,
|
||||
(GLsizei) cd->getSize(datamip), cd->getData(datamip));
|
||||
}
|
||||
}
|
||||
|
||||
void Image::loadFromImageData()
|
||||
{
|
||||
GLenum glformat = GL_RGBA;
|
||||
GLenum gltype = GL_UNSIGNED_BYTE;
|
||||
GLenum iformat = getFormat(data[0]->getFormat(), glformat, gltype, sRGB);
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false, sRGB);
|
||||
|
||||
if (isGammaCorrect() && !sRGB)
|
||||
flags.linear = true;
|
||||
@@ -271,8 +273,8 @@ void Image::loadFromImageData()
|
||||
love::image::ImageData *id = data[i].get();
|
||||
love::thread::Lock lock(id->getMutex());
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, i, iformat, id->getWidth(), id->getHeight(),
|
||||
0, glformat, gltype, id->getData());
|
||||
glTexImage2D(GL_TEXTURE_2D, i, fmt.internalformat, id->getWidth(), id->getHeight(),
|
||||
0, fmt.externalformat, fmt.type, id->getData());
|
||||
}
|
||||
|
||||
if (data.size() <= 1)
|
||||
@@ -286,13 +288,13 @@ bool Image::loadVolatile()
|
||||
|
||||
OpenGL::TempDebugGroup debuggroup("Image load");
|
||||
|
||||
if (isCompressed() && !hasCompressedTextureSupport(cdata[0]->getFormat(), sRGB))
|
||||
if (!OpenGL::isPixelFormatSupported(format, false, sRGB))
|
||||
{
|
||||
const char *str;
|
||||
if (image::CompressedImageData::getConstant(cdata[0]->getFormat(), str))
|
||||
if (love::getConstant(format, str))
|
||||
{
|
||||
throw love::Exception("Cannot create image: "
|
||||
"%s%s compressed images are not supported on this system.", sRGB ? "sRGB " : "", str);
|
||||
"%s%s images are not supported on this system.", sRGB ? "sRGB " : "", str);
|
||||
}
|
||||
else
|
||||
throw love::Exception("cannot create image: format is not supported on this system.");
|
||||
@@ -417,9 +419,8 @@ bool Image::refresh(int xoffset, int yoffset, int w, int h)
|
||||
return true;
|
||||
}
|
||||
|
||||
GLenum glformat = GL_RGBA;
|
||||
GLenum gltype = GL_UNSIGNED_BYTE;
|
||||
getFormat(data[0]->getFormat(), glformat, gltype, sRGB);
|
||||
bool isSRGB = sRGB;
|
||||
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false, isSRGB);
|
||||
|
||||
int mipcount = flags.mipmaps ? (int) data.size() : 1;
|
||||
|
||||
@@ -430,8 +431,8 @@ bool Image::refresh(int xoffset, int yoffset, int w, int h)
|
||||
pdata += yoffset * data[i]->getWidth() + xoffset;
|
||||
|
||||
thread::Lock lock(data[i]->getMutex());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, i, xoffset, yoffset, w, h, glformat,
|
||||
gltype, pdata);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, i, xoffset, yoffset, w, h,
|
||||
fmt.externalformat, fmt.type, pdata);
|
||||
|
||||
xoffset /= 2;
|
||||
yoffset /= 2;
|
||||
@@ -501,7 +502,7 @@ void Image::setFilter(const Texture::Filter &f)
|
||||
|
||||
filter = f;
|
||||
|
||||
if (!data.empty() && !hasTextureFilteringSupport(data[0]->getFormat()))
|
||||
if (!data.empty() && !OpenGL::hasTextureFilteringSupport(data[0]->getFormat()))
|
||||
{
|
||||
filter.mag = filter.min = FILTER_NEAREST;
|
||||
|
||||
@@ -599,245 +600,9 @@ bool Image::isCompressed() const
|
||||
return compressed;
|
||||
}
|
||||
|
||||
GLenum Image::getFormat(image::ImageData::Format format, GLenum &glformat, GLenum &gltype, bool &isSRGB) const
|
||||
bool Image::isFormatSupported(PixelFormat pixelformat)
|
||||
{
|
||||
using image::ImageData;
|
||||
|
||||
GLenum internalformat = GL_RGBA8;
|
||||
glformat = GL_RGBA;
|
||||
gltype = GL_UNSIGNED_BYTE;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case ImageData::FORMAT_RGBA8:
|
||||
if (isSRGB)
|
||||
{
|
||||
internalformat = GL_SRGB8_ALPHA8;
|
||||
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
|
||||
glformat = GL_SRGB_ALPHA;
|
||||
}
|
||||
break;
|
||||
case ImageData::FORMAT_RGBA16:
|
||||
internalformat = GL_RGBA16;
|
||||
gltype = GL_UNSIGNED_SHORT;
|
||||
isSRGB = false;
|
||||
break;
|
||||
case ImageData::FORMAT_RGBA16F:
|
||||
internalformat = GL_RGBA16F;
|
||||
// HALF_FLOAT_OES has a different value than HALF_FLOAT... of course
|
||||
if (GLAD_OES_texture_half_float && !GLAD_ES_VERSION_3_0)
|
||||
gltype = GL_HALF_FLOAT_OES;
|
||||
else
|
||||
gltype = GL_HALF_FLOAT;
|
||||
isSRGB = false;
|
||||
break;
|
||||
case ImageData::FORMAT_RGBA32F:
|
||||
internalformat = GL_RGBA32F;
|
||||
gltype = GL_FLOAT;
|
||||
isSRGB = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
|
||||
internalformat = glformat;
|
||||
|
||||
return internalformat;
|
||||
}
|
||||
|
||||
GLenum Image::getCompressedFormat(image::CompressedImageData::Format cformat, bool &isSRGB) const
|
||||
{
|
||||
using image::CompressedImageData;
|
||||
|
||||
switch (cformat)
|
||||
{
|
||||
case CompressedImageData::FORMAT_DXT1:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
|
||||
case CompressedImageData::FORMAT_DXT3:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT : GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
|
||||
case CompressedImageData::FORMAT_DXT5:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT : GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
|
||||
case CompressedImageData::FORMAT_BC4:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_RED_RGTC1;
|
||||
case CompressedImageData::FORMAT_BC4s:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_SIGNED_RED_RGTC1;
|
||||
case CompressedImageData::FORMAT_BC5:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_RG_RGTC2;
|
||||
case CompressedImageData::FORMAT_BC5s:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_SIGNED_RG_RGTC2;
|
||||
case CompressedImageData::FORMAT_BC6H:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT;
|
||||
case CompressedImageData::FORMAT_BC6Hs:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT;
|
||||
case CompressedImageData::FORMAT_BC7:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM : GL_COMPRESSED_RGBA_BPTC_UNORM;
|
||||
case CompressedImageData::FORMAT_PVR1_RGB2:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT : GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
|
||||
case CompressedImageData::FORMAT_PVR1_RGB4:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT : GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
|
||||
case CompressedImageData::FORMAT_PVR1_RGBA2:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT : GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
|
||||
case CompressedImageData::FORMAT_PVR1_RGBA4:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT : GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
|
||||
case CompressedImageData::FORMAT_ETC1:
|
||||
// The ETC2 format can load ETC1 textures.
|
||||
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility)
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ETC2 : GL_COMPRESSED_RGB8_ETC2;
|
||||
else
|
||||
{
|
||||
isSRGB = false;
|
||||
return GL_ETC1_RGB8_OES;
|
||||
}
|
||||
case CompressedImageData::FORMAT_ETC2_RGB:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ETC2 : GL_COMPRESSED_RGB8_ETC2;
|
||||
case CompressedImageData::FORMAT_ETC2_RGBA:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : GL_COMPRESSED_RGBA8_ETC2_EAC;
|
||||
case CompressedImageData::FORMAT_ETC2_RGBA1:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 : GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
|
||||
case CompressedImageData::FORMAT_EAC_R:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_R11_EAC;
|
||||
case CompressedImageData::FORMAT_EAC_Rs:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_SIGNED_R11_EAC;
|
||||
case CompressedImageData::FORMAT_EAC_RG:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_RG11_EAC;
|
||||
case CompressedImageData::FORMAT_EAC_RGs:
|
||||
isSRGB = false;
|
||||
return GL_COMPRESSED_SIGNED_RG11_EAC;
|
||||
case CompressedImageData::FORMAT_ASTC_4x4:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_5x4:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_5x5:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_6x5:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_6x6:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_8x5:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_8x6:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_8x8:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_10x5:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_10x6:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_10x8:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_10x10:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_12x10:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
|
||||
case CompressedImageData::FORMAT_ASTC_12x12:
|
||||
return isSRGB ? GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
|
||||
default:
|
||||
return isSRGB ? GL_SRGB8_ALPHA8 : GL_RGBA8;
|
||||
}
|
||||
}
|
||||
|
||||
bool Image::hasAnisotropicFilteringSupport()
|
||||
{
|
||||
return GLAD_EXT_texture_filter_anisotropic != GL_FALSE;
|
||||
}
|
||||
|
||||
bool Image::hasTextureSupport(image::ImageData::Format format)
|
||||
{
|
||||
using image::ImageData;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case ImageData::FORMAT_RGBA8:
|
||||
return true;
|
||||
case ImageData::FORMAT_RGBA16:
|
||||
return GLAD_VERSION_1_1 || GLAD_EXT_texture_norm16;
|
||||
case ImageData::FORMAT_RGBA16F:
|
||||
return GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel) || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float;
|
||||
case ImageData::FORMAT_RGBA32F:
|
||||
return GLAD_VERSION_3_0 || GLAD_ARB_texture_float || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_float;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Image::hasTextureFilteringSupport(image::ImageData::Format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case image::ImageData::FORMAT_RGBA16F:
|
||||
return GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear;
|
||||
case image::ImageData::FORMAT_RGBA32F:
|
||||
return GLAD_VERSION_1_1;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Image::hasCompressedTextureSupport(image::CompressedImageData::Format format, bool sRGB)
|
||||
{
|
||||
using image::CompressedImageData;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case CompressedImageData::FORMAT_DXT1:
|
||||
return GLAD_EXT_texture_compression_s3tc || GLAD_EXT_texture_compression_dxt1;
|
||||
case CompressedImageData::FORMAT_DXT3:
|
||||
return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt3;
|
||||
case CompressedImageData::FORMAT_DXT5:
|
||||
return GLAD_EXT_texture_compression_s3tc || GLAD_ANGLE_texture_compression_dxt5;
|
||||
case CompressedImageData::FORMAT_BC4:
|
||||
case CompressedImageData::FORMAT_BC4s:
|
||||
case CompressedImageData::FORMAT_BC5:
|
||||
case CompressedImageData::FORMAT_BC5s:
|
||||
return (GLAD_VERSION_3_0 || GLAD_ARB_texture_compression_rgtc || GLAD_EXT_texture_compression_rgtc);
|
||||
case CompressedImageData::FORMAT_BC6H:
|
||||
case CompressedImageData::FORMAT_BC6Hs:
|
||||
case CompressedImageData::FORMAT_BC7:
|
||||
return GLAD_VERSION_4_2 || GLAD_ARB_texture_compression_bptc;
|
||||
case CompressedImageData::FORMAT_PVR1_RGB2:
|
||||
case CompressedImageData::FORMAT_PVR1_RGB4:
|
||||
case CompressedImageData::FORMAT_PVR1_RGBA2:
|
||||
case CompressedImageData::FORMAT_PVR1_RGBA4:
|
||||
return sRGB ? GLAD_EXT_pvrtc_sRGB : GLAD_IMG_texture_compression_pvrtc;
|
||||
case CompressedImageData::FORMAT_ETC1:
|
||||
// ETC2 support guarantees ETC1 support as well.
|
||||
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility || GLAD_OES_compressed_ETC1_RGB8_texture;
|
||||
case CompressedImageData::FORMAT_ETC2_RGB:
|
||||
case CompressedImageData::FORMAT_ETC2_RGBA:
|
||||
case CompressedImageData::FORMAT_ETC2_RGBA1:
|
||||
case CompressedImageData::FORMAT_EAC_R:
|
||||
case CompressedImageData::FORMAT_EAC_Rs:
|
||||
case CompressedImageData::FORMAT_EAC_RG:
|
||||
case CompressedImageData::FORMAT_EAC_RGs:
|
||||
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility;
|
||||
case CompressedImageData::FORMAT_ASTC_4x4:
|
||||
case CompressedImageData::FORMAT_ASTC_5x4:
|
||||
case CompressedImageData::FORMAT_ASTC_5x5:
|
||||
case CompressedImageData::FORMAT_ASTC_6x5:
|
||||
case CompressedImageData::FORMAT_ASTC_6x6:
|
||||
case CompressedImageData::FORMAT_ASTC_8x5:
|
||||
case CompressedImageData::FORMAT_ASTC_8x6:
|
||||
case CompressedImageData::FORMAT_ASTC_8x8:
|
||||
case CompressedImageData::FORMAT_ASTC_10x5:
|
||||
case CompressedImageData::FORMAT_ASTC_10x6:
|
||||
case CompressedImageData::FORMAT_ASTC_10x8:
|
||||
case CompressedImageData::FORMAT_ASTC_10x10:
|
||||
case CompressedImageData::FORMAT_ASTC_12x10:
|
||||
case CompressedImageData::FORMAT_ASTC_12x12:
|
||||
return GLAD_ES_VERSION_3_2 || GLAD_KHR_texture_compression_astc_ldr;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return OpenGL::isPixelFormatSupported(pixelformat, false, false);
|
||||
}
|
||||
|
||||
bool Image::hasSRGBSupport()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -123,6 +123,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct TextureFormat
|
||||
{
|
||||
GLenum internalformat = 0;
|
||||
GLenum externalformat = 0;
|
||||
GLenum type = 0;
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
std::vector<Matrix4> 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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 },
|
||||
|
||||
@@ -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<CompressedImageData::Format, CompressedImageData::FORMAT_MAX_ENUM>::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::Format, CompressedImageData::FORMAT_MAX_ENUM> CompressedImageData::formats(CompressedImageData::formatEntries, sizeof(CompressedImageData::formatEntries));
|
||||
|
||||
} // image
|
||||
} // love
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "common/Data.h"
|
||||
#include "common/StringMap.h"
|
||||
#include "common/int.h"
|
||||
#include "common/pixelformat.h"
|
||||
|
||||
// STL
|
||||
#include <vector>
|
||||
@@ -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<Format, FORMAT_MAX_ENUM>::Entry formatEntries[];
|
||||
static StringMap<Format, FORMAT_MAX_ENUM> formats;
|
||||
|
||||
}; // CompressedImageData
|
||||
|
||||
} // image
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<ImageData::Format, ImageData::FORMAT_MAX_ENUM>::Entry ImageData::formatEntries[] =
|
||||
{
|
||||
{"rgba8", FORMAT_RGBA8 },
|
||||
{"rgba16", FORMAT_RGBA16 },
|
||||
{"rgba16f", FORMAT_RGBA16F},
|
||||
{"rgba32f", FORMAT_RGBA32F},
|
||||
};
|
||||
|
||||
StringMap<ImageData::Format, ImageData::FORMAT_MAX_ENUM> ImageData::formats(ImageData::formatEntries, sizeof(ImageData::formatEntries));
|
||||
|
||||
|
||||
StringMap<ImageData::EncodedFormat, ImageData::ENCODED_MAX_ENUM>::Entry ImageData::encodedFormatEntries[] =
|
||||
{
|
||||
{"tga", ENCODED_TGA},
|
||||
|
||||
@@ -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<Format, FORMAT_MAX_ENUM>::Entry formatEntries[];
|
||||
static StringMap<Format, FORMAT_MAX_ENUM> formats;
|
||||
|
||||
static StringMap<EncodedFormat, ENCODED_MAX_ENUM>::Entry encodedFormatEntries[];
|
||||
static StringMap<EncodedFormat, ENCODED_MAX_ENUM> encodedFormats;
|
||||
|
||||
|
||||
@@ -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<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB)
|
||||
uint8 *ASTCHandler::parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &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);
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
|
||||
// Implements CompressedFormatHandler.
|
||||
virtual bool canParse(const filesystem::FileData *data);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images, size_t &dataSize, PixelFormat &format, bool &sRGB);
|
||||
|
||||
}; // ASTCHandler
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
* @return The single block of memory containing the parsed images.
|
||||
**/
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images,
|
||||
size_t &dataSize, CompressedImageData::Format &format, bool &sRGB) = 0;
|
||||
size_t &dataSize, PixelFormat &format, bool &sRGB) = 0;
|
||||
|
||||
}; // CompressedFormatHandler
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ CompressedImageData::CompressedImageData(std::list<CompressedFormatHandler *> 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.");
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -38,12 +38,12 @@ ImageData::ImageData(std::list<FormatHandler *> formatHandlers, love::filesystem
|
||||
decode(data);
|
||||
}
|
||||
|
||||
ImageData::ImageData(std::list<FormatHandler *> formatHandlers, int width, int height, Format format)
|
||||
ImageData::ImageData(std::list<FormatHandler *> 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<FormatHandler *> formatHandlers, int width, int h
|
||||
|
||||
// Set to black/transparency.
|
||||
memset(data, 0, getSize());
|
||||
|
||||
for (FormatHandler *handler : formatHandlers)
|
||||
handler->retain();
|
||||
}
|
||||
|
||||
ImageData::ImageData(std::list<FormatHandler *> formatHandlers, int width, int height, Format format, void *data, bool own)
|
||||
ImageData::ImageData(std::list<FormatHandler *> 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<FormatHandler *> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ class ImageData : public love::image::ImageData
|
||||
public:
|
||||
|
||||
ImageData(std::list<FormatHandler *> formatHandlers, love::filesystem::FileData *data);
|
||||
ImageData(std::list<FormatHandler *> formatHandlers, int width, int height, Format format = FORMAT_RGBA8);
|
||||
ImageData(std::list<FormatHandler *> formatHandlers, int width, int height, Format format, void *data, bool own);
|
||||
ImageData(std::list<FormatHandler *> formatHandlers, int width, int height, PixelFormat format = PIXELFORMAT_RGBA8);
|
||||
ImageData(std::list<FormatHandler *> 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);
|
||||
|
||||
@@ -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<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB)
|
||||
uint8 *KTXHandler::parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &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<CompressedI
|
||||
header.numberOfMipmapLevels = std::max(header.numberOfMipmapLevels, 1u);
|
||||
|
||||
bool isSRGB = false;
|
||||
CompressedImageData::Format cformat = convertFormat(header.glInternalFormat, isSRGB);
|
||||
PixelFormat cformat = convertFormat(header.glInternalFormat, isSRGB);
|
||||
|
||||
if (cformat == CompressedImageData::FORMAT_UNKNOWN)
|
||||
if (cformat == PIXELFORMAT_UNKNOWN)
|
||||
throw love::Exception("Unsupported image format in KTX file.");
|
||||
|
||||
if (header.numberOfArrayElements > 0)
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
// Implements CompressedFormatHandler.
|
||||
virtual bool canParse(const filesystem::FileData *data);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images, size_t &dataSize, PixelFormat &format, bool &sRGB);
|
||||
|
||||
}; // KTXHandler
|
||||
|
||||
|
||||
@@ -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<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB)
|
||||
uint8 *PKMHandler::parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &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<CompressedI
|
||||
header.widthBig = swap16big(header.widthBig);
|
||||
header.heightBig = swap16big(header.heightBig);
|
||||
|
||||
CompressedImageData::Format cformat = convertFormat(header.textureFormatBig);
|
||||
PixelFormat cformat = convertFormat(header.textureFormatBig);
|
||||
|
||||
if (cformat == CompressedImageData::FORMAT_UNKNOWN)
|
||||
if (cformat == PIXELFORMAT_UNKNOWN)
|
||||
throw love::Exception("Could not parse PKM file: unsupported texture format.");
|
||||
|
||||
// The rest of the file after the header is all texture data.
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
// Implements CompressedFormatHandler.
|
||||
virtual bool canParse(const filesystem::FileData *data);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images, size_t &dataSize, PixelFormat &format, bool &sRGB);
|
||||
|
||||
}; // PKMHandler
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB)
|
||||
uint8 *PVRHandler::parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &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<CompressedI
|
||||
PVRV3PixelFormat pixelformat = (PVRV3PixelFormat) header3.pixelFormat;
|
||||
PVRV3ChannelType channeltype = (PVRV3ChannelType) header3.channelType;
|
||||
|
||||
CompressedImageData::Format cformat = convertFormat(pixelformat, channeltype);
|
||||
PixelFormat cformat = convertFormat(pixelformat, channeltype);
|
||||
|
||||
if (cformat == CompressedImageData::FORMAT_UNKNOWN)
|
||||
if (cformat == PIXELFORMAT_UNKNOWN)
|
||||
throw love::Exception("Could not parse PVR file: unsupported image format.");
|
||||
|
||||
size_t totalsize = 0;
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
|
||||
// Implements CompressedFormatHandler.
|
||||
virtual bool canParse(const filesystem::FileData *data);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images, size_t &dataSize, PixelFormat &format, bool &sRGB);
|
||||
|
||||
}; // PVRHandler
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB)
|
||||
uint8 *DDSHandler::parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &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<CompressedI
|
||||
|
||||
texformat = convertFormat(parser.getFormat(), isSRGB);
|
||||
|
||||
if (texformat == CompressedImageData::FORMAT_UNKNOWN)
|
||||
if (texformat == PIXELFORMAT_UNKNOWN)
|
||||
throw love::Exception("Could not parse compressed data: Unsupported format.");
|
||||
|
||||
if (parser.getMipmapCount() == 0)
|
||||
@@ -101,37 +101,37 @@ uint8 *DDSHandler::parse(filesystem::FileData *filedata, std::vector<CompressedI
|
||||
return data;
|
||||
}
|
||||
|
||||
CompressedImageData::Format DDSHandler::convertFormat(dds::Format ddsformat, bool &sRGB)
|
||||
PixelFormat DDSHandler::convertFormat(dds::Format ddsformat, bool &sRGB)
|
||||
{
|
||||
sRGB = false;
|
||||
|
||||
switch (ddsformat)
|
||||
{
|
||||
case dds::FORMAT_DXT1:
|
||||
return CompressedImageData::FORMAT_DXT1;
|
||||
return PIXELFORMAT_DXT1;
|
||||
case dds::FORMAT_DXT3:
|
||||
return CompressedImageData::FORMAT_DXT3;
|
||||
return PIXELFORMAT_DXT3;
|
||||
case dds::FORMAT_DXT5:
|
||||
return CompressedImageData::FORMAT_DXT5;
|
||||
return PIXELFORMAT_DXT5;
|
||||
case dds::FORMAT_BC4:
|
||||
return CompressedImageData::FORMAT_BC4;
|
||||
return PIXELFORMAT_BC4;
|
||||
case dds::FORMAT_BC4s:
|
||||
return CompressedImageData::FORMAT_BC4s;
|
||||
return PIXELFORMAT_BC4s;
|
||||
case dds::FORMAT_BC5:
|
||||
return CompressedImageData::FORMAT_BC5;
|
||||
return PIXELFORMAT_BC5;
|
||||
case dds::FORMAT_BC5s:
|
||||
return CompressedImageData::FORMAT_BC5s;
|
||||
return PIXELFORMAT_BC5s;
|
||||
case dds::FORMAT_BC6H:
|
||||
return CompressedImageData::FORMAT_BC6H;
|
||||
return PIXELFORMAT_BC6H;
|
||||
case dds::FORMAT_BC6Hs:
|
||||
return CompressedImageData::FORMAT_BC6Hs;
|
||||
return PIXELFORMAT_BC6Hs;
|
||||
case dds::FORMAT_BC7:
|
||||
return CompressedImageData::FORMAT_BC7;
|
||||
return PIXELFORMAT_BC7;
|
||||
case dds::FORMAT_BC7srgb:
|
||||
sRGB = true;
|
||||
return CompressedImageData::FORMAT_BC7;
|
||||
return PIXELFORMAT_BC7;
|
||||
default:
|
||||
return CompressedImageData::FORMAT_UNKNOWN;
|
||||
return PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,11 +48,11 @@ public:
|
||||
|
||||
// Implements CompressedFormatHandler.
|
||||
virtual bool canParse(const filesystem::FileData *data);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &images, size_t &dataSize, CompressedImageData::Format &format, bool &sRGB);
|
||||
virtual uint8 *parse(filesystem::FileData *filedata, std::vector<CompressedImageData::SubImage> &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
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user