mirror of
https://github.com/love2d/love.git
synced 2026-08-12 16:40:57 +02:00
Fixed love.graphics.setScissor when love.graphics.setCanvas is called directly after a setScissor call
This commit is contained in:
@@ -455,7 +455,7 @@ void Canvas::setupGrab()
|
||||
// bind buffer and clear screen
|
||||
glPushAttrib(GL_VIEWPORT_BIT | GL_TRANSFORM_BIT);
|
||||
strategy->bindFBO(fbo);
|
||||
glViewport(0, 0, width, height);
|
||||
gl.setViewport(OpenGL::Viewport(0, 0, width, height));
|
||||
|
||||
// Reset the projection matrix
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
||||
@@ -96,7 +96,7 @@ DisplayState Graphics::saveState()
|
||||
s.scissor = (glIsEnabled(GL_SCISSOR_TEST) == GL_TRUE);
|
||||
//do we have scissor, if so, store the box
|
||||
if (s.scissor)
|
||||
glGetIntegerv(GL_SCISSOR_BOX, s.scissorBox);
|
||||
s.scissorBox = gl.getScissor();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
s.colorMask[i] = colorMask[i];
|
||||
@@ -116,7 +116,7 @@ void Graphics::restoreState(const DisplayState &s)
|
||||
else
|
||||
setAlphaTest();
|
||||
if (s.scissor)
|
||||
setScissor(s.scissorBox[0], s.scissorBox[1], s.scissorBox[2], s.scissorBox[3]);
|
||||
setScissor(s.scissorBox.x, s.scissorBox.y, s.scissorBox.w, s.scissorBox.h);
|
||||
else
|
||||
setScissor();
|
||||
setColorMask(s.colorMask[0], s.colorMask[1], s.colorMask[2], s.colorMask[3]);
|
||||
@@ -161,7 +161,7 @@ bool Graphics::setMode(int width, int height)
|
||||
gl.setActiveTextureUnit(0);
|
||||
|
||||
// Set the viewport to top-left corner
|
||||
glViewport(0, 0, width, height);
|
||||
gl.setViewport(OpenGL::Viewport(0, 0, width, height));
|
||||
|
||||
// Reset the projection matrix
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
@@ -266,8 +266,8 @@ bool Graphics::isCreated() const
|
||||
void Graphics::setScissor(int x, int y, int width, int height)
|
||||
{
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// Compensates for the fact that our y-coordinate is reverse of OpenGL's.
|
||||
glScissor(x, getRenderHeight() - (y + height), width, height);
|
||||
// OpenGL's reversed y-coordinate is compensated for in OpenGL::setScissor.
|
||||
gl.setScissor(OpenGL::Viewport(x, y, width, height));
|
||||
}
|
||||
|
||||
void Graphics::setScissor()
|
||||
@@ -280,13 +280,12 @@ int Graphics::getScissor(lua_State *L) const
|
||||
if (glIsEnabled(GL_SCISSOR_TEST) == GL_FALSE)
|
||||
return 0;
|
||||
|
||||
GLint scissor[4];
|
||||
glGetIntegerv(GL_SCISSOR_BOX, scissor);
|
||||
OpenGL::Viewport scissor = gl.getScissor();
|
||||
|
||||
lua_pushnumber(L, scissor[0]);
|
||||
lua_pushnumber(L, getRenderHeight() - (scissor[1] + scissor[3])); // Compensates for the fact that our y-coordinate is reverse of OpenGLs.
|
||||
lua_pushnumber(L, scissor[2]);
|
||||
lua_pushnumber(L, scissor[3]);
|
||||
lua_pushinteger(L, scissor.x);
|
||||
lua_pushinteger(L, scissor.y);
|
||||
lua_pushinteger(L, scissor.w);
|
||||
lua_pushinteger(L, scissor.h);
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ struct DisplayState
|
||||
|
||||
// Scissor.
|
||||
bool scissor;
|
||||
GLint scissorBox[4];
|
||||
OpenGL::Viewport scissorBox;
|
||||
|
||||
// Color mask.
|
||||
bool colorMask[4];
|
||||
|
||||
@@ -64,6 +64,14 @@ void OpenGL::initContext()
|
||||
state.clearColor.b = glcolor[2] * 255;
|
||||
state.clearColor.a = glcolor[3] * 255;
|
||||
|
||||
// Get the current viewport.
|
||||
glGetIntegerv(GL_VIEWPORT, (GLint *) &state.viewport);
|
||||
|
||||
// And the current scissor - but we need to compensate for GL scissors
|
||||
// starting at the bottom left instead of top left.
|
||||
glGetIntegerv(GL_SCISSOR_BOX, (GLint *) &state.scissor);
|
||||
state.scissor.y = state.viewport.h - (state.scissor.y + state.scissor.h);
|
||||
|
||||
// Initialize multiple texture unit support for shaders, if available.
|
||||
state.textureUnits.clear();
|
||||
if (Shader::isSupported())
|
||||
@@ -187,6 +195,36 @@ Color OpenGL::getClearColor() const
|
||||
return state.clearColor;
|
||||
}
|
||||
|
||||
void OpenGL::setViewport(const OpenGL::Viewport &v)
|
||||
{
|
||||
glViewport(v.x, v.y, v.w, v.h);
|
||||
state.viewport = v;
|
||||
|
||||
// glScissor starts from the lower left, so we compensate when setting the
|
||||
// scissor. When the viewport is changed, we need to manually update the
|
||||
// scissor again.
|
||||
if (v.h != state.viewport.h)
|
||||
setScissor(state.scissor);
|
||||
}
|
||||
|
||||
OpenGL::Viewport OpenGL::getViewport() const
|
||||
{
|
||||
return state.viewport;
|
||||
}
|
||||
|
||||
void OpenGL::setScissor(const OpenGL::Viewport &v)
|
||||
{
|
||||
// We need to compensate for glScissor starting from the lower left of the
|
||||
// viewport instead of the top left.
|
||||
glScissor(v.x, state.viewport.h - (v.y + v.h), v.w, v.h);
|
||||
state.scissor = v;
|
||||
}
|
||||
|
||||
OpenGL::Viewport OpenGL::getScissor() const
|
||||
{
|
||||
return state.scissor;
|
||||
}
|
||||
|
||||
void OpenGL::setActiveTextureUnit(int textureunit)
|
||||
{
|
||||
if (textureunit < 0 || (size_t) textureunit >= state.textureUnits.size())
|
||||
|
||||
@@ -48,6 +48,21 @@ class OpenGL
|
||||
{
|
||||
public:
|
||||
|
||||
// A rectangle representing an OpenGL viewport or a scissor box.
|
||||
struct Viewport
|
||||
{
|
||||
int x, y;
|
||||
int w, h;
|
||||
|
||||
Viewport()
|
||||
: x(0), y(0), w(0), h(0)
|
||||
{}
|
||||
|
||||
Viewport(int _x, int _y, int _w, int _h)
|
||||
: x(_x), y(_y), w(_w), h(_h)
|
||||
{}
|
||||
};
|
||||
|
||||
OpenGL();
|
||||
|
||||
/**
|
||||
@@ -83,6 +98,28 @@ public:
|
||||
**/
|
||||
Color getClearColor() const;
|
||||
|
||||
/**
|
||||
* Sets the OpenGL rendering viewport to the specified rectangle.
|
||||
* The y-coordinate starts at the top.
|
||||
**/
|
||||
void setViewport(const Viewport &v);
|
||||
|
||||
/**
|
||||
* Gets the current OpenGL rendering viewport rectangle.
|
||||
**/
|
||||
Viewport getViewport() const;
|
||||
|
||||
/**
|
||||
* Sets the scissor box to the specified rectangle.
|
||||
* The y-coordinate starts at the top and is flipped internally.
|
||||
**/
|
||||
void setScissor(const Viewport &v);
|
||||
|
||||
/**
|
||||
* Gets the current scissor box (regardless of whether scissoring is enabled.)
|
||||
**/
|
||||
Viewport getScissor() const;
|
||||
|
||||
/**
|
||||
* Helper for setting the active texture unit.
|
||||
*
|
||||
@@ -153,6 +190,9 @@ private:
|
||||
// Currently active texture unit.
|
||||
int curTextureUnit;
|
||||
|
||||
Viewport viewport;
|
||||
Viewport scissor;
|
||||
|
||||
} state;
|
||||
|
||||
}; // OpenGL
|
||||
|
||||
Reference in New Issue
Block a user