Browse Source

Added love.graphics.intersectScissor(x, y, w, h). Resolves issue #1071.

It sets the active scissor rectangle to the intersection of the existing scissor (if any) and the specified rectangle.
Alex Szpakowski 10 years ago
parent
commit
00845c0ad0

+ 0 - 6
platform/xcode/ios/Images.xcassets/AppIcon.appiconset/Contents.json

@@ -113,12 +113,6 @@
       "idiom" : "ipad",
       "idiom" : "ipad",
       "filename" : "[email protected]",
       "filename" : "[email protected]",
       "scale" : "2x"
       "scale" : "2x"
-    },
-    {
-      "size" : "120x120",
-      "idiom" : "car",
-      "filename" : "[email protected]",
-      "scale" : "1x"
     }
     }
   ],
   ],
   "info" : {
   "info" : {

BIN
platform/xcode/ios/Images.xcassets/AppIcon.appiconset/[email protected]


+ 11 - 0
src/modules/graphics/Graphics.h

@@ -178,6 +178,17 @@ public:
 		}
 		}
 	};
 	};
 
 
+	struct ScissorRect
+	{
+		int x, y;
+		int w, h;
+
+		bool operator == (const ScissorRect &rhs) const
+		{
+			return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
+		}
+	};
+
 	virtual ~Graphics();
 	virtual ~Graphics();
 
 
 	// Implements Module.
 	// Implements Module.

+ 31 - 10
src/modules/graphics/opengl/Graphics.cpp

@@ -110,7 +110,7 @@ void Graphics::restoreState(const DisplayState &s)
 	setPointSize(s.pointSize);
 	setPointSize(s.pointSize);
 
 
 	if (s.scissor)
 	if (s.scissor)
-		setScissor(s.scissorBox.x, s.scissorBox.y, s.scissorBox.w, s.scissorBox.h);
+		setScissor(s.scissorRect.x, s.scissorRect.y, s.scissorRect.w, s.scissorRect.h);
 	else
 	else
 		setScissor();
 		setScissor();
 
 
@@ -147,10 +147,10 @@ void Graphics::restoreStateChecked(const DisplayState &s)
 	if (s.pointSize != cur.pointSize)
 	if (s.pointSize != cur.pointSize)
 		setPointSize(s.pointSize);
 		setPointSize(s.pointSize);
 
 
-	if (s.scissor != cur.scissor || (s.scissor && !(s.scissorBox == cur.scissorBox)))
+	if (s.scissor != cur.scissor || (s.scissor && !(s.scissorRect == cur.scissorRect)))
 	{
 	{
 		if (s.scissor)
 		if (s.scissor)
-			setScissor(s.scissorBox.x, s.scissorBox.y, s.scissorBox.w, s.scissorBox.h);
+			setScissor(s.scissorRect.x, s.scissorRect.y, s.scissorRect.w, s.scissorRect.h);
 		else
 		else
 			setScissor();
 			setScissor();
 	}
 	}
@@ -580,14 +580,35 @@ bool Graphics::isCreated() const
 
 
 void Graphics::setScissor(int x, int y, int width, int height)
 void Graphics::setScissor(int x, int y, int width, int height)
 {
 {
-	OpenGL::Viewport box = {x, y, width, height};
+	ScissorRect rect = {x, y, width, height};
 
 
 	glEnable(GL_SCISSOR_TEST);
 	glEnable(GL_SCISSOR_TEST);
 	// OpenGL's reversed y-coordinate is compensated for in OpenGL::setScissor.
 	// OpenGL's reversed y-coordinate is compensated for in OpenGL::setScissor.
-	gl.setScissor(box);
+	gl.setScissor({rect.x, rect.y, rect.w, rect.h});
 
 
 	states.back().scissor = true;
 	states.back().scissor = true;
-	states.back().scissorBox = box;
+	states.back().scissorRect = rect;
+}
+
+void Graphics::intersectScissor(int x, int y, int width, int height)
+{
+	ScissorRect rect = states.back().scissorRect;
+
+	if (!states.back().scissor)
+	{
+		rect.x = 0;
+		rect.y = 0;
+		rect.w = std::numeric_limits<int>::max();
+		rect.h = std::numeric_limits<int>::max();
+	}
+
+	int x1 = std::max(rect.x, x);
+	int y1 = std::max(rect.y, y);
+
+	int x2 = std::min(rect.x + rect.w, x + width);
+	int y2 = std::min(rect.y + rect.h, y + height);
+
+	setScissor(x1, y1, std::max(0, x2 - x1), std::max(0, y2 - y1));
 }
 }
 
 
 void Graphics::setScissor()
 void Graphics::setScissor()
@@ -600,10 +621,10 @@ bool Graphics::getScissor(int &x, int &y, int &width, int &height) const
 {
 {
 	const DisplayState &state = states.back();
 	const DisplayState &state = states.back();
 
 
-	x = state.scissorBox.x;
-	y = state.scissorBox.y;
-	width = state.scissorBox.w;
-	height = state.scissorBox.h;
+	x = state.scissorRect.x;
+	y = state.scissorRect.y;
+	width = state.scissorRect.w;
+	height = state.scissorRect.h;
 
 
 	return state.scissor;
 	return state.scissor;
 }
 }

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

@@ -126,6 +126,8 @@ public:
 	 **/
 	 **/
 	void setScissor(int x, int y, int width, int height);
 	void setScissor(int x, int y, int width, int height);
 
 
+	void intersectScissor(int x, int y, int width, int height);
+
 	/**
 	/**
 	 * Clears any scissor that has been created.
 	 * Clears any scissor that has been created.
 	 **/
 	 **/
@@ -478,7 +480,7 @@ private:
 		float pointSize = 1.0f;
 		float pointSize = 1.0f;
 
 
 		bool scissor = false;
 		bool scissor = false;
-		OpenGL::Viewport scissorBox = OpenGL::Viewport();
+		ScissorRect scissorRect = ScissorRect();
 
 
 		// Stencil.
 		// Stencil.
 		bool stencilTest = false;
 		bool stencilTest = false;

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

@@ -184,6 +184,20 @@ int w_setScissor(lua_State *L)
 	return 0;
 	return 0;
 }
 }
 
 
+int w_intersectScissor(lua_State *L)
+{
+	int x = (int) luaL_checknumber(L, 1);
+	int y = (int) luaL_checknumber(L, 2);
+	int w = (int) luaL_checknumber(L, 3);
+	int h = (int) luaL_checknumber(L, 4);
+
+	if (w < 0 || h < 0)
+		return luaL_error(L, "Can't set scissor with negative width and/or height.");
+
+	instance()->intersectScissor(x, y, w, h);
+	return 0;
+}
+
 int w_getScissor(lua_State *L)
 int w_getScissor(lua_State *L)
 {
 {
 	int x, y, w, h;
 	int x, y, w, h;
@@ -1899,6 +1913,7 @@ static const luaL_Reg functions[] =
 	{ "getDimensions", w_getDimensions },
 	{ "getDimensions", w_getDimensions },
 
 
 	{ "setScissor", w_setScissor },
 	{ "setScissor", w_setScissor },
+	{ "intersectScissor", w_intersectScissor },
 	{ "getScissor", w_getScissor },
 	{ "getScissor", w_getScissor },
 
 
 	{ "stencil", w_stencil },
 	{ "stencil", w_stencil },

+ 1 - 0
src/modules/graphics/opengl/wrap_Graphics.h

@@ -52,6 +52,7 @@ int w_getWidth(lua_State *L);
 int w_getHeight(lua_State *L);
 int w_getHeight(lua_State *L);
 int w_getDimensions(lua_State *L);
 int w_getDimensions(lua_State *L);
 int w_setScissor(lua_State *L);
 int w_setScissor(lua_State *L);
+int w_intersectScissor(lua_State *L);
 int w_getScissor(lua_State *L);
 int w_getScissor(lua_State *L);
 int w_stencil(lua_State *L);
 int w_stencil(lua_State *L);
 int w_setStencilTest(lua_State *L);
 int w_setStencilTest(lua_State *L);