Browse Source

love.graphics.discard now accepts a table of booleans indicating which of the active canvases to discard (matches love.graphics.clear.)

Alex Szpakowski 10 years ago
parent
commit
e237ed2432

+ 9 - 8
src/modules/graphics/opengl/Graphics.cpp

@@ -465,18 +465,18 @@ void Graphics::clear(const std::vector<Color> &colors)
 	}
 	}
 }
 }
 
 
-void Graphics::discard(bool color, bool stencil)
+void Graphics::discard(const std::vector<bool> &colorbuffers, bool stencil)
 {
 {
 	if (!(GLAD_VERSION_4_3 || GLAD_ARB_invalidate_subdata || GLAD_ES_VERSION_3_0 || GLAD_EXT_discard_framebuffer))
 	if (!(GLAD_VERSION_4_3 || GLAD_ARB_invalidate_subdata || GLAD_ES_VERSION_3_0 || GLAD_EXT_discard_framebuffer))
 		return;
 		return;
 
 
 	std::vector<GLenum> attachments;
 	std::vector<GLenum> attachments;
-	attachments.reserve(3);
+	attachments.reserve(colorbuffers.size());
 
 
 	// glDiscardFramebuffer uses different attachment enums for the default FBO.
 	// glDiscardFramebuffer uses different attachment enums for the default FBO.
 	if (!Canvas::current && gl.getDefaultFBO() == 0)
 	if (!Canvas::current && gl.getDefaultFBO() == 0)
 	{
 	{
-		if (color)
+		if (colorbuffers.size() > 0 && colorbuffers[0])
 			attachments.push_back(GL_COLOR);
 			attachments.push_back(GL_COLOR);
 
 
 		if (stencil)
 		if (stencil)
@@ -487,11 +487,12 @@ void Graphics::discard(bool color, bool stencil)
 	}
 	}
 	else
 	else
 	{
 	{
-		if (color)
+		int activecanvascount = (int) states.back().canvases.size();
+
+		for (int i = 0; i < (int) colorbuffers.size(); i++)
 		{
 		{
-			attachments.push_back(GL_COLOR_ATTACHMENT0);
-			for (int i = 0; i < (int) states.back().canvases.size() - 1; i++)
-				attachments.push_back(GL_COLOR_ATTACHMENT1 + i);
+			if (colorbuffers[i] && i < activecanvascount)
+				attachments.push_back(GL_COLOR_ATTACHMENT0 + i);
 		}
 		}
 
 
 		if (stencil)
 		if (stencil)
@@ -518,7 +519,7 @@ void Graphics::present()
 	setCanvas();
 	setCanvas();
 
 
 	// Discard the stencil buffer before swapping.
 	// Discard the stencil buffer before swapping.
-	discard(false, true);
+	discard({}, true);
 
 
 #ifdef LOVE_IOS
 #ifdef LOVE_IOS
 	// Hack: SDL's color renderbuffer needs to be bound when swapBuffers is called.
 	// Hack: SDL's color renderbuffer needs to be bound when swapBuffers is called.

+ 1 - 1
src/modules/graphics/opengl/Graphics.h

@@ -94,7 +94,7 @@ public:
 	/**
 	/**
 	 * Discards the contents of the screen.
 	 * Discards the contents of the screen.
 	 **/
 	 **/
-	void discard(bool color, bool stencil);
+	void discard(const std::vector<bool> &colorbuffers, bool stencil);
 
 
 	/**
 	/**
 	 * Flips buffers. (Rendered geometry is presented on screen).
 	 * Flips buffers. (Rendered geometry is presented on screen).

+ 19 - 2
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -88,9 +88,26 @@ int w_clear(lua_State *L)
 
 
 int w_discard(lua_State *L)
 int w_discard(lua_State *L)
 {
 {
-	bool color = luax_optboolean(L, 1, true);
+	std::vector<bool> colorbuffers;
+
+	if (lua_istable(L, 1))
+	{
+		for (size_t i = 1; i <= lua_objlen(L, 1); i++)
+		{
+			lua_rawgeti(L, 1, i);
+			colorbuffers.push_back(luax_optboolean(L, -1, true));
+			lua_pop(L, 1);
+		}
+	}
+	else
+	{
+		bool discardcolor = luax_optboolean(L, 1, true);
+		size_t numbuffers = std::max((size_t) 1, instance()->getCanvas().size());
+		colorbuffers = std::vector<bool>(numbuffers, discardcolor);
+	}
+
 	bool stencil = luax_optboolean(L, 2, true);
 	bool stencil = luax_optboolean(L, 2, true);
-	instance()->discard(color, stencil);
+	instance()->discard(colorbuffers, stencil);
 	return 0;
 	return 0;
 }
 }