Browse Source

Prevent overflows and underflows in love.graphics.push and love.graphics.pop (bug #118)

Maximum is hardware maximum - 5, so the engine itself has a few matrices.
Bart van Strien 14 years ago
parent
commit
efb8efb45e

+ 12 - 1
src/modules/graphics/opengl/Graphics.cpp

@@ -37,7 +37,7 @@ namespace opengl
 {
 
 	Graphics::Graphics()
-		: currentFont(0), lineWidth(1)
+		: currentFont(0), lineWidth(1), matrixLimit(0), userMatrices(0)
 	{
 		// Indicates that there is no screen
 		// created yet.
@@ -279,6 +279,11 @@ namespace opengl
 
 		// Restore the display state.
 		restoreState(tempState);
+		
+		// Get the maximum number of matrices
+		// subtract a few to give the engine some room.
+		glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &matrixLimit);
+		matrixLimit -= 5;
 
 		return true;
 	}
@@ -984,12 +989,18 @@ namespace opengl
 
 	void Graphics::push()
 	{
+		if (userMatrices == matrixLimit)
+			throw Exception("Maximum stack depth reached.");
 		glPushMatrix();
+		++userMatrices;
 	}
 
 	void Graphics::pop()
 	{
+		if (userMatrices < 1)
+			throw Exception("Minimum stack depth reached. (More pops than pushes?)");
 		glPopMatrix();
+		--userMatrices;
 	}
 
 	void Graphics::rotate(float r)

+ 2 - 0
src/modules/graphics/opengl/Graphics.h

@@ -115,6 +115,8 @@ namespace opengl
 		DisplayMode currentMode;
 
 		float lineWidth;
+		GLint matrixLimit;
+		GLint userMatrices;
 
 	public:
 

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

@@ -950,15 +950,29 @@ namespace opengl
 		return 0;
 	}
 
-	int w_push(lua_State *)
+	int w_push(lua_State *L)
 	{
-		instance->push();
+		try
+		{
+			instance->push();
+		}
+		catch (love::Exception e)
+		{
+			return luaL_error(L, e.what());
+		}
 		return 0;
 	}
 
-	int w_pop(lua_State *)
+	int w_pop(lua_State *L)
 	{
-		instance->pop();
+		try
+		{
+			instance->pop();
+		}
+		catch (love::Exception e)
+		{
+			return luaL_error(L, e.what());
+		}
 		return 0;
 	}