diff --git a/src/modules/graphics/Polyline.cpp b/src/modules/graphics/Polyline.cpp index 5698a9dd3..b5a910d1f 100644 --- a/src/modules/graphics/Polyline.cpp +++ b/src/modules/graphics/Polyline.cpp @@ -405,18 +405,28 @@ void Polyline::draw(love::graphics::Graphics *gfx) Color32 *colordata = (Color32 *) data.stream[1]; + int draw_rough_count = std::min(cmd.vertexCount, (int) vertex_count - vertex_start); + // Constant vertex color up to the overdraw vertices. - for (int i = 0; i < std::min(cmd.vertexCount, (int) vertex_count - vertex_start); i++) + for (int i = 0; i < draw_rough_count; i++) colordata[i] = curcolor; - int colorcount = 0; if (overdraw) - colorcount = std::min(cmd.vertexCount, overdraw_count - (vertex_start - overdraw_start)); - - if (colorcount > 0) { - Color32 *colors = colordata + std::max(0, (overdraw_start - vertex_start)); - fill_color_array(curcolor, colors, colorcount); + int draw_remaining_count = cmd.vertexCount - draw_rough_count; + + int draw_overdraw_begin = overdraw_start - vertex_start; + int draw_overdraw_end = draw_overdraw_begin + overdraw_count; + + draw_overdraw_begin = std::max(0, draw_overdraw_begin); + + int draw_overdraw_count = std::min(draw_remaining_count, draw_overdraw_end - draw_overdraw_begin); + + if (draw_overdraw_count > 0) + { + Color32 *colors = colordata + draw_overdraw_begin; + fill_color_array(curcolor, colors, draw_overdraw_count); + } } } } diff --git a/src/modules/graphics/opengl/OpenGL.cpp b/src/modules/graphics/opengl/OpenGL.cpp index 792523234..490d7b9b5 100644 --- a/src/modules/graphics/opengl/OpenGL.cpp +++ b/src/modules/graphics/opengl/OpenGL.cpp @@ -155,11 +155,11 @@ bool OpenGL::initContext() #ifdef LOVE_WINDOWS if (getVendor() == VENDOR_AMD) { - // Radeon HD drivers switched from "ATI Radeon" to "AMD Radeon" around + // Radeon drivers switched from "ATI Radeon" to "AMD Radeon" around // the 7000 series. We'll assume this bug doesn't affect those newer // GPUs / drivers. const char *device = (const char *) glGetString(GL_RENDERER); - if (strstr(device, "ATI Radeon HD ") || strstr(device, "ATI Mobility Radeon HD")) + if (strstr(device, "ATI Radeon") || strstr(device, "ATI Mobility Radeon")) bugs.texStorageBreaksSubImage = true; } #endif diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 13afd9c92..3a57a2d55 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -166,7 +166,7 @@ public: * initial full-size one (determined after some investigation with an * affected user on Discord.) * https://bitbucket.org/rude/love/issues/1436/bug-with-lovegraphicsprint-on-older-ati - * + * https://github.com/love2d/love/issues/1563 **/ bool texStorageBreaksSubImage; diff --git a/src/modules/graphics/opengl/Texture.cpp b/src/modules/graphics/opengl/Texture.cpp index b54b42eb0..b51cfbdfb 100644 --- a/src/modules/graphics/opengl/Texture.cpp +++ b/src/modules/graphics/opengl/Texture.cpp @@ -42,6 +42,11 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo glGenFramebuffers(1, &framebuffer); gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, framebuffer); + // Intel driver bug: https://github.com/love2d/love/issues/1592 + bool current_srgb = gl.isStateEnabled(OpenGL::ENABLE_FRAMEBUFFER_SRGB); + if (current_srgb && isPixelFormatDepthStencil(format)) + gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, false); + if (texture != 0) { if (isPixelFormatDepthStencil(format) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0)) @@ -103,6 +108,11 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, current_fbo); + + // Restore sRGB state if we turned it off above. + if (current_srgb && isPixelFormatDepthStencil(format)) + gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, current_srgb); + return status; } diff --git a/src/modules/graphics/wrap_Shader.cpp b/src/modules/graphics/wrap_Shader.cpp index 44badcb0d..3fbddc65c 100644 --- a/src/modules/graphics/wrap_Shader.cpp +++ b/src/modules/graphics/wrap_Shader.cpp @@ -313,20 +313,36 @@ static int w_Shader_sendData(lua_State *L, int startidx, Shader *shader, const S if (info->baseType == Shader::UNIFORM_SAMPLER) return luaL_error(L, "Uniform sampler values (textures) cannot be sent to Shaders via Data objects."); - bool columnmajor = false; - if (info->baseType == Shader::UNIFORM_MATRIX && lua_type(L, startidx + 1) == LUA_TSTRING) + math::Transform::MatrixLayout layout = math::Transform::MATRIX_ROW_MAJOR; + int dataidx = startidx; + if (info->baseType == Shader::UNIFORM_MATRIX) { - const char *layoutstr = lua_tostring(L, startidx + 1); - math::Transform::MatrixLayout layout; - if (!math::Transform::getConstant(layoutstr, layout)) - return luax_enumerror(L, "matrix layout", math::Transform::getConstants(layout), layoutstr); + if (lua_type(L, startidx) == LUA_TSTRING) + { + // (matrixlayout, data, ...) + const char *layoutstr = lua_tostring(L, startidx); + if (!math::Transform::getConstant(layoutstr, layout)) + return luax_enumerror(L, "matrix layout", math::Transform::getConstants(layout), layoutstr); - columnmajor = (layout == math::Transform::MATRIX_COLUMN_MAJOR); - startidx++; + startidx++; + dataidx = startidx; + } + else if (lua_type(L, startidx + 1) == LUA_TSTRING) + { + // (data, matrixlayout, ...) + // Should be deprecated in the future (doesn't match the argument + // order of Shader:send(name, matrixlayout, table)) + const char *layoutstr = lua_tostring(L, startidx + 1); + if (!math::Transform::getConstant(layoutstr, layout)) + return luax_enumerror(L, "matrix layout", math::Transform::getConstants(layout), layoutstr); + + startidx++; + } } - Data *data = luax_checktype(L, startidx); + bool columnmajor = (layout == math::Transform::MATRIX_COLUMN_MAJOR); + Data *data = luax_checktype(L, dataidx); size_t size = data->getSize(); ptrdiff_t offset = (ptrdiff_t) luaL_optinteger(L, startidx + 1, 0); @@ -339,17 +355,17 @@ static int w_Shader_sendData(lua_State *L, int startidx, Shader *shader, const S if (!lua_isnoneornil(L, startidx + 2)) { - lua_Integer datasize = luaL_checkinteger(L, startidx + 2); - if (datasize <= 0) + lua_Integer sizearg = luaL_checkinteger(L, startidx + 2); + if (sizearg <= 0) return luaL_error(L, "Size must be greater than 0."); - else if ((size_t) datasize > size - offset) + else if ((size_t) sizearg > size - offset) return luaL_error(L, "Size and offset must fit within the Data's bounds."); - else if (size % uniformstride != 0) - return luaL_error(L, "Size must be a multiple of the uniform's size in bytes."); - else if (size > info->dataSize) + else if (sizearg % uniformstride != 0) + return luaL_error(L, "Size (%d) must be a multiple of the uniform's size in bytes (%d).", sizearg, uniformstride); + else if ((size_t) sizearg > info->dataSize) return luaL_error(L, "Size must not be greater than the uniform's total size in bytes."); - size = (size_t) datasize; + size = (size_t) sizearg; } else { @@ -416,7 +432,7 @@ int w_Shader_send(lua_State *L) return 1; } - if (luax_istype(L, 3, Data::type)) + if (luax_istype(L, 3, Data::type) || (info->baseType == Shader::UNIFORM_MATRIX && luax_istype(L, 4, Data::type))) w_Shader_sendData(L, 3, shader, info, false); else w_Shader_sendLuaValues(L, 3, shader, info, name);