Fixed love.graphics.setScissor when love.graphics.setCanvas is called directly after a setScissor call

This commit is contained in:
Alex Szpakowski
2013-06-07 03:31:30 -03:00
parent 1482b13363
commit c0998cd996
5 changed files with 90 additions and 13 deletions
+1 -1
View File
@@ -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);
+10 -11
View File
@@ -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;
}
+1 -1
View File
@@ -80,7 +80,7 @@ struct DisplayState
// Scissor.
bool scissor;
GLint scissorBox[4];
OpenGL::Viewport scissorBox;
// Color mask.
bool colorMask[4];
+38
View File
@@ -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())
+40
View File
@@ -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