mirror of
https://github.com/love2d/love.git
synced 2026-08-15 15:51:12 +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:
@@ -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 },
|
||||
|
||||
Reference in New Issue
Block a user