Browse Source

Fix issue #294: Canvas not working when not rendering to default render target.

vrld 14 years ago
parent
commit
d5dce6284f

+ 21 - 0
src/modules/graphics/opengl/Canvas.h

@@ -49,6 +49,27 @@ namespace opengl
 		bool loadVolatile();
 		bool loadVolatile();
 		void unloadVolatile();
 		void unloadVolatile();
 
 
+		/// Unbind the current canvas on construction and rebind it upon destruction.
+		// Exception safe temporary unbinding/rebinding for techniques that require
+		// the default canvas to work (e.g. stencils).
+		// XXX: If a canvas is switched between creating and destroying an unbinder
+		//      object, the canvas will not be switched back.
+		struct TemporaryUnbinder
+		{
+			Canvas * canvas;
+			inline TemporaryUnbinder() : canvas(Canvas::current)
+			{
+				if (NULL != canvas)
+					Canvas::bindDefaultCanvas();
+			}
+
+			inline ~TemporaryUnbinder()
+			{
+				if (NULL != canvas && NULL == Canvas::current)
+					canvas->startGrab();
+			}
+		};
+
 	private:
 	private:
 		friend class PixelEffect;
 		friend class PixelEffect;
 		GLuint getTextureName() const { return img; }
 		GLuint getTextureName() const { return img; }

+ 4 - 0
src/modules/graphics/opengl/wrap_Graphics.cpp

@@ -24,6 +24,7 @@
 #include <font/Rasterizer.h>
 #include <font/Rasterizer.h>
 
 
 #include <scripts/graphics.lua.h>
 #include <scripts/graphics.lua.h>
+#include <cassert>
 
 
 namespace love
 namespace love
 {
 {
@@ -168,6 +169,9 @@ namespace opengl
 
 
 	static int setStencil(lua_State * L, bool invert)
 	static int setStencil(lua_State * L, bool invert)
 	{
 	{
+		// stencils require the default fb to work properly
+		Canvas::TemporaryUnbinder unbinder;
+
 		// no argument -> clear mask
 		// no argument -> clear mask
 		if (lua_isnoneornil(L, 1)) {
 		if (lua_isnoneornil(L, 1)) {
 			instance->discardStencil();
 			instance->discardStencil();