diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 8339b0457..785371426 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -448,21 +448,29 @@ void Graphics::clear(Colorf c) glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void Graphics::clear(const std::vector &colors) +void Graphics::clear(const std::vector &colors) { if (colors.size() == 0) return; if (states.back().canvases.size() == 0) - return clear(colors[0]); + { + if (colors[0].enabled) + clear({colors[0].r, colors[0].g, colors[0].b, colors[0].a}); + + return; + } if (colors.size() != states.back().canvases.size()) throw love::Exception("Number of clear colors must match the number of active canvases (%ld)", states.back().canvases.size()); - std::vector bufs; + bool drawbuffermodified = false; for (int i = 0; i < (int) colors.size(); i++) { + if (!colors[i].enabled) + continue; + GLfloat c[] = {colors[i].r/255.f, colors[i].g/255.f, colors[i].b/255.f, colors[i].a/255.f}; // TODO: Investigate a potential bug on AMD drivers in Windows/Linux @@ -478,10 +486,11 @@ void Graphics::clear(const std::vector &colors) glClearBufferfv(GL_COLOR, i, c); else { - bufs.push_back(GL_COLOR_ATTACHMENT0 + i); glDrawBuffer(GL_COLOR_ATTACHMENT0 + i); glClearColor(c[0], c[1], c[2], c[3]); glClear(GL_COLOR_BUFFER_BIT); + + drawbuffermodified = true; } } @@ -489,8 +498,13 @@ void Graphics::clear(const std::vector &colors) // Revert to the expected draw buffers once we're done, if glClearBuffer // wasn't supported. - if (!(GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0)) + if (drawbuffermodified) { + std::vector bufs; + + for (int i = 0; i < (int) states.back().canvases.size(); i++) + bufs.push_back(GL_COLOR_ATTACHMENT0 + i); + if (bufs.size() > 1) glDrawBuffers((int) bufs.size(), &bufs[0]); else diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 3fab27735..e5b49c3d2 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -62,6 +62,12 @@ class Graphics : public love::graphics::Graphics { public: + struct OptionalColorf + { + float r, g, b, a; + bool enabled; + }; + Graphics(); virtual ~Graphics(); @@ -92,7 +98,7 @@ public: /** * Clears each active canvas to a different color. **/ - void clear(const std::vector &colors); + void clear(const std::vector &colors); /** * Discards the contents of the screen. diff --git a/src/modules/graphics/opengl/wrap_Graphics.cpp b/src/modules/graphics/opengl/wrap_Graphics.cpp index b3a888d19..5cbff5d0b 100644 --- a/src/modules/graphics/opengl/wrap_Graphics.cpp +++ b/src/modules/graphics/opengl/wrap_Graphics.cpp @@ -55,19 +55,26 @@ int w_reset(lua_State *) int w_clear(lua_State *L) { - std::vector colors(1); + Colorf color; if (lua_isnoneornil(L, 1)) - colors[0].set(0, 0, 0, 0); + color.set(0, 0, 0, 0); else if (lua_istable(L, 1)) { - colors.resize((size_t) lua_gettop(L)); + std::vector colors((size_t) lua_gettop(L)); for (int i = 0; i < lua_gettop(L); i++) { + if (lua_isnoneornil(L, i + 1) || luax_objlen(L, i + 1) == 0) + { + colors[i].enabled = false; + continue; + } + for (int j = 1; j <= 4; j++) lua_rawgeti(L, i + 1, j); + colors[i].enabled = true; colors[i].r = (float) luaL_checknumber(L, -4); colors[i].g = (float) luaL_checknumber(L, -3); colors[i].b = (float) luaL_checknumber(L, -2); @@ -75,22 +82,19 @@ int w_clear(lua_State *L) lua_pop(L, 4); } + + luax_catchexcept(L, [&]() { instance()->clear(colors); }); + return 0; } else { - colors[0].r = (float) luaL_checknumber(L, 1); - colors[0].g = (float) luaL_checknumber(L, 2); - colors[0].b = (float) luaL_checknumber(L, 3); - colors[0].a = (float) luaL_optnumber(L, 4, 255); + color.r = (float) luaL_checknumber(L, 1); + color.g = (float) luaL_checknumber(L, 2); + color.b = (float) luaL_checknumber(L, 3); + color.a = (float) luaL_optnumber(L, 4, 255); } - luax_catchexcept(L, [&]() { - if (colors.size() == 1) - instance()->clear(colors[0]); - else - instance()->clear(colors); - }); - + luax_catchexcept(L, [&]() { instance()->clear(color); }); return 0; }