diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index f2fc3b11f..b54ff62c6 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -605,10 +605,10 @@ void Graphics::setRenderTargets(const RenderTargets &rts) return; } - if (rtcount > capabilities.limits[LIMIT_MULTI_CANVAS]) + if (rtcount > capabilities.limits[LIMIT_RENDER_TARGETS]) throw love::Exception("This system can't simultaneously render to %d textures.", rtcount); - bool multiformatsupported = capabilities.features[FEATURE_MULTI_CANVAS_FORMATS]; + bool multiformatsupported = capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS]; PixelFormat firstcolorformat = PIXELFORMAT_UNKNOWN; if (!rts.colors.empty()) @@ -1886,16 +1886,16 @@ StringMap Graphics::lineJoins( StringMap::Entry Graphics::featureEntries[] = { - { "multicanvasformats", FEATURE_MULTI_CANVAS_FORMATS }, - { "clampzero", FEATURE_CLAMP_ZERO }, - { "blendminmax", FEATURE_BLENDMINMAX }, - { "lighten", FEATURE_LIGHTEN }, - { "fullnpot", FEATURE_FULL_NPOT }, - { "pixelshaderhighp", FEATURE_PIXEL_SHADER_HIGHP }, - { "shaderderivatives", FEATURE_SHADER_DERIVATIVES }, - { "glsl3", FEATURE_GLSL3 }, - { "glsl4", FEATURE_GLSL4 }, - { "instancing", FEATURE_INSTANCING }, + { "multirendertargetformats", FEATURE_MULTI_RENDER_TARGET_FORMATS }, + { "clampzero", FEATURE_CLAMP_ZERO }, + { "blendminmax", FEATURE_BLEND_MINMAX }, + { "lighten", FEATURE_LIGHTEN }, + { "fullnpot", FEATURE_FULL_NPOT }, + { "pixelshaderhighp", FEATURE_PIXEL_SHADER_HIGHP }, + { "shaderderivatives", FEATURE_SHADER_DERIVATIVES }, + { "glsl3", FEATURE_GLSL3 }, + { "glsl4", FEATURE_GLSL4 }, + { "instancing", FEATURE_INSTANCING }, }; StringMap Graphics::features(Graphics::featureEntries, sizeof(Graphics::featureEntries)); @@ -1907,8 +1907,8 @@ StringMap::Entry Graphics::syst { "texturelayers", LIMIT_TEXTURE_LAYERS }, { "volumetexturesize", LIMIT_VOLUME_TEXTURE_SIZE }, { "cubetexturesize", LIMIT_CUBE_TEXTURE_SIZE }, - { "multicanvas", LIMIT_MULTI_CANVAS }, - { "canvasmsaa", LIMIT_CANVAS_MSAA }, + { "rendertargets", LIMIT_RENDER_TARGETS }, + { "texturemsaa", LIMIT_TEXTURE_MSAA }, { "anisotropy", LIMIT_ANISOTROPY }, }; diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 0b97a69ec..119ef5ff8 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -133,9 +133,9 @@ public: enum Feature { - FEATURE_MULTI_CANVAS_FORMATS, + FEATURE_MULTI_RENDER_TARGET_FORMATS, FEATURE_CLAMP_ZERO, - FEATURE_BLENDMINMAX, + FEATURE_BLEND_MINMAX, FEATURE_LIGHTEN, // Deprecated FEATURE_FULL_NPOT, FEATURE_PIXEL_SHADER_HIGHP, @@ -160,8 +160,8 @@ public: LIMIT_VOLUME_TEXTURE_SIZE, LIMIT_CUBE_TEXTURE_SIZE, LIMIT_TEXTURE_LAYERS, - LIMIT_MULTI_CANVAS, - LIMIT_CANVAS_MSAA, + LIMIT_RENDER_TARGETS, + LIMIT_TEXTURE_MSAA, LIMIT_ANISOTROPY, LIMIT_MAX_ENUM }; diff --git a/src/modules/graphics/Texture.cpp b/src/modules/graphics/Texture.cpp index 7ebd427c5..dcfa3b407 100644 --- a/src/modules/graphics/Texture.cpp +++ b/src/modules/graphics/Texture.cpp @@ -826,10 +826,10 @@ bool Texture::Slices::validate() const int expectedmips = Texture::getTotalMipmapCount(w, h, depth); if (mipcount != expectedmips && mipcount != 1) - throw love::Exception("Image does not have all required mipmap levels (expected %d, got %d)", expectedmips, mipcount); + throw love::Exception("Texture does not have all required mipmap levels (expected %d, got %d)", expectedmips, mipcount); if (textureType == TEXTURE_CUBE && w != h) - throw love::Exception("Cube images must have equal widths and heights for each cube face."); + throw love::Exception("Cube textures must have equal widths and heights for each cube face."); int mipw = w; int miph = h; @@ -856,7 +856,7 @@ bool Texture::Slices::validate() const int realh = slicedata->getHeight(); if (getMipmapCount(slice) != mipcount) - throw love::Exception("All Image layers must have the same mipmap count."); + throw love::Exception("All texture layers must have the same mipmap count."); if (mipw != realw) throw love::Exception("Width of image data (slice %d, mipmap level %d) is incorrect (expected %d, got %d)", slice+1, mip+1, mipw, realw); @@ -865,7 +865,7 @@ bool Texture::Slices::validate() const throw love::Exception("Height of image data (slice %d, mipmap level %d) is incorrect (expected %d, got %d)", slice+1, mip+1, miph, realh); if (format != slicedata->getFormat()) - throw love::Exception("All Image slices and mipmaps must have the same pixel format."); + throw love::Exception("All texture slices and mipmaps must have the same pixel format."); } mipw = std::max(mipw / 2, 1); diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 8b82e583e..1f4e52671 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -308,7 +308,7 @@ protected: int64 graphicsMemorySize; - // True if the image wasn't able to be properly created and it had to fall + // True if the texture wasn't able to be properly created and it had to fall // back to a default texture. bool usingDefaultTexture; diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index b0b9f25e6..d5b6c0469 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -1269,7 +1269,7 @@ void Graphics::setBlendState(const BlendState &blend) if (blend.operationRGB == BLENDOP_MAX || blend.operationA == BLENDOP_MAX || blend.operationRGB == BLENDOP_MIN || blend.operationA == BLENDOP_MIN) { - if (!capabilities.features[FEATURE_BLENDMINMAX]) + if (!capabilities.features[FEATURE_BLEND_MINMAX]) throw love::Exception("The 'min' and 'max' blend operations are not supported on this system."); } @@ -1355,10 +1355,10 @@ void Graphics::getAPIStats(int &shaderswitches) const void Graphics::initCapabilities() { - capabilities.features[FEATURE_MULTI_CANVAS_FORMATS] = gl.isMultiFormatMRTSupported(); + capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = gl.isMultiFormatMRTSupported(); capabilities.features[FEATURE_CLAMP_ZERO] = gl.isClampZeroOneTextureWrapSupported(); - capabilities.features[FEATURE_BLENDMINMAX] = GLAD_VERSION_1_4 || GLAD_ES_VERSION_3_0 || GLAD_EXT_blend_minmax; - capabilities.features[FEATURE_LIGHTEN] = capabilities.features[FEATURE_BLENDMINMAX]; + 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; @@ -1372,8 +1372,8 @@ void Graphics::initCapabilities() capabilities.limits[LIMIT_TEXTURE_LAYERS] = gl.getMaxTextureLayers(); capabilities.limits[LIMIT_VOLUME_TEXTURE_SIZE] = gl.getMax3DTextureSize(); capabilities.limits[LIMIT_CUBE_TEXTURE_SIZE] = gl.getMaxCubeTextureSize(); - capabilities.limits[LIMIT_MULTI_CANVAS] = gl.getMaxRenderTargets(); - capabilities.limits[LIMIT_CANVAS_MSAA] = gl.getMaxRenderbufferSamples(); + capabilities.limits[LIMIT_RENDER_TARGETS] = gl.getMaxRenderTargets(); + capabilities.limits[LIMIT_TEXTURE_MSAA] = gl.getMaxRenderbufferSamples(); capabilities.limits[LIMIT_ANISOTROPY] = gl.getMaxAnisotropy(); static_assert(LIMIT_MAX_ENUM == 8, "Graphics::initCapabilities must be updated when adding a new system limit!"); diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index b010202d4..df8cae160 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -259,8 +259,9 @@ void OpenGL::setupContext() #ifdef LOVE_ANDROID // This can't be done in initContext with the rest of the bug checks because - // Canvas::isFormatSupported relies on state initialized here / after init. - if (GLAD_ES_VERSION_3_0 && !Canvas::isFormatSupported(PIXELFORMAT_R8)) + // isPixelFormatSupported relies on state initialized here / after init. + auto gfx = Module::getInstance(Module::M_GRAPHICS); + if (GLAD_ES_VERSION_3_0 && gfx != nullptr && !gfx->isPixelFormatSupported(PIXELFORMAT_R8_UNORM, true, true)) bugs.brokenR8PixelFormat = true; #endif } diff --git a/src/modules/graphics/opengl/Shader.h b/src/modules/graphics/opengl/Shader.h index 23397ac57..8681ca5b1 100644 --- a/src/modules/graphics/opengl/Shader.h +++ b/src/modules/graphics/opengl/Shader.h @@ -110,7 +110,7 @@ private: // Uniform location buffer map std::map uniforms; - // Texture unit pool for setting images + // Texture unit pool for setting textures std::vector textureUnits; std::vector> pendingUniformUpdates; diff --git a/src/modules/graphics/opengl/Texture.cpp b/src/modules/graphics/opengl/Texture.cpp index ec6da42a8..5b9d82fe8 100644 --- a/src/modules/graphics/opengl/Texture.cpp +++ b/src/modules/graphics/opengl/Texture.cpp @@ -75,23 +75,26 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo gl.framebufferTexture(attachment, texType, texture, 0, layer, face); } - if (isPixelFormatDepthStencil(format)) + if (clear) { - bool hadDepthWrites = gl.hasDepthWrites(); - if (!hadDepthWrites) // glDepthMask also affects glClear. - gl.setDepthWrites(true); + if (isPixelFormatDepthStencil(format)) + { + bool hadDepthWrites = gl.hasDepthWrites(); + if (!hadDepthWrites) // glDepthMask also affects glClear. + gl.setDepthWrites(true); - gl.clearDepth(1.0); - glClearStencil(0); - glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + gl.clearDepth(1.0); + glClearStencil(0); + glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - if (!hadDepthWrites) - gl.setDepthWrites(hadDepthWrites); - } - else - { - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glClear(GL_COLOR_BUFFER_BIT); + if (!hadDepthWrites) + gl.setDepthWrites(hadDepthWrites); + } + else + { + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + } } } } diff --git a/src/modules/graphics/wrap_GraphicsShader.lua b/src/modules/graphics/wrap_GraphicsShader.lua index 14a1ba19d..f0631c6f6 100644 --- a/src/modules/graphics/wrap_GraphicsShader.lua +++ b/src/modules/graphics/wrap_GraphicsShader.lua @@ -271,7 +271,7 @@ GLSL.PIXEL = { precision mediump float; #endif -#define love_MaxCanvases gl_MaxDrawBuffers +#define love_MaxRenderTargets gl_MaxDrawBuffers #if __VERSION__ >= 130 #define varying in @@ -279,19 +279,26 @@ GLSL.PIXEL = { // pixel shader outputs are defined, even when only one is actually used. // TODO: We should use reflection or something instead of this, to determine // how many outputs are actually used in the shader code. - #ifdef LOVE_MULTI_CANVAS - layout(location = 0) out vec4 love_Canvases[love_MaxCanvases]; - #define love_PixelColor love_Canvases[0] + #ifdef LOVE_MULTI_RENDER_TARGETS + layout(location = 0) out vec4 love_RenderTargets[love_MaxRenderTargets]; + #define love_PixelColor love_RenderTargets[0] #else layout(location = 0) out vec4 love_PixelColor; #endif #else - #ifdef LOVE_MULTI_CANVAS - #define love_Canvases gl_FragData + #ifdef LOVE_MULTI_RENDER_TARGETS + #define love_RenderTargets gl_FragData #endif #define love_PixelColor gl_FragColor #endif +// Legacy +#define love_MaxCanvases love_MaxRenderTargets +#define love_Canvases love_RenderTargets +#ifdef LOVE_MULTI_RENDER_TARGETS +#define LOVE_MULTI_CANVASES 1 +#endif + // See Shader::updateScreenParams in Shader.cpp. #define love_PixelCoord (vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w))]], @@ -345,14 +352,14 @@ local function getLanguageTarget(code) return (code:match("^%s*#pragma language (%w+)")) or "glsl1" end -local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, custom, multicanvas) +local function createShaderStageCode(stage, code, lang, gles, glsl1on3, gammacorrect, custom, multirendertarget) stage = stage:upper() local lines = { GLSL.VERSION[lang][gles], "#define " ..stage .. " " .. stage, glsl1on3 and "#define LOVE_GLSL1_ON_GLSL3 1" or "", gammacorrect and "#define LOVE_GAMMA_CORRECT 1" or "", - multicanvas and "#define LOVE_MULTI_CANVAS 1" or "", + multirendertarget and "#define LOVE_MULTI_RENDER_TARGETS 1" or "", GLSL.SYNTAX, GLSL[stage].HEADER, GLSL.UNIFORMS, @@ -373,8 +380,8 @@ local function isPixelCode(code) if code:match("vec4%s+effect%s*%(") then return true elseif code:match("void%s+effect%s*%(") then -- custom effect function - local multicanvas = code:match("love_Canvases") ~= nil - return true, true, multicanvas + local multirendertargets = (code:match("love_RenderTargets") ~= nil) or (code:match("love_Canvases") ~= nil) + return true, true, multirendertargets else return false end