Minimum required opengl version is now OpenGL 3.3 / OpenGL ES 3.0.

This commit is contained in:
Sasha Szpakowski
2024-06-19 18:08:09 -03:00
parent 5112345893
commit 54a31ec615
17 changed files with 121 additions and 623 deletions
-3
View File
@@ -86,9 +86,6 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataDe
if (indexbuffer)
{
if (!caps.features[Graphics::FEATURE_INDEX_BUFFER_32BIT] && format == DATAFORMAT_UINT32)
throw love::Exception("32 bit index buffer formats are not supported on this system.");
if (format != DATAFORMAT_UINT16 && format != DATAFORMAT_UINT32)
throw love::Exception("Index buffers only support uint16 and uint32 data types.");
-15
View File
@@ -1604,9 +1604,6 @@ void Graphics::captureScreenshot(const ScreenshotInfo &info)
void Graphics::copyBuffer(Buffer *source, Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
{
if (!capabilities.features[FEATURE_COPY_BUFFER])
throw love::Exception("Buffer copying is not supported on this system.");
Range sourcerange(sourceoffset, size);
Range destrange(destoffset, size);
@@ -1640,9 +1637,6 @@ void Graphics::copyTextureToBuffer(Texture *source, Buffer *dest, int slice, int
{
if (!source->isRenderTarget())
throw love::Exception("Copying a non-render target Texture to a Buffer is not supported on this system.");
if (!capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER])
throw love::Exception("Copying a render target Texture to a Buffer is not supported on this system.");
}
PixelFormat format = source->getPixelFormat();
@@ -1728,9 +1722,6 @@ void Graphics::copyTextureToBuffer(Texture *source, Buffer *dest, int slice, int
void Graphics::copyBufferToTexture(Buffer *source, Texture *dest, size_t sourceoffset, int sourcewidth, int slice, int mipmap, const Rect &rect)
{
if (!capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE])
throw love::Exception("Copying a Buffer to a Texture is not supported on this system.");
if (source->getDataUsage() == BUFFERDATAUSAGE_READBACK)
throw love::Exception("Buffers created with 'readback' data usage cannot be used as a copy source.");
@@ -2914,7 +2905,6 @@ STRINGMAP_CLASS_BEGIN(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, f
{ "multirendertargetformats", Graphics::FEATURE_MULTI_RENDER_TARGET_FORMATS },
{ "clampzero", Graphics::FEATURE_CLAMP_ZERO },
{ "clampone", Graphics::FEATURE_CLAMP_ONE },
{ "blendminmax", Graphics::FEATURE_BLEND_MINMAX },
{ "lighten", Graphics::FEATURE_LIGHTEN },
{ "fullnpot", Graphics::FEATURE_FULL_NPOT },
{ "pixelshaderhighp", Graphics::FEATURE_PIXEL_SHADER_HIGHP },
@@ -2923,12 +2913,7 @@ STRINGMAP_CLASS_BEGIN(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, f
{ "glsl4", Graphics::FEATURE_GLSL4 },
{ "instancing", Graphics::FEATURE_INSTANCING },
{ "texelbuffer", Graphics::FEATURE_TEXEL_BUFFER },
{ "indexbuffer32bit", Graphics::FEATURE_INDEX_BUFFER_32BIT },
{ "copybuffer", Graphics::FEATURE_COPY_BUFFER },
{ "copybuffertotexture", Graphics::FEATURE_COPY_BUFFER_TO_TEXTURE },
{ "copytexturetobuffer", Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER },
{ "copyrendertargettobuffer", Graphics::FEATURE_COPY_RENDER_TARGET_TO_BUFFER },
{ "mipmaprange", Graphics::FEATURE_MIPMAP_RANGE },
{ "indirectdraw", Graphics::FEATURE_INDIRECT_DRAW },
}
STRINGMAP_CLASS_END(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, feature)
+6 -12
View File
@@ -147,24 +147,18 @@ public:
enum Feature
{
FEATURE_MULTI_RENDER_TARGET_FORMATS,
FEATURE_MULTI_RENDER_TARGET_FORMATS, // Deprecated
FEATURE_CLAMP_ZERO,
FEATURE_CLAMP_ONE,
FEATURE_BLEND_MINMAX,
FEATURE_LIGHTEN, // Deprecated
FEATURE_FULL_NPOT,
FEATURE_PIXEL_SHADER_HIGHP,
FEATURE_SHADER_DERIVATIVES,
FEATURE_GLSL3,
FEATURE_FULL_NPOT, // Deprecated
FEATURE_PIXEL_SHADER_HIGHP, // Deprecated
FEATURE_SHADER_DERIVATIVES, // Deprecated
FEATURE_GLSL3, // Deprecated
FEATURE_GLSL4,
FEATURE_INSTANCING,
FEATURE_INSTANCING, // Deprecated
FEATURE_TEXEL_BUFFER,
FEATURE_INDEX_BUFFER_32BIT,
FEATURE_COPY_BUFFER,
FEATURE_COPY_BUFFER_TO_TEXTURE,
FEATURE_COPY_TEXTURE_TO_BUFFER,
FEATURE_COPY_RENDER_TARGET_TO_BUFFER,
FEATURE_MIPMAP_RANGE,
FEATURE_INDIRECT_DRAW,
FEATURE_MAX_ENUM
};
+1 -6
View File
@@ -40,9 +40,6 @@ GraphicsReadback::GraphicsReadback(Graphics *gfx, ReadbackMethod method, Buffer
{
const auto &caps = gfx->getCapabilities();
if (!caps.features[Graphics::FEATURE_COPY_BUFFER])
throw love::Exception("readbackBuffer is not supported on this system (buffer copy support is required).");
if (offset + size > buffer->getSize())
throw love::Exception("Invalid offset or size for the given Buffer.");
@@ -94,9 +91,7 @@ GraphicsReadback::GraphicsReadback(Graphics *gfx, ReadbackMethod method, Texture
if (method == READBACK_ASYNC)
{
if (isRT && !caps.features[Graphics::FEATURE_COPY_RENDER_TARGET_TO_BUFFER])
throw love::Exception("readbackTextureAsync is not supported on this system.");
else if (!isRT && !caps.features[Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER])
if (!isRT && !caps.features[Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER])
throw love::Exception("readbackTextureAsync with a non-render-target texture is not supported on this system.");
}
else
+2 -26
View File
@@ -51,11 +51,7 @@ static const char global_syntax[] = R"(
#define mediump
#define highp
#endif
#if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH)
#define LOVE_HIGHP_OR_MEDIUMP highp
#else
#define LOVE_HIGHP_OR_MEDIUMP mediump
#endif
#define LOVE_HIGHP_OR_MEDIUMP highp
#if __VERSION__ >= 300
#define LOVE_IO_LOCATION(x) layout (location = x)
#else
@@ -88,15 +84,7 @@ static const char global_syntax[] = R"(
)";
static const char render_uniforms[] = R"(
// According to the GLSL ES 1.0 spec, uniform precision must match between stages,
// but we can't guarantee that highp is always supported in fragment shaders...
// We *really* don't want to use mediump for these in vertex shaders though.
#ifdef LOVE_SPLIT_UNIFORMS_PER_DRAW
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[11];
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw2[1];
#else
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[12];
#endif
uniform highp vec4 love_UniformsPerDraw[12];
// Older GLSL doesn't support preprocessor line continuations...
#define TransformMatrix mat4(love_UniformsPerDraw[0], love_UniformsPerDraw[1], love_UniformsPerDraw[2], love_UniformsPerDraw[3])
@@ -105,16 +93,9 @@ uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[12];
#define CurrentDPIScale (love_UniformsPerDraw[8].x)
#define ConstantPointSize (love_UniformsPerDraw[8].y)
#define love_ClipSpaceParams (love_UniformsPerDraw[9])
#define ConstantColor (love_UniformsPerDraw[10])
#ifdef LOVE_SPLIT_UNIFORMS_PER_DRAW
#define love_ScreenSize (love_UniformsPerDraw2[0])
#else
#define love_ScreenSize (love_UniformsPerDraw[11])
#endif
// Alternate names
#define ViewSpaceFromLocal TransformMatrix
@@ -667,11 +648,6 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
if (info.usesMRT)
ss << "#define LOVE_MULTI_RENDER_TARGETS 1\n";
// Note: backends are expected to handle this situation if highp is ever
// conditional in that backend.
if (!gfx->getCapabilities().features[Graphics::FEATURE_PIXEL_SHADER_HIGHP])
ss << "#define LOVE_SPLIT_UNIFORMS_PER_DRAW 1\n";
for (const auto &def : options.defines)
ss << "#define " + def.first + " " + def.second + "\n";
-3
View File
@@ -253,9 +253,6 @@ Texture::Texture(Graphics *gfx, const Settings &settings, const Slices *slices)
mipmapCount = std::min(totalMipmapCount, requestedMipmapCount);
else
mipmapCount = totalMipmapCount;
if (mipmapCount != totalMipmapCount && !caps.features[Graphics::FEATURE_MIPMAP_RANGE])
throw love::Exception("Custom mipmap ranges for a texture are not supported on this system (%d mipmap levels are required but only %d levels were provided.)", totalMipmapCount, mipmapCount);
}
const char *miperr = nullptr;
+1 -7
View File
@@ -2227,7 +2227,6 @@ void Graphics::initCapabilities()
if (families.mac[1] || families.macCatalyst[1] || families.apple[7])
capabilities.features[FEATURE_CLAMP_ONE] = true;
}
capabilities.features[FEATURE_BLEND_MINMAX] = true;
capabilities.features[FEATURE_LIGHTEN] = true;
capabilities.features[FEATURE_FULL_NPOT] = true;
capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
@@ -2236,19 +2235,14 @@ void Graphics::initCapabilities()
capabilities.features[FEATURE_GLSL4] = true;
capabilities.features[FEATURE_INSTANCING] = true;
capabilities.features[FEATURE_TEXEL_BUFFER] = true;
capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = true;
capabilities.features[FEATURE_COPY_BUFFER] = true;
capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = true;
capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = true;
capabilities.features[FEATURE_MIPMAP_RANGE] = true;
if (families.mac[1] || families.macCatalyst[1] || families.apple[3])
capabilities.features[FEATURE_INDIRECT_DRAW] = true;
else
capabilities.features[FEATURE_INDIRECT_DRAW] = false;
static_assert(FEATURE_MAX_ENUM == 19, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
capabilities.limits[LIMIT_POINT_SIZE] = 511;
+1 -5
View File
@@ -196,11 +196,7 @@ void *Buffer::map(MapType map, size_t offset, size_t size)
if (map == MAP_READ_ONLY)
{
gl.bindBuffer(mapUsage, buffer);
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0)
data = (char *) glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
else if (GLAD_VERSION_1_1)
data = (char *) glMapBuffer(target, GL_READ_ONLY) + offset;
data = (char *) glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
}
else if (ownsMemoryMap)
{
+24 -77
View File
@@ -225,14 +225,6 @@ void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixe
if (msaa > 1)
useinternalbackbuffer = true;
// Our internal backbuffer code needs glBlitFramebuffer.
if (!(GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object || GLAD_ES_VERSION_3_0
|| GLAD_EXT_framebuffer_blit || GLAD_ANGLE_framebuffer_blit || GLAD_NV_framebuffer_blit))
{
if (!(msaa > 1 && GLAD_APPLE_framebuffer_multisample))
useinternalbackbuffer = false;
}
GLuint prevFBO = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
bool restoreFBO = prevFBO != getInternalBackbufferFBO();
@@ -350,8 +342,7 @@ bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth,
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
// Set whether drawing converts input from linear -> sRGB colorspace.
if (!gl.bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
|| GLAD_EXT_framebuffer_sRGB || GLAD_ES_VERSION_3_0))
if (!gl.bugs.brokenSRGB)
{
if (GLAD_VERSION_1_0 || GLAD_EXT_sRGB_write_control)
gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, isGammaCorrect());
@@ -947,7 +938,6 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
flushBatchedDraws();
bool drawbuffersmodified = false;
ncolors = std::min(ncolors, ncolorRTs);
for (int i = 0; i < ncolors; i++)
@@ -961,51 +951,25 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
ColorD c = colors[i].value;
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0)
if (datatype == PIXELFORMATTYPE_SINT)
{
if (datatype == PIXELFORMATTYPE_SINT)
{
const GLint carray[] = {(GLint)c.r, (GLint)c.g, (GLint)c.b, (GLint)c.a};
glClearBufferiv(GL_COLOR, i, carray);
}
else if (datatype == PIXELFORMATTYPE_UINT)
{
const GLuint carray[] = {(GLuint)c.r, (GLuint)c.g, (GLuint)c.b, (GLuint)c.a};
glClearBufferuiv(GL_COLOR, i, carray);
}
else
{
Colorf cf((float)c.r, (float)c.g, (float)c.b, (float)c.a);
gammaCorrectColor(cf);
const GLfloat carray[] = {cf.r, cf.g, cf.b, cf.a};
glClearBufferfv(GL_COLOR, i, carray);
}
const GLint carray[] = {(GLint)c.r, (GLint)c.g, (GLint)c.b, (GLint)c.a};
glClearBufferiv(GL_COLOR, i, carray);
}
else if (datatype == PIXELFORMATTYPE_UINT)
{
const GLuint carray[] = {(GLuint)c.r, (GLuint)c.g, (GLuint)c.b, (GLuint)c.a};
glClearBufferuiv(GL_COLOR, i, carray);
}
else
{
Colorf cf((float)c.r, (float)c.g, (float)c.b, (float)c.a);
gammaCorrectColor(cf);
glDrawBuffer(GL_COLOR_ATTACHMENT0 + i);
glClearColor(cf.r, cf.g, cf.b, cf.a);
glClear(GL_COLOR_BUFFER_BIT);
drawbuffersmodified = true;
const GLfloat carray[] = {cf.r, cf.g, cf.b, cf.a};
glClearBufferfv(GL_COLOR, i, carray);
}
}
// Revert to the expected draw buffers once we're done, if glClearBuffer
// wasn't supported.
if (drawbuffersmodified)
{
GLenum bufs[MAX_COLOR_RENDER_TARGETS];
for (int i = 0; i < ncolorRTs; i++)
bufs[i] = GL_COLOR_ATTACHMENT0 + i;
glDrawBuffers(ncolorRTs, bufs);
}
GLbitfield flags = 0;
if (stencil.hasValue)
@@ -1145,7 +1109,7 @@ GLuint Graphics::bindCachedFBO(const RenderTargets &targets)
auto attachRT = [&](const RenderTarget &rt)
{
bool renderbuffer = msaa > 1 || !rt.texture->isReadable();
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(rt.texture->getPixelFormat(), renderbuffer);
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(rt.texture->getPixelFormat());
if (fmt.framebufferAttachments[0] == GL_COLOR_ATTACHMENT0)
{
@@ -1183,14 +1147,10 @@ GLuint Graphics::bindCachedFBO(const RenderTargets &targets)
if (ncolortargets > 1)
glDrawBuffers(ncolortargets, drawbuffers);
else if (ncolortargets == 0 && hasDS && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
else if (ncolortargets == 0 && hasDS)
{
// glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3.
GLenum none = GL_NONE;
if (GLAD_ES_VERSION_3_0)
glDrawBuffers(1, &none);
else
glDrawBuffer(GL_NONE);
glDrawBuffers(1, &none);
glReadBuffer(GL_NONE);
}
@@ -1521,13 +1481,6 @@ void Graphics::setBlendState(const BlendState &blend)
if (!(blend == states.back().blend))
flushBatchedDraws();
if (blend.operationRGB == BLENDOP_MAX || blend.operationA == BLENDOP_MAX
|| blend.operationRGB == BLENDOP_MIN || blend.operationA == BLENDOP_MIN)
{
if (!capabilities.features[FEATURE_BLEND_MINMAX])
throw love::Exception("The 'min' and 'max' blend operations are not supported on this system.");
}
if (blend.enable != gl.isStateEnabled(OpenGL::ENABLE_BLEND))
gl.setEnableState(OpenGL::ENABLE_BLEND, blend.enable);
@@ -1629,26 +1582,20 @@ void Graphics::getAPIStats(int &shaderswitches) const
void Graphics::initCapabilities()
{
capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = gl.isMultiFormatMRTSupported();
capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true;
capabilities.features[FEATURE_CLAMP_ZERO] = gl.isClampZeroOneTextureWrapSupported();
capabilities.features[FEATURE_CLAMP_ONE] = gl.isClampZeroOneTextureWrapSupported();
capabilities.features[FEATURE_BLEND_MINMAX] = GLAD_VERSION_1_4 || GLAD_ES_VERSION_3_0 || GLAD_EXT_blend_minmax;
capabilities.features[FEATURE_LIGHTEN] = capabilities.features[FEATURE_BLEND_MINMAX];
capabilities.features[FEATURE_FULL_NPOT] = GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot;
capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = gl.isPixelShaderHighpSupported();
capabilities.features[FEATURE_SHADER_DERIVATIVES] = GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_standard_derivatives;
capabilities.features[FEATURE_GLSL3] = GLAD_ES_VERSION_3_0 || gl.isCoreProfile();
capabilities.features[FEATURE_LIGHTEN] = true;
capabilities.features[FEATURE_FULL_NPOT] = true;
capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
capabilities.features[FEATURE_SHADER_DERIVATIVES] = true;
capabilities.features[FEATURE_GLSL3] = true;
capabilities.features[FEATURE_GLSL4] = GLAD_ES_VERSION_3_1 || (gl.isCoreProfile() && GLAD_VERSION_4_3);
capabilities.features[FEATURE_INSTANCING] = gl.isInstancingSupported();
capabilities.features[FEATURE_INSTANCING] = true;
capabilities.features[FEATURE_TEXEL_BUFFER] = gl.isBufferUsageSupported(BUFFERUSAGE_TEXEL);
capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_element_index_uint;
capabilities.features[FEATURE_COPY_BUFFER] = gl.isCopyBufferSupported();
capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = gl.isCopyBufferToTextureSupported();
capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = gl.isCopyTextureToBufferSupported();
capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = gl.isCopyRenderTargetToBufferSupported();
capabilities.features[FEATURE_MIPMAP_RANGE] = GLAD_VERSION_1_2 || GLAD_ES_VERSION_3_0;
capabilities.features[FEATURE_INDIRECT_DRAW] = capabilities.features[FEATURE_GLSL4];
static_assert(FEATURE_MAX_ENUM == 19, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
capabilities.limits[LIMIT_POINT_SIZE] = gl.getMaxPointSize();
capabilities.limits[LIMIT_TEXTURE_SIZE] = gl.getMax2DTextureSize();
@@ -1666,7 +1613,7 @@ void Graphics::initCapabilities()
static_assert(LIMIT_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new system limit!");
for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
capabilities.textureTypes[i] = gl.isTextureTypeSupported((TextureType) i);
capabilities.textureTypes[i] = true;
for (int i = 0; i < PIXELFORMAT_MAX_ENUM; i++)
{
@@ -1708,7 +1655,7 @@ uint32 Graphics::computePixelFormatUsage(PixelFormat format, bool readable)
GLuint texture = 0;
GLuint renderbuffer = 0;
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, !readable);
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format);
GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
+59 -358
View File
@@ -130,7 +130,6 @@ OpenGL::OpenGL()
: stats()
, bugs()
, contextInitialized(false)
, pixelShaderHighpSupported(false)
, baseVertexSupported(false)
, maxAnisotropy(1.0f)
, maxLODBias(0.0f)
@@ -166,16 +165,6 @@ bool OpenGL::initContext()
bugs = {};
if (GLAD_ES_VERSION_3_0 && !GLAD_ES_VERSION_3_1)
{
const char *device = (const char *) glGetString(GL_RENDERER);
if (getVendor() == VENDOR_VIVANTE && strstr(device, "Vivante GC7000UL"))
bugs.brokenGLES3 = true;
}
if (bugs.brokenGLES3)
GLAD_ES_VERSION_3_0 = false;
if (GLAD_VERSION_3_2)
{
GLint profileMask = 0;
@@ -274,11 +263,8 @@ void OpenGL::setupContext()
setEnableState(ENABLE_SCISSOR_TEST, state.enableState[ENABLE_SCISSOR_TEST]);
setEnableState(ENABLE_FACE_CULL, state.enableState[ENABLE_FACE_CULL]);
if (!bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
|| GLAD_EXT_framebuffer_sRGB || GLAD_EXT_sRGB_write_control))
{
if (!bugs.brokenSRGB)
setEnableState(ENABLE_FRAMEBUFFER_SRGB, state.enableState[ENABLE_FRAMEBUFFER_SRGB]);
}
else
state.enableState[ENABLE_FRAMEBUFFER_SRGB] = false;
@@ -310,9 +296,7 @@ void OpenGL::setupContext()
for (int j = 0; j < TEXTURE_MAX_ENUM; j++)
{
TextureType textype = (TextureType) j;
if (isTextureTypeSupported(textype))
glBindTexture(getGLTextureType(textype), 0);
glBindTexture(getGLTextureType(textype), 0);
}
}
@@ -374,89 +358,6 @@ void OpenGL::initVendor()
void OpenGL::initOpenGLFunctions()
{
// Alias extension-suffixed framebuffer functions to core versions since
// there are so many different-named extensions that do the same things...
if (!(GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object))
{
if (GLAD_VERSION_1_0 && GLAD_EXT_framebuffer_object)
{
fp_glBindRenderbuffer = fp_glBindRenderbufferEXT;
fp_glDeleteRenderbuffers = fp_glDeleteRenderbuffersEXT;
fp_glGenRenderbuffers = fp_glGenRenderbuffersEXT;
fp_glRenderbufferStorage = fp_glRenderbufferStorageEXT;
fp_glGetRenderbufferParameteriv = fp_glGetRenderbufferParameterivEXT;
fp_glBindFramebuffer = fp_glBindFramebufferEXT;
fp_glDeleteFramebuffers = fp_glDeleteFramebuffersEXT;
fp_glGenFramebuffers = fp_glGenFramebuffersEXT;
fp_glCheckFramebufferStatus = fp_glCheckFramebufferStatusEXT;
fp_glFramebufferTexture2D = fp_glFramebufferTexture2DEXT;
fp_glFramebufferTexture3D = fp_glFramebufferTexture3DEXT;
fp_glFramebufferRenderbuffer = fp_glFramebufferRenderbufferEXT;
fp_glGetFramebufferAttachmentParameteriv = fp_glGetFramebufferAttachmentParameterivEXT;
fp_glGenerateMipmap = fp_glGenerateMipmapEXT;
}
if (GLAD_VERSION_1_0 && GLAD_EXT_texture_array)
fp_glFramebufferTextureLayer = fp_glFramebufferTextureLayerEXT;
if (GLAD_EXT_framebuffer_blit)
fp_glBlitFramebuffer = fp_glBlitFramebufferEXT;
else if (GLAD_ANGLE_framebuffer_blit)
fp_glBlitFramebuffer = fp_glBlitFramebufferANGLE;
else if (GLAD_NV_framebuffer_blit)
fp_glBlitFramebuffer = fp_glBlitFramebufferNV;
if (GLAD_EXT_framebuffer_multisample)
fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleEXT;
else if (GLAD_APPLE_framebuffer_multisample)
fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleAPPLE;
else if (GLAD_ANGLE_framebuffer_multisample)
fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleANGLE;
else if (GLAD_NV_framebuffer_multisample)
fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleNV;
}
if (isInstancingSupported() && !(GLAD_VERSION_3_3 || GLAD_ES_VERSION_3_0))
{
if (GLAD_ARB_instanced_arrays)
{
fp_glDrawArraysInstanced = fp_glDrawArraysInstancedARB;
fp_glDrawElementsInstanced = fp_glDrawElementsInstancedARB;
fp_glVertexAttribDivisor = fp_glVertexAttribDivisorARB;
}
else if (GLAD_EXT_instanced_arrays)
{
fp_glDrawArraysInstanced = fp_glDrawArraysInstancedEXT;
fp_glDrawElementsInstanced = fp_glDrawElementsInstancedEXT;
fp_glVertexAttribDivisor = fp_glVertexAttribDivisorEXT;
}
else if (GLAD_ANGLE_instanced_arrays)
{
fp_glDrawArraysInstanced = fp_glDrawArraysInstancedANGLE;
fp_glDrawElementsInstanced = fp_glDrawElementsInstancedANGLE;
fp_glVertexAttribDivisor = fp_glVertexAttribDivisorANGLE;
}
}
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
{
// The Nvidia Tegra 3 driver (used by Ouya) claims to support GL_EXT_texture_array but
// segfaults if you actually try to use it. OpenGL ES 2.0 devices should use OES_texture_3D.
// GL_EXT_texture_array is for desktops.
GLAD_EXT_texture_array = false;
if (GLAD_OES_texture_3D)
{
// Function signatures don't match, we'll have to conditionally call it
//fp_glTexImage3D = fp_glTexImage3DOES;
fp_glTexSubImage3D = fp_glTexSubImage3DOES;
fp_glCopyTexSubImage3D = fp_glCopyTexSubImage3DOES;
fp_glCompressedTexImage3D = fp_glCompressedTexImage3DOES;
fp_glCompressedTexSubImage3D = fp_glCompressedTexSubImage3DOES;
fp_glFramebufferTexture3D = fp_glFramebufferTexture3DOES;
}
}
if (!GLAD_VERSION_3_2 && !GLAD_ES_VERSION_3_2 && !GLAD_ARB_draw_elements_base_vertex)
{
if (GLAD_OES_draw_elements_base_vertex)
@@ -486,16 +387,6 @@ void OpenGL::initOpenGLFunctions()
void OpenGL::initMaxValues()
{
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
{
GLint range = 0;
GLint precision = 0;
glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, &range, &precision);
pixelShaderHighpSupported = range > 0;
}
else
pixelShaderHighpSupported = true;
baseVertexSupported = GLAD_VERSION_3_2 || GLAD_ES_VERSION_3_2 || GLAD_ARB_draw_elements_base_vertex
|| GLAD_OES_draw_elements_base_vertex || GLAD_EXT_draw_elements_base_vertex;
@@ -507,16 +398,8 @@ void OpenGL::initMaxValues()
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DTextureSize);
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
if (isTextureTypeSupported(TEXTURE_VOLUME))
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
else
max3DTextureSize = 0;
if (isTextureTypeSupported(TEXTURE_2D_ARRAY))
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureArrayLayers);
else
maxTextureArrayLayers = 0;
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureArrayLayers);
if (isBufferUsageSupported(BUFFERUSAGE_TEXEL))
glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTexelBufferSize);
@@ -549,23 +432,12 @@ void OpenGL::initMaxValues()
int maxattachments = 1;
int maxdrawbuffers = 1;
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_2_0)
{
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxattachments);
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxdrawbuffers);
}
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxattachments);
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxdrawbuffers);
maxRenderTargets = std::max(std::min(maxattachments, maxdrawbuffers), 1);
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object
|| GLAD_EXT_framebuffer_multisample || GLAD_APPLE_framebuffer_multisample
|| GLAD_ANGLE_framebuffer_multisample)
{
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
}
else
maxSamples = 1;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
@@ -794,8 +666,7 @@ GLenum OpenGL::getGLBufferDataUsage(BufferDataUsage usage)
case BUFFERDATAUSAGE_STREAM: return GL_STREAM_DRAW;
case BUFFERDATAUSAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
case BUFFERDATAUSAGE_STATIC: return GL_STATIC_DRAW;
case BUFFERDATAUSAGE_READBACK:
return (GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) ? GL_STREAM_READ : GL_STREAM_DRAW;
case BUFFERDATAUSAGE_READBACK: return GL_STREAM_READ;
default: return 0;
}
}
@@ -1285,42 +1156,27 @@ void OpenGL::setSamplerState(TextureType target, SamplerState &s)
s.maxAnisotropy = 1;
}
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0)
glTexParameterf(gltarget, GL_TEXTURE_MIN_LOD, (float)s.minLod);
glTexParameterf(gltarget, GL_TEXTURE_MAX_LOD, (float)s.maxLod);
if (s.depthSampleMode.hasValue)
{
glTexParameterf(gltarget, GL_TEXTURE_MIN_LOD, (float)s.minLod);
glTexParameterf(gltarget, GL_TEXTURE_MAX_LOD, (float)s.maxLod);
// See the comment in renderstate.h
GLenum glmode = getGLCompareMode(getReversedCompareMode(s.depthSampleMode.value));
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_FUNC, glmode);
}
else
{
s.minLod = 0;
s.maxLod = LOVE_UINT8_MAX;
}
if (isDepthCompareSampleSupported())
{
if (s.depthSampleMode.hasValue)
{
// See the comment in renderstate.h
GLenum glmode = getGLCompareMode(getReversedCompareMode(s.depthSampleMode.value));
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_FUNC, glmode);
}
else
{
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
}
else
{
s.depthSampleMode.hasValue = false;
glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
}
bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, int width, int height, int depth)
{
GLenum gltarget = getGLTextureType(target);
TextureFormat fmt = convertPixelFormat(pixelformat, false);
TextureFormat fmt = convertPixelFormat(pixelformat);
// This shouldn't be needed for glTexStorage, but some drivers don't follow
// the spec apparently.
@@ -1375,16 +1231,8 @@ bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelform
}
else if (target == TEXTURE_2D_ARRAY || target == TEXTURE_VOLUME)
{
if (target == TEXTURE_VOLUME && GLAD_ES_VERSION_2_0 && GLAD_OES_texture_3D && !GLAD_ES_VERSION_3_0)
{
glTexImage3DOES(gltarget, level, fmt.internalformat, w, h,
d, 0, fmt.externalformat, fmt.type, nullptr);
}
else
{
glTexImage3D(gltarget, level, fmt.internalformat, w, h, d,
0, fmt.externalformat, fmt.type, nullptr);
}
glTexImage3D(gltarget, level, fmt.internalformat, w, h, d,
0, fmt.externalformat, fmt.type, nullptr);
}
w = std::max(w / 2, 1);
@@ -1406,24 +1254,6 @@ bool OpenGL::isTexStorageSupported()
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_2 || GLAD_ARB_texture_storage;
}
bool OpenGL::isTextureTypeSupported(TextureType type) const
{
switch (type)
{
case TEXTURE_2D:
return true;
case TEXTURE_VOLUME:
return GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_3D;
case TEXTURE_2D_ARRAY:
return GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_array;
case TEXTURE_CUBE:
return GLAD_VERSION_1_3 || GLAD_ES_VERSION_2_0;
case TEXTURE_MAX_ENUM:
return false;
}
return false;
}
bool OpenGL::isBufferUsageSupported(BufferUsage usage) const
{
switch (usage)
@@ -1434,7 +1264,7 @@ bool OpenGL::isBufferUsageSupported(BufferUsage usage) const
case BUFFERUSAGE_TEXEL:
return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_2;
case BUFFERUSAGE_UNIFORM:
return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_0;
return true;
case BUFFERUSAGE_SHADER_STORAGE:
return (GLAD_VERSION_4_3 && isCoreProfile()) || GLAD_ES_VERSION_3_1;
case BUFFERUSAGE_INDIRECT_ARGUMENTS:
@@ -1450,24 +1280,6 @@ bool OpenGL::isClampZeroOneTextureWrapSupported() const
return GLAD_VERSION_1_3 || GLAD_EXT_texture_border_clamp || GLAD_NV_texture_border_clamp;
}
bool OpenGL::isPixelShaderHighpSupported() const
{
return pixelShaderHighpSupported;
}
bool OpenGL::isInstancingSupported() const
{
return GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_3
|| GLAD_ARB_instanced_arrays || GLAD_EXT_instanced_arrays || GLAD_ANGLE_instanced_arrays;
}
bool OpenGL::isDepthCompareSampleSupported() const
{
// Our official API only supports this in GLSL3 shaders, but unofficially
// the requirements are more lax.
return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_shadow_samplers;
}
bool OpenGL::isSamplerLODBiasSupported() const
{
return GLAD_VERSION_1_4;
@@ -1478,34 +1290,12 @@ bool OpenGL::isBaseVertexSupported() const
return baseVertexSupported;
}
bool OpenGL::isMultiFormatMRTSupported() const
{
return getMaxRenderTargets() > 1 && (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object);
}
bool OpenGL::isCopyBufferSupported() const
{
return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_0;
}
bool OpenGL::isCopyBufferToTextureSupported() const
{
// Requires pixel unpack buffer binding support.
return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0;
}
bool OpenGL::isCopyTextureToBufferSupported() const
{
// Requires glGetTextureSubImage support.
return GLAD_VERSION_4_5 || GLAD_ARB_get_texture_sub_image;
}
bool OpenGL::isCopyRenderTargetToBufferSupported() const
{
// Requires pixel pack buffer binding support.
return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0;
}
int OpenGL::getMax2DTextureSize() const
{
return std::max(max2DTextureSize, 1);
@@ -1596,7 +1386,7 @@ OpenGL::Vendor OpenGL::getVendor() const
return vendor;
}
OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool renderbuffer)
OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat)
{
TextureFormat f;
@@ -1613,8 +1403,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
switch (pixelformat)
{
case PIXELFORMAT_R8_UNORM:
if ((GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg)
&& !gl.bugs.brokenR8PixelFormat)
if (!gl.bugs.brokenR8PixelFormat)
{
f.internalformat = GL_R8;
f.externalformat = GL_RED;
@@ -1639,10 +1428,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
case PIXELFORMAT_RGBA8_sRGB:
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;
f.externalformat = GL_RGBA;
break;
case PIXELFORMAT_BGRA8_UNORM:
case PIXELFORMAT_BGRA8_sRGB:
@@ -1841,28 +1627,10 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
case PIXELFORMAT_STENCIL8:
// Prefer a combined depth/stencil buffer due to driver issues.
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object)
{
f.internalformat = GL_DEPTH24_STENCIL8;
f.externalformat = GL_DEPTH_STENCIL;
f.type = GL_UNSIGNED_INT_24_8;
f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
}
else if (GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil)
{
f.internalformat = GL_DEPTH24_STENCIL8;
f.externalformat = GL_DEPTH_STENCIL;
f.type = GL_UNSIGNED_INT_24_8;
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
f.framebufferAttachments[1] = GL_STENCIL_ATTACHMENT;
}
else
{
f.internalformat = GL_STENCIL_INDEX8;
f.externalformat = GL_STENCIL;
f.type = GL_UNSIGNED_BYTE;
f.framebufferAttachments[0] = GL_STENCIL_ATTACHMENT;
}
f.internalformat = GL_DEPTH24_STENCIL8;
f.externalformat = GL_DEPTH_STENCIL;
f.type = GL_UNSIGNED_INT_24_8;
f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
break;
case PIXELFORMAT_DEPTH16_UNORM:
@@ -1873,21 +1641,10 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
break;
case PIXELFORMAT_DEPTH24_UNORM:
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0 && !GLAD_OES_depth24 && GLAD_OES_packed_depth_stencil)
{
f.internalformat = GL_DEPTH24_STENCIL8;
f.externalformat = GL_DEPTH_STENCIL;
f.type = GL_UNSIGNED_INT_24_8;
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
f.framebufferAttachments[1] = GL_STENCIL_ATTACHMENT;
}
else
{
f.internalformat = GL_DEPTH_COMPONENT24;
f.externalformat = GL_DEPTH_COMPONENT;
f.type = GL_UNSIGNED_INT;
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
}
f.internalformat = GL_DEPTH_COMPONENT24;
f.externalformat = GL_DEPTH_COMPONENT;
f.type = GL_UNSIGNED_INT;
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
break;
case PIXELFORMAT_DEPTH32_FLOAT:
@@ -1901,15 +1658,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
f.internalformat = GL_DEPTH24_STENCIL8;
f.externalformat = GL_DEPTH_STENCIL;
f.type = GL_UNSIGNED_INT_24_8;
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object)
{
f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
}
else if (GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil)
{
f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
f.framebufferAttachments[1] = GL_STENCIL_ATTACHMENT;
}
f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
break;
case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
@@ -2111,22 +1860,6 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
break;
}
if (!isPixelFormatCompressed(pixelformat))
{
// glTexImage in OpenGL ES 2 only accepts internal format enums that
// match the external format. GLES3 doesn't have that restriction -
// except for GL_LUMINANCE_ALPHA which doesn't have a sized version in
// ES3. However we always use RG8 for PIXELFORMAT_LA8 on GLES3 so it
// doesn't matter there.
// Also note that GLES2+extension sRGB format enums are different from
// desktop GL and GLES3+ (this is handled above).
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0
&& !renderbuffer && !isTexStorageSupported())
{
f.internalformat = f.externalformat;
}
}
return f;
}
@@ -2142,28 +1875,19 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
{
case PIXELFORMAT_R8_UNORM:
case PIXELFORMAT_RG8_UNORM:
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg)
flags |= commonsample | commonrender;
else if (pixelformat == PIXELFORMAT_R8_UNORM && (GLAD_ES_VERSION_2_0 || GLAD_VERSION_1_1))
flags |= commonsample; // We'll use OpenGL's luminance format internally.
flags |= commonsample | commonrender;
if (GLAD_VERSION_4_3)
flags |= computewrite;
break;
case PIXELFORMAT_RGBA8_UNORM:
flags |= commonsample;
if (GLAD_VERSION_1_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_rgb8_rgba8 || GLAD_ARM_rgba8)
flags |= commonrender;
flags |= commonsample | commonrender;
if (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_1)
flags |= computewrite;
break;
case PIXELFORMAT_RGBA8_sRGB:
if (gl.bugs.brokenSRGB)
break;
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB)
flags |= commonsample;
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0
|| ((GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB) && (GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB)))
flags |= commonrender;
flags |= commonsample | commonrender;
break;
case PIXELFORMAT_BGRA8_UNORM:
case PIXELFORMAT_BGRA8_sRGB:
@@ -2171,9 +1895,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
break;
case PIXELFORMAT_R16_UNORM:
case PIXELFORMAT_RG16_UNORM:
if (GLAD_VERSION_3_0
|| (GLAD_VERSION_1_1 && GLAD_ARB_texture_rg)
|| (GLAD_EXT_texture_norm16 && (GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg)))
if (GLAD_VERSION_3_0 || (GLAD_EXT_texture_norm16 && GLAD_ES_VERSION_3_0))
flags |= commonsample | commonrender;
if (GLAD_VERSION_4_3)
flags |= computewrite;
@@ -2186,26 +1908,20 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
break;
case PIXELFORMAT_R16_FLOAT:
case PIXELFORMAT_RG16_FLOAT:
if (GLAD_VERSION_1_0 && (GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel && GLAD_ARB_texture_rg)))
flags |= commonsample | commonrender;
if (GLAD_ES_VERSION_3_0 || (GLAD_OES_texture_half_float && GLAD_EXT_texture_rg))
flags |= commonsample;
if ((GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float) && (GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg))
flags |= commonsample;
if (GLAD_VERSION_3_0)
flags |= commonrender;
if ((GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float) && GLAD_ES_VERSION_3_0)
flags |= commonrender;
if (!(GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear))
flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
if (GLAD_VERSION_4_3)
flags |= computewrite;
break;
case PIXELFORMAT_RGBA16_FLOAT:
if (GLAD_VERSION_3_0 || (GLAD_VERSION_1_0 && GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel))
flags |= commonsample | commonrender;
if (GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float)
flags |= commonsample;
flags |= commonsample;
if (GLAD_VERSION_3_0)
flags |= commonrender;
if (GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float)
flags |= commonrender;
if (!(GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear))
flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
if (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_1)
flags |= computewrite;
break;
@@ -2214,22 +1930,20 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
flags |= computewrite;
// Fallthrough.
case PIXELFORMAT_RG32_FLOAT:
if (GLAD_VERSION_3_0 || (GLAD_VERSION_1_0 && GLAD_ARB_texture_float && GLAD_ARB_texture_rg))
flags |= commonsample | commonrender;
if (GLAD_ES_VERSION_3_0 || (GLAD_OES_texture_float && GLAD_EXT_texture_rg))
flags |= commonsample;
flags |= commonsample;
if (GLAD_VERSION_3_0)
flags |= commonrender;
if (GLAD_EXT_color_buffer_float)
flags |= commonrender;
if (!(GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear))
if (!(GLAD_VERSION_1_1 || GLAD_OES_texture_float_linear))
flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
if (GLAD_VERSION_4_3)
flags |= computewrite;
break;
case PIXELFORMAT_RGBA32_FLOAT:
if (GLAD_VERSION_3_0 || (GLAD_VERSION_1_0 && GLAD_ARB_texture_float))
flags |= commonsample | commonrender;
if (GLAD_ES_VERSION_3_0 || GLAD_OES_texture_float)
flags |= commonsample;
flags |= commonsample;
if (GLAD_VERSION_3_0)
flags |= commonrender;
if (GLAD_EXT_color_buffer_float)
flags |= commonrender;
if (!(GLAD_VERSION_1_1 || GLAD_OES_texture_float_linear))
@@ -2256,8 +1970,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
case PIXELFORMAT_RG32_UINT:
case PIXELFORMAT_RGBA32_INT:
case PIXELFORMAT_RGBA32_UINT:
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0)
flags |= PIXELFORMATUSAGEFLAGS_SAMPLE | PIXELFORMATUSAGEFLAGS_RENDERTARGET;
flags |= PIXELFORMATUSAGEFLAGS_SAMPLE | PIXELFORMATUSAGEFLAGS_RENDERTARGET;
if (GLAD_VERSION_4_3)
flags |= computewrite;
if (GLAD_ES_VERSION_3_1)
@@ -2293,8 +2006,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
flags |= commonsample | commonrender;
break;
case PIXELFORMAT_RGB10A2_UNORM:
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0)
flags |= commonsample | commonrender;
flags |= commonsample | commonrender;
if (GLAD_VERSION_4_3)
flags |= computewrite;
break;
@@ -2314,31 +2026,20 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
break;
case PIXELFORMAT_DEPTH16_UNORM:
flags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
if (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_depth_texture)
flags |= commonsample;
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
break;
case PIXELFORMAT_DEPTH24_UNORM:
if (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_depth24 || GLAD_OES_depth_texture)
flags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
if (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || (GLAD_OES_depth_texture && (GLAD_OES_depth24 || GLAD_OES_depth_texture)))
flags |= commonsample;
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
break;
case PIXELFORMAT_DEPTH24_UNORM_STENCIL8:
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil)
flags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_packed_depth_stencil || (GLAD_OES_depth_texture && GLAD_OES_packed_depth_stencil))
flags |= commonsample;
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
break;
case PIXELFORMAT_DEPTH32_FLOAT:
case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_depth_buffer_float)
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
break;
case PIXELFORMAT_DXT1_UNORM:
@@ -2386,7 +2087,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
break;
case PIXELFORMAT_ETC1_UNORM:
// ETC2 support guarantees ETC1 support as well.
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility || GLAD_OES_compressed_ETC1_RGB8_texture)
if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility)
flags |= commonsample;
break;
case PIXELFORMAT_ETC2_RGB_UNORM:
+1 -17
View File
@@ -200,13 +200,6 @@ public:
**/
bool brokenSRGB;
/**
* Some Android graphics drivers claim to support GLES3.0 but have bugs
* with certain aspects that users expect to work. For example:
* https://github.com/love2d/love-android/issues/204
**/
bool brokenGLES3;
/**
* Other bugs which have workarounds that don't use conditional code at
* the moment:
@@ -369,19 +362,11 @@ public:
**/
bool rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, int width, int height, int depth = 1);
bool isTextureTypeSupported(TextureType type) const;
bool isBufferUsageSupported(BufferUsage usage) const;
bool isClampZeroOneTextureWrapSupported() const;
bool isPixelShaderHighpSupported() const;
bool isInstancingSupported() const;
bool isDepthCompareSampleSupported() const;
bool isSamplerLODBiasSupported() const;
bool isBaseVertexSupported() const;
bool isMultiFormatMRTSupported() const;
bool isCopyBufferSupported() const;
bool isCopyBufferToTextureSupported() const;
bool isCopyTextureToBufferSupported() const;
bool isCopyRenderTargetToBufferSupported() const;
/**
* Returns the maximum supported width or height of a texture.
@@ -461,7 +446,7 @@ public:
static GLint getGLWrapMode(SamplerState::WrapMode wmode);
static GLint getGLCompareMode(CompareMode mode);
static TextureFormat convertPixelFormat(PixelFormat pixelformat, bool renderbuffer);
static TextureFormat convertPixelFormat(PixelFormat pixelformat);
static bool isTexStorageSupported();
static uint32 getPixelFormatUsageFlags(PixelFormat pixelformat);
@@ -481,7 +466,6 @@ private:
bool contextInitialized;
bool pixelShaderHighpSupported;
bool baseVertexSupported;
float maxAnisotropy;
+4 -28
View File
@@ -41,7 +41,6 @@ namespace opengl
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const CompileOptions &options)
: love::graphics::Shader(stages, options)
, program(0)
, splitUniformsPerDraw(false)
, builtinUniforms()
, builtinUniformInfo()
{
@@ -158,7 +157,7 @@ void Shader::mapActiveUniforms()
else if ((u.access & ACCESS_READ) != 0)
binding.access = GL_READ_ONLY;
auto fmt = OpenGL::convertPixelFormat(u.storageTextureFormat, false);
auto fmt = OpenGL::convertPixelFormat(u.storageTextureFormat);
binding.internalFormat = fmt.internalformat;
for (int i = 0; i < u.count; i++)
@@ -283,11 +282,6 @@ bool Shader::loadVolatile()
{
OpenGL::TempDebugGroup debuggroup("Shader load");
// love::graphics::Shader sets up the shader code-side of this.
auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
if (gfx != nullptr)
splitUniformsPerDraw = !gfx->getCapabilities().features[Graphics::FEATURE_PIXEL_SHADER_HIGHP];
// zero out active texture list
textureUnits.clear();
textureUnits.push_back(TextureUnit());
@@ -813,27 +807,9 @@ void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW,
data.constantColor = gfx->getColor();
gammaCorrectColor(data.constantColor);
// This branch is to avoid always declaring the whole array as highp in the
// vertex shader and mediump in the pixel shader for love's default shaders,
// on systems that don't support highp in pixel shaders. The default shaders
// use the transform matrices in vertex shaders and screen size params in
// pixel shaders. If there's a single array containing both and each shader
// stage declares a different precision, that's a compile error.
if (splitUniformsPerDraw)
{
GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
if (location >= 0)
glUniform4fv(location, 11, (const GLfloat *) &data);
GLint location2 = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW_2];
if (location2 >= 0)
glUniform4fv(location2, 1, (const GLfloat *) &data.screenSizeParams);
}
else
{
GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
if (location >= 0)
glUniform4fv(location, 12, (const GLfloat *) &data);
}
GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
if (location >= 0)
glUniform4fv(location, 12, (const GLfloat *) &data);
}
} // opengl
-2
View File
@@ -106,8 +106,6 @@ private:
// volatile
GLuint program;
bool splitUniformsPerDraw;
// Location values for any built-in uniform variables.
GLint builtinUniforms[BUILTIN_MAX_ENUM];
UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];
+13 -39
View File
@@ -45,18 +45,14 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
if (texture != 0)
{
if (isPixelFormatDepthStencil(format) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
if (isPixelFormatDepthStencil(format))
{
// glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3.
GLenum none = GL_NONE;
if (GLAD_ES_VERSION_3_0)
glDrawBuffers(1, &none);
else
glDrawBuffer(GL_NONE);
glDrawBuffers(1, &none);
glReadBuffer(GL_NONE);
}
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false);
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format);
int faces = texType == TEXTURE_CUBE ? 6 : 1;
@@ -124,7 +120,7 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
static GLenum newRenderbuffer(int width, int height, int &samples, PixelFormat pixelformat, GLuint &buffer)
{
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(pixelformat, true);
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(pixelformat);
GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
@@ -133,14 +129,10 @@ static GLenum newRenderbuffer(int width, int height, int &samples, PixelFormat p
glGenFramebuffers(1, &fbo);
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, fbo);
if (isPixelFormatDepthStencil(pixelformat) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
if (isPixelFormatDepthStencil(pixelformat))
{
// glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3.
GLenum none = GL_NONE;
if (GLAD_ES_VERSION_3_0)
glDrawBuffers(1, &none);
else
glDrawBuffer(GL_NONE);
glDrawBuffers(1, &none);
glReadBuffer(GL_NONE);
}
@@ -278,7 +270,7 @@ void Texture::createTexture()
if (parentView.texture != this)
{
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format, false);
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format);
Texture *basetex = (Texture *) parentView.texture;
int layers = texType == TEXTURE_CUBE ? 6 : getLayerCount();
@@ -317,14 +309,14 @@ void Texture::createTexture()
gl.rawTexStorage(texType, mipcount, format, pixelWidth, pixelHeight, texType == TEXTURE_VOLUME ? depth : layers);
// rawTexStorage handles this for uncompressed textures.
if (isCompressed() && (GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0))
if (isCompressed())
glTexParameteri(gltype, GL_TEXTURE_MAX_LEVEL, mipcount - 1);
int w = pixelWidth;
int h = pixelHeight;
int d = depth;
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format, false);
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format);
for (int mip = 0; mip < mipcount; mip++)
{
@@ -413,14 +405,6 @@ bool Texture::loadVolatile()
OpenGL::TempDebugGroup debuggroup("Texture load");
// NPOT textures don't support mipmapping without full NPOT support.
if ((GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot))
&& (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight)))
{
mipmapCount = 1;
samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NONE;
}
actualSamples = std::max(1, std::min(getRequestedMSAA(), gl.getMaxSamples()));
while (glGetError() != GL_NO_ERROR); // Clear errors.
@@ -512,7 +496,7 @@ void Texture::uploadByteData(const void *data, size_t size, int level, int slice
gl.bindTextureToUnit(this, 0, false);
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false);
OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format);
GLenum gltarget = OpenGL::getGLTextureType(texType);
if (texType == TEXTURE_CUBE)
@@ -555,12 +539,12 @@ void Texture::generateMipmapsInternal()
void Texture::readbackInternal(int slice, int mipmap, const Rect &rect, int destwidth, size_t size, void *dest)
{
// Not supported in GL with compressed textures...
if ((GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) && !isCompressed())
if (!isCompressed())
glPixelStorei(GL_PACK_ROW_LENGTH, destwidth);
gl.bindTextureToUnit(this, 0, false);
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format, false);
OpenGL::TextureFormat fmt = gl.convertPixelFormat(format);
if (gl.isCopyTextureToBufferSupported())
{
@@ -589,7 +573,7 @@ void Texture::readbackInternal(int slice, int mipmap, const Rect &rect, int dest
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, current_fbo);
}
if ((GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) && !isCompressed())
if (!isCompressed())
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
}
@@ -630,18 +614,8 @@ void Texture::copyToBuffer(love::graphics::Buffer *dest, int slice, int mipmap,
void Texture::setSamplerState(const SamplerState &s)
{
if (s.depthSampleMode.hasValue && !gl.isDepthCompareSampleSupported())
throw love::Exception("Depth comparison sampling in shaders is not supported on this system.");
samplerState = validateSamplerState(s);
// If we only have limited NPOT support then the wrap mode must be CLAMP.
if ((GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot))
&& (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight) || depth != nextP2(depth)))
{
samplerState.wrapU = samplerState.wrapV = samplerState.wrapW = SamplerState::WRAP_CLAMP;
}
gl.bindTextureToUnit(this, 0, false);
gl.setSamplerState(texType, samplerState);
}
+4 -9
View File
@@ -739,7 +739,6 @@ void Graphics::initCapabilities()
capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true;
capabilities.features[FEATURE_CLAMP_ZERO] = true;
capabilities.features[FEATURE_CLAMP_ONE] = true;
capabilities.features[FEATURE_BLEND_MINMAX] = true;
capabilities.features[FEATURE_LIGHTEN] = true;
capabilities.features[FEATURE_FULL_NPOT] = true;
capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
@@ -748,14 +747,9 @@ void Graphics::initCapabilities()
capabilities.features[FEATURE_GLSL4] = true;
capabilities.features[FEATURE_INSTANCING] = true;
capabilities.features[FEATURE_TEXEL_BUFFER] = true;
capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = true;
capabilities.features[FEATURE_COPY_BUFFER] = true;
capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = true;
capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = true;
capabilities.features[FEATURE_MIPMAP_RANGE] = true;
capabilities.features[FEATURE_INDIRECT_DRAW] = true;
static_assert(FEATURE_MAX_ENUM == 19, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
VkPhysicalDeviceProperties properties;
vkGetPhysicalDeviceProperties(physicalDevice, &properties);
@@ -1410,7 +1404,7 @@ graphics::Shader::BuiltinUniformData Graphics::getCurrentBuiltinUniformData()
data.projectionMatrix = getDeviceProjection();
data.scaleParams.x = (float) getCurrentDPIScale();
data.scaleParams.y = getPointSize();;
data.scaleParams.y = getPointSize();
// Flip y to convert input y-up [-1, 1] to vulkan's y-down [-1, 1].
// Convert input z [-1, 1] to vulkan [0, 1].
@@ -2809,7 +2803,8 @@ VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration &confi
return graphicsPipeline;
}
void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration) {
void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration)
{
auto it = graphicsPipelines.find(configuration);
if (it != graphicsPipelines.end())
{
+2 -12
View File
@@ -259,9 +259,6 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
// Do we want a debug context?
bool debug = love::graphics::isDebugEnabled();
const char *preferGL2hint = SDL_GetHint("LOVE_GRAPHICS_USE_GL2");
bool preferGL2 = (preferGL2hint != nullptr && preferGL2hint[0] != '0');
const char *preferGL3hint = SDL_GetHint("LOVE_GRAPHICS_USE_GL3");
bool preferGL3 = (preferGL3hint != nullptr && preferGL3hint[0] != '0');
@@ -269,22 +266,15 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
{
{4, 3, false, debug},
{3, 3, false, debug},
{2, 1, false, debug},
};
std::vector<ContextAttribs> glescontexts =
{
{3, 2, true, debug},
{3, 0, true, debug},
{2, 0, true, debug}
};
if (preferGL2)
{
std::swap(glcontexts[0], glcontexts[2]);
std::swap(glescontexts[0], glescontexts[2]);
}
else if (preferGL3)
if (preferGL3)
{
std::swap(glcontexts[0], glcontexts[1]);
std::swap(glescontexts[0], glescontexts[1]);
@@ -458,7 +448,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
if (failed)
{
std::string title = "Unable to create renderer";
std::string message = "This program requires a graphics card and video drivers which support OpenGL 2.1 or OpenGL ES 2.";
std::string message = "This program requires a graphics card and video drivers which support OpenGL 3.3 or OpenGL ES 3.0.";
if (!glversion.empty())
message += "\n\nDetected OpenGL version:\n" + glversion;
+3 -4
View File
@@ -2805,10 +2805,9 @@ love.test.graphics.getSupported = function(test)
-- table match what the documentation lists
local gfs = {
'clampzero', 'lighten', 'glsl3', 'instancing', 'fullnpot',
'pixelshaderhighp', 'shaderderivatives', 'indirectdraw', 'mipmaprange',
'copyrendertargettobuffer', 'copytexturetobuffer', 'copybuffer',
'copybuffertotexture', 'indexbuffer32bit', 'multirendertargetformats',
'clampone', 'blendminmax', 'glsl4'
'pixelshaderhighp', 'shaderderivatives', 'indirectdraw',
'copytexturetobuffer', 'multirendertargetformats',
'clampone', 'glsl4'
}
local features = love.graphics.getSupported()
for g=1,#gfs do