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.
This commit is contained in:
Sasha Szpakowski
2024-03-24 10:46:29 -03:00
parent 7bfbd647ba
commit 21b71d02b5
3 changed files with 125 additions and 92 deletions
+29
View File
@@ -3900,6 +3900,34 @@ int w_inverseTransformPoint(lua_State *L)
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*/)
{
instance()->resetProjection();
@@ -4052,6 +4080,7 @@ static const luaL_Reg functions[] =
{ "transformPoint", w_transformPoint },
{ "inverseTransformPoint", w_inverseTransformPoint },
{ "setCustomProjection", w_setCustomProjection },
{ "resetProjection", w_resetProjection },
// Deprecated
+95 -92
View File
@@ -30,6 +30,99 @@ Transform *luax_checktransform(lua_State *L, int idx)
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)
{
Transform *t = luax_checktransform(L, 1);
@@ -131,110 +224,20 @@ int w_Transform_setTransformation(lua_State *L)
int w_Transform_setMatrix(lua_State *L)
{
Transform *t = luax_checktransform(L, 1);
bool columnmajor = false;
Transform::MatrixLayout layout = Transform::MATRIX_ROW_MAJOR;
int idx = 2;
if (lua_type(L, idx) == LUA_TSTRING)
{
const char *layoutstr = lua_tostring(L, idx);
Transform::MatrixLayout layout;
if (!Transform::getConstant(layoutstr, layout))
return luax_enumerror(L, "matrix layout", Transform::getConstants(layout), layoutstr);
columnmajor = (layout == Transform::MATRIX_COLUMN_MAJOR);
idx++;
}
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));
lua_pushvalue(L, 1);
+1
View File
@@ -30,6 +30,7 @@ namespace math
{
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);
} // math