mirror of
https://github.com/love2d/love.git
synced 2026-08-18 03:34:23 +02:00
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.
This commit is contained in:
@@ -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();
|
||||
|
||||
// Implements Module.
|
||||
|
||||
@@ -110,7 +110,7 @@ void Graphics::restoreState(const DisplayState &s)
|
||||
setPointSize(s.pointSize);
|
||||
|
||||
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
|
||||
setScissor();
|
||||
|
||||
@@ -147,10 +147,10 @@ void Graphics::restoreStateChecked(const DisplayState &s)
|
||||
if (s.pointSize != cur.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)
|
||||
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
|
||||
setScissor();
|
||||
}
|
||||
@@ -580,14 +580,35 @@ bool Graphics::isCreated() const
|
||||
|
||||
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);
|
||||
// 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().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()
|
||||
@@ -600,10 +621,10 @@ bool Graphics::getScissor(int &x, int &y, int &width, int &height) const
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -126,6 +126,8 @@ public:
|
||||
**/
|
||||
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.
|
||||
**/
|
||||
@@ -478,7 +480,7 @@ private:
|
||||
float pointSize = 1.0f;
|
||||
|
||||
bool scissor = false;
|
||||
OpenGL::Viewport scissorBox = OpenGL::Viewport();
|
||||
ScissorRect scissorRect = ScissorRect();
|
||||
|
||||
// Stencil.
|
||||
bool stencilTest = false;
|
||||
|
||||
@@ -184,6 +184,20 @@ int w_setScissor(lua_State *L)
|
||||
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 x, y, w, h;
|
||||
@@ -1899,6 +1913,7 @@ static const luaL_Reg functions[] =
|
||||
{ "getDimensions", w_getDimensions },
|
||||
|
||||
{ "setScissor", w_setScissor },
|
||||
{ "intersectScissor", w_intersectScissor },
|
||||
{ "getScissor", w_getScissor },
|
||||
|
||||
{ "stencil", w_stencil },
|
||||
|
||||
@@ -52,6 +52,7 @@ int w_getWidth(lua_State *L);
|
||||
int w_getHeight(lua_State *L);
|
||||
int w_getDimensions(lua_State *L);
|
||||
int w_setScissor(lua_State *L);
|
||||
int w_intersectScissor(lua_State *L);
|
||||
int w_getScissor(lua_State *L);
|
||||
int w_stencil(lua_State *L);
|
||||
int w_setStencilTest(lua_State *L);
|
||||
|
||||
Reference in New Issue
Block a user