Browse Source

Add love.graphics.setCustomProjection.

The active projection matrix is reset when changing canvases, and when the window is resized if no canvas is active at the time.
Sasha Szpakowski 1 year ago
parent
commit
21b71d02b5

+ 29 - 0
src/modules/graphics/wrap_Graphics.cpp

@@ -3900,6 +3900,34 @@ int w_inverseTransformPoint(lua_State *L)
 	return 2;
 	return 2;
 }
 }
 
 
+int w_setCustomProjection(lua_State *L)
+{
+	math::Transform *transform = luax_totype<math::Transform>(L, 1);
+	if (transform != nullptr)
+	{
+		instance()->setCustomProjection(transform->getMatrix());
+		return 0;
+	}
+
+	math::Transform::MatrixLayout layout = math::Transform::MATRIX_ROW_MAJOR;
+
+	int idx = 1;
+	if (lua_type(L, idx) == LUA_TSTRING)
+	{
+		const char* layoutstr = lua_tostring(L, idx);
+		if (!math::Transform::getConstant(layoutstr, layout))
+			return luax_enumerror(L, "matrix layout", math::Transform::getConstants(layout), layoutstr);
+
+		idx++;
+	}
+
+	float elements[16];
+	love::math::luax_checkmatrix(L, idx, layout, elements);
+
+	instance()->setCustomProjection(Matrix4(elements));
+	return 0;
+}
+
 int w_resetProjection(lua_State */*L*/)
 int w_resetProjection(lua_State */*L*/)
 {
 {
 	instance()->resetProjection();
 	instance()->resetProjection();
@@ -4052,6 +4080,7 @@ static const luaL_Reg functions[] =
 	{ "transformPoint", w_transformPoint },
 	{ "transformPoint", w_transformPoint },
 	{ "inverseTransformPoint", w_inverseTransformPoint },
 	{ "inverseTransformPoint", w_inverseTransformPoint },
 
 
+	{ "setCustomProjection", w_setCustomProjection },
 	{ "resetProjection", w_resetProjection },
 	{ "resetProjection", w_resetProjection },
 
 
 	// Deprecated
 	// Deprecated

+ 95 - 92
src/modules/math/wrap_Transform.cpp

@@ -30,6 +30,99 @@ Transform *luax_checktransform(lua_State *L, int idx)
 	return luax_checktype<Transform>(L, idx, Transform::type);
 	return luax_checktype<Transform>(L, idx, Transform::type);
 }
 }
 
 
+void luax_checkmatrix(lua_State *L, int idx, Transform::MatrixLayout layout, float elements[16])
+{
+	bool columnmajor = layout == Transform::MATRIX_COLUMN_MAJOR;
+
+	if (lua_istable(L, idx))
+	{
+		lua_rawgeti(L, idx, 1);
+		bool tableoftables = lua_istable(L, -1);
+		lua_pop(L, 1);
+
+		if (tableoftables)
+		{
+			if (columnmajor)
+			{
+				for (int column = 0; column < 4; column++)
+				{
+					lua_rawgeti(L, idx, column + 1);
+
+					for (int row = 0; row < 4; row++)
+					{
+						lua_rawgeti(L, -(row + 1), row + 1);
+						elements[column * 4 + row] = (float) luaL_checknumber(L, -1);
+					}
+
+					lua_pop(L, 4 + 1);
+				}
+			}
+			else
+			{
+				for (int row = 0; row < 4; row++)
+				{
+					lua_rawgeti(L, idx, row + 1);
+
+					for (int column = 0; column < 4; column++)
+					{
+						// The table has the matrix elements laid out in row-major
+						// order, but we need to store them column-major in memory.
+						lua_rawgeti(L, -(column + 1), column + 1);
+						elements[column * 4 + row] = (float) luaL_checknumber(L, -1);
+					}
+
+					lua_pop(L, 4 + 1);
+				}
+			}
+		}
+		else
+		{
+			if (columnmajor)
+			{
+				for (int column = 0; column < 4; column++)
+				{
+					for (int row = 0; row < 4; row++)
+					{
+						lua_rawgeti(L, idx, column * 4 + row + 1);
+						elements[column * 4 + row] = (float) luaL_checknumber(L, -1);
+					}
+				}
+			}
+			else
+			{
+				for (int column = 0; column < 4; column++)
+				{
+					for (int row = 0; row < 4; row++)
+					{
+						// The table has the matrix elements laid out in row-major
+						// order, but we need to store them column-major in memory.
+						lua_rawgeti(L, idx, row * 4 + column + 1);
+						elements[column * 4 + row] = (float) luaL_checknumber(L, -1);
+					}
+				}
+			}
+
+			lua_pop(L, 16);
+		}
+	}
+	else
+	{
+		if (columnmajor)
+		{
+			for (int i = 0; i < 16; i++)
+				elements[i] = (float) luaL_checknumber(L, idx + i);
+		}
+		else
+		{
+			for (int column = 0; column < 4; column++)
+			{
+				for (int row = 0; row < 4; row++)
+					elements[column * 4 + row] = (float) luaL_checknumber(L, row * 4 + column + idx);
+			}
+		}
+	}
+}
+
 int w_Transform_clone(lua_State *L)
 int w_Transform_clone(lua_State *L)
 {
 {
 	Transform *t = luax_checktransform(L, 1);
 	Transform *t = luax_checktransform(L, 1);
@@ -131,110 +224,20 @@ int w_Transform_setTransformation(lua_State *L)
 int w_Transform_setMatrix(lua_State *L)
 int w_Transform_setMatrix(lua_State *L)
 {
 {
 	Transform *t = luax_checktransform(L, 1);
 	Transform *t = luax_checktransform(L, 1);
-
-	bool columnmajor = false;
+	Transform::MatrixLayout layout = Transform::MATRIX_ROW_MAJOR;
 
 
 	int idx = 2;
 	int idx = 2;
 	if (lua_type(L, idx) == LUA_TSTRING)
 	if (lua_type(L, idx) == LUA_TSTRING)
 	{
 	{
 		const char *layoutstr = lua_tostring(L, idx);
 		const char *layoutstr = lua_tostring(L, idx);
-		Transform::MatrixLayout layout;
 		if (!Transform::getConstant(layoutstr, layout))
 		if (!Transform::getConstant(layoutstr, layout))
 			return luax_enumerror(L, "matrix layout", Transform::getConstants(layout), layoutstr);
 			return luax_enumerror(L, "matrix layout", Transform::getConstants(layout), layoutstr);
 
 
-		columnmajor = (layout == Transform::MATRIX_COLUMN_MAJOR);
 		idx++;
 		idx++;
 	}
 	}
 
 
 	float elements[16];
 	float elements[16];
-
-	if (lua_istable(L, idx))
-	{
-		lua_rawgeti(L, idx, 1);
-		bool tableoftables = lua_istable(L, -1);
-		lua_pop(L, 1);
-
-		if (tableoftables)
-		{
-			if (columnmajor)
-			{
-				for (int column = 0; column < 4; column++)
-				{
-					lua_rawgeti(L, idx, column + 1);
-
-					for (int row = 0; row < 4; row++)
-					{
-						lua_rawgeti(L, -(row + 1), row + 1);
-						elements[column * 4 + row] = (float) luaL_checknumber(L, -1);
-					}
-
-					lua_pop(L, 4 + 1);
-				}
-			}
-			else
-			{
-				for (int row = 0; row < 4; row++)
-				{
-					lua_rawgeti(L, idx, row + 1);
-
-					for (int column = 0; column < 4; column++)
-					{
-						// The table has the matrix elements laid out in row-major
-						// order, but we need to store them column-major in memory.
-						lua_rawgeti(L, -(column + 1), column + 1);
-						elements[column * 4 + row] = (float) luaL_checknumber(L, -1);
-					}
-
-					lua_pop(L, 4 + 1);
-				}
-			}
-		}
-		else
-		{
-			if (columnmajor)
-			{
-				for (int column = 0; column < 4; column++)
-				{
-					for (int row = 0; row < 4; row++)
-					{
-						lua_rawgeti(L, idx, column * 4 + row + 1);
-						elements[column * 4 + row] = (float) luaL_checknumber(L, -1);
-					}
-				}
-			}
-			else
-			{
-				for (int column = 0; column < 4; column++)
-				{
-					for (int row = 0; row < 4; row++)
-					{
-						// The table has the matrix elements laid out in row-major
-						// order, but we need to store them column-major in memory.
-						lua_rawgeti(L, idx, row * 4 + column + 1);
-						elements[column * 4 + row] = (float) luaL_checknumber(L, -1);
-					}
-				}
-			}
-
-			lua_pop(L, 16);
-		}
-	}
-	else
-	{
-		if (columnmajor)
-		{
-			for (int i = 0; i < 16; i++)
-				elements[i] = (float) luaL_checknumber(L, idx + i);
-		}
-		else
-		{
-			for (int column = 0; column < 4; column++)
-			{
-				for (int row = 0; row < 4; row++)
-					elements[column * 4 + row] = (float) luaL_checknumber(L, row * 4 + column + idx);
-			}
-		}
-	}
+	luax_checkmatrix(L, idx, layout, elements);
 
 
 	t->setMatrix(Matrix4(elements));
 	t->setMatrix(Matrix4(elements));
 	lua_pushvalue(L, 1);
 	lua_pushvalue(L, 1);

+ 1 - 0
src/modules/math/wrap_Transform.h

@@ -30,6 +30,7 @@ namespace math
 {
 {
 
 
 Transform *luax_checktransform(lua_State *L, int idx);
 Transform *luax_checktransform(lua_State *L, int idx);
+void luax_checkmatrix(lua_State *L, int idx, Transform::MatrixLayout layout, float elements[16]);
 extern "C" int luaopen_transform(lua_State *L);
 extern "C" int luaopen_transform(lua_State *L);
 
 
 } // math
 } // math