When multiple canvases are active at once (MRT), individual canvases can now be selectively cleared with love.graphics.clear(c1, c2, ...) by passing empty tables for the canvases that shouldn't be cleared, and color tables for the canvases that should.

This commit is contained in:
Alex Szpakowski
2015-12-29 00:10:40 -04:00
parent b56a0cfc3d
commit 09e6a9a434
3 changed files with 44 additions and 20 deletions
+19 -5
View File
@@ -448,21 +448,29 @@ void Graphics::clear(Colorf c)
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
void Graphics::clear(const std::vector<Colorf> &colors) void Graphics::clear(const std::vector<OptionalColorf> &colors)
{ {
if (colors.size() == 0) if (colors.size() == 0)
return; return;
if (states.back().canvases.size() == 0) 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()) 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()); throw love::Exception("Number of clear colors must match the number of active canvases (%ld)", states.back().canvases.size());
std::vector<GLenum> bufs; bool drawbuffermodified = false;
for (int i = 0; i < (int) colors.size(); i++) 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}; 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 // TODO: Investigate a potential bug on AMD drivers in Windows/Linux
@@ -478,10 +486,11 @@ void Graphics::clear(const std::vector<Colorf> &colors)
glClearBufferfv(GL_COLOR, i, c); glClearBufferfv(GL_COLOR, i, c);
else else
{ {
bufs.push_back(GL_COLOR_ATTACHMENT0 + i);
glDrawBuffer(GL_COLOR_ATTACHMENT0 + i); glDrawBuffer(GL_COLOR_ATTACHMENT0 + i);
glClearColor(c[0], c[1], c[2], c[3]); glClearColor(c[0], c[1], c[2], c[3]);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
drawbuffermodified = true;
} }
} }
@@ -489,8 +498,13 @@ void Graphics::clear(const std::vector<Colorf> &colors)
// Revert to the expected draw buffers once we're done, if glClearBuffer // Revert to the expected draw buffers once we're done, if glClearBuffer
// wasn't supported. // wasn't supported.
if (!(GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0)) if (drawbuffermodified)
{ {
std::vector<GLenum> bufs;
for (int i = 0; i < (int) states.back().canvases.size(); i++)
bufs.push_back(GL_COLOR_ATTACHMENT0 + i);
if (bufs.size() > 1) if (bufs.size() > 1)
glDrawBuffers((int) bufs.size(), &bufs[0]); glDrawBuffers((int) bufs.size(), &bufs[0]);
else else
+7 -1
View File
@@ -62,6 +62,12 @@ class Graphics : public love::graphics::Graphics
{ {
public: public:
struct OptionalColorf
{
float r, g, b, a;
bool enabled;
};
Graphics(); Graphics();
virtual ~Graphics(); virtual ~Graphics();
@@ -92,7 +98,7 @@ public:
/** /**
* Clears each active canvas to a different color. * Clears each active canvas to a different color.
**/ **/
void clear(const std::vector<Colorf> &colors); void clear(const std::vector<OptionalColorf> &colors);
/** /**
* Discards the contents of the screen. * Discards the contents of the screen.
+18 -14
View File
@@ -55,19 +55,26 @@ int w_reset(lua_State *)
int w_clear(lua_State *L) int w_clear(lua_State *L)
{ {
std::vector<Colorf> colors(1); Colorf color;
if (lua_isnoneornil(L, 1)) if (lua_isnoneornil(L, 1))
colors[0].set(0, 0, 0, 0); color.set(0, 0, 0, 0);
else if (lua_istable(L, 1)) else if (lua_istable(L, 1))
{ {
colors.resize((size_t) lua_gettop(L)); std::vector<Graphics::OptionalColorf> colors((size_t) lua_gettop(L));
for (int i = 0; i < lua_gettop(L); i++) 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++) for (int j = 1; j <= 4; j++)
lua_rawgeti(L, i + 1, j); lua_rawgeti(L, i + 1, j);
colors[i].enabled = true;
colors[i].r = (float) luaL_checknumber(L, -4); colors[i].r = (float) luaL_checknumber(L, -4);
colors[i].g = (float) luaL_checknumber(L, -3); colors[i].g = (float) luaL_checknumber(L, -3);
colors[i].b = (float) luaL_checknumber(L, -2); colors[i].b = (float) luaL_checknumber(L, -2);
@@ -75,22 +82,19 @@ int w_clear(lua_State *L)
lua_pop(L, 4); lua_pop(L, 4);
} }
luax_catchexcept(L, [&]() { instance()->clear(colors); });
return 0;
} }
else else
{ {
colors[0].r = (float) luaL_checknumber(L, 1); color.r = (float) luaL_checknumber(L, 1);
colors[0].g = (float) luaL_checknumber(L, 2); color.g = (float) luaL_checknumber(L, 2);
colors[0].b = (float) luaL_checknumber(L, 3); color.b = (float) luaL_checknumber(L, 3);
colors[0].a = (float) luaL_optnumber(L, 4, 255); color.a = (float) luaL_optnumber(L, 4, 255);
} }
luax_catchexcept(L, [&]() { luax_catchexcept(L, [&]() { instance()->clear(color); });
if (colors.size() == 1)
instance()->clear(colors[0]);
else
instance()->clear(colors);
});
return 0; return 0;
} }