mirror of
https://github.com/love2d/love.git
synced 2026-08-16 00:02:12 +02:00
opengl: scissor and color mask no longer affects love.graphics.clear.
This makes it more consistent with other backends.
This commit is contained in:
@@ -922,36 +922,23 @@ void Graphics::clear(OptionalColorD c, OptionalInt stencil, OptionalDouble depth
|
||||
flags |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
uint32 stencilwrites = gl.getStencilWriteMask();
|
||||
|
||||
if (stencil.hasValue)
|
||||
{
|
||||
if (stencilwrites != LOVE_UINT32_MAX)
|
||||
gl.setStencilWriteMask(LOVE_UINT32_MAX);
|
||||
|
||||
glClearStencil(stencil.value);
|
||||
flags |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
bool hadDepthWrites = gl.hasDepthWrites();
|
||||
|
||||
if (depth.hasValue)
|
||||
{
|
||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
||||
gl.setDepthWrites(true);
|
||||
|
||||
gl.clearDepth(depth.value);
|
||||
flags |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (flags != 0)
|
||||
{
|
||||
OpenGL::CleanClearState cs(flags);
|
||||
glClear(flags);
|
||||
|
||||
if (stencil.hasValue && stencilwrites != LOVE_UINT32_MAX)
|
||||
gl.setStencilWriteMask(stencilwrites);
|
||||
|
||||
if (depth.hasValue && !hadDepthWrites)
|
||||
gl.setDepthWrites(hadDepthWrites);
|
||||
}
|
||||
|
||||
if (c.hasValue && gl.bugs.clearRequiresDriverTextureStateUpdate && Shader::current)
|
||||
{
|
||||
@@ -1041,36 +1028,23 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
|
||||
|
||||
GLbitfield flags = 0;
|
||||
|
||||
uint32 stencilwrites = gl.getStencilWriteMask();
|
||||
|
||||
if (stencil.hasValue)
|
||||
{
|
||||
if (stencilwrites != LOVE_UINT32_MAX)
|
||||
gl.setStencilWriteMask(LOVE_UINT32_MAX);
|
||||
|
||||
glClearStencil(stencil.value);
|
||||
flags |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
|
||||
bool hadDepthWrites = gl.hasDepthWrites();
|
||||
|
||||
if (depth.hasValue)
|
||||
{
|
||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
||||
gl.setDepthWrites(true);
|
||||
|
||||
gl.clearDepth(depth.value);
|
||||
flags |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if (flags != 0)
|
||||
{
|
||||
OpenGL::CleanClearState cs(flags);
|
||||
glClear(flags);
|
||||
|
||||
if (stencil.hasValue && stencilwrites != LOVE_UINT32_MAX)
|
||||
gl.setStencilWriteMask(stencilwrites);
|
||||
|
||||
if (depth.hasValue && !hadDepthWrites)
|
||||
gl.setDepthWrites(hadDepthWrites);
|
||||
}
|
||||
|
||||
if (gl.bugs.clearRequiresDriverTextureStateUpdate && Shader::current)
|
||||
{
|
||||
@@ -1568,7 +1542,11 @@ void Graphics::setColorMask(ColorChannelMask mask)
|
||||
{
|
||||
flushBatchedDraws();
|
||||
|
||||
glColorMask(mask.r, mask.g, mask.b, mask.a);
|
||||
uint32 maskbits =
|
||||
((mask.r ? 1 : 0) << 1) | ((mask.g ? 1 : 0) << 2) |
|
||||
((mask.g ? 1 : 0) << 3) | ((mask.a ? 1 : 0) << 4);
|
||||
|
||||
gl.setColorWriteMask(maskbits);
|
||||
states.back().colorMask = mask;
|
||||
}
|
||||
|
||||
|
||||
@@ -91,12 +91,49 @@ OpenGL::TempDebugGroup::~TempDebugGroup()
|
||||
}
|
||||
}
|
||||
|
||||
OpenGL::CleanClearState::CleanClearState(GLbitfield clearFlags)
|
||||
: clearFlags(clearFlags)
|
||||
, colorWriteMask(gl.getColorWriteMask())
|
||||
, stencilWriteMask(gl.getStencilWriteMask())
|
||||
, depthWrites(gl.hasDepthWrites())
|
||||
, scissor(gl.isStateEnabled(ENABLE_SCISSOR_TEST))
|
||||
{
|
||||
if (clearFlags & GL_COLOR_BUFFER_BIT)
|
||||
gl.setColorWriteMask(LOVE_UINT32_MAX);
|
||||
|
||||
if (clearFlags & GL_DEPTH_BUFFER_BIT)
|
||||
gl.setDepthWrites(false);
|
||||
|
||||
if (clearFlags & GL_STENCIL_BUFFER_BIT)
|
||||
gl.setStencilWriteMask(LOVE_UINT32_MAX);
|
||||
|
||||
if (clearFlags != 0)
|
||||
gl.setEnableState(ENABLE_SCISSOR_TEST, false);
|
||||
}
|
||||
|
||||
OpenGL::CleanClearState::~CleanClearState()
|
||||
{
|
||||
if (clearFlags & GL_COLOR_BUFFER_BIT)
|
||||
gl.setColorWriteMask(colorWriteMask);
|
||||
|
||||
if (clearFlags & GL_DEPTH_BUFFER_BIT)
|
||||
gl.setDepthWrites(depthWrites);
|
||||
|
||||
if (clearFlags & GL_STENCIL_BUFFER_BIT)
|
||||
gl.setStencilWriteMask(stencilWriteMask);
|
||||
|
||||
if (clearFlags != 0)
|
||||
gl.setEnableState(ENABLE_SCISSOR_TEST, scissor);
|
||||
}
|
||||
|
||||
OpenGL::OpenGL()
|
||||
: stats()
|
||||
, bugs()
|
||||
, contextInitialized(false)
|
||||
, pixelShaderHighpSupported(false)
|
||||
, baseVertexSupported(false)
|
||||
, maxAnisotropy(1.0f)
|
||||
, maxLODBias(0.0f)
|
||||
, max2DTextureSize(0)
|
||||
, max3DTextureSize(0)
|
||||
, maxCubeTextureSize(0)
|
||||
@@ -284,6 +321,7 @@ void OpenGL::setupContext()
|
||||
|
||||
setDepthWrites(state.depthWritesEnabled);
|
||||
setStencilWriteMask(state.stencilWriteMask);
|
||||
setColorWriteMask(state.colorWriteMask);
|
||||
|
||||
createDefaultTexture();
|
||||
|
||||
@@ -1125,6 +1163,17 @@ uint32 OpenGL::getStencilWriteMask() const
|
||||
return state.stencilWriteMask;
|
||||
}
|
||||
|
||||
void OpenGL::setColorWriteMask(uint32 mask)
|
||||
{
|
||||
glColorMask(mask & (1 << 0), mask & (1 << 1), mask & (1 << 2), mask & (1 << 3));
|
||||
state.colorWriteMask = mask;
|
||||
}
|
||||
|
||||
uint32 OpenGL::getColorWriteMask() const
|
||||
{
|
||||
return state.colorWriteMask;
|
||||
}
|
||||
|
||||
void OpenGL::useProgram(GLuint program)
|
||||
{
|
||||
glUseProgram(program);
|
||||
|
||||
@@ -124,6 +124,21 @@ public:
|
||||
~TempDebugGroup();
|
||||
};
|
||||
|
||||
// glClear() is affected by various OpenGL state...
|
||||
class CleanClearState
|
||||
{
|
||||
public:
|
||||
CleanClearState(GLbitfield clearFlags);
|
||||
~CleanClearState();
|
||||
|
||||
private:
|
||||
GLenum clearFlags;
|
||||
uint32 colorWriteMask;
|
||||
uint32 stencilWriteMask;
|
||||
bool depthWrites;
|
||||
bool scissor;
|
||||
};
|
||||
|
||||
struct Stats
|
||||
{
|
||||
int shaderSwitches;
|
||||
@@ -301,6 +316,9 @@ public:
|
||||
void setStencilWriteMask(uint32 mask);
|
||||
uint32 getStencilWriteMask() const;
|
||||
|
||||
void setColorWriteMask(uint32 mask);
|
||||
uint32 getColorWriteMask() const;
|
||||
|
||||
/**
|
||||
* Calls glUseProgram.
|
||||
**/
|
||||
@@ -528,6 +546,7 @@ private:
|
||||
|
||||
bool depthWritesEnabled = true;
|
||||
uint32 stencilWriteMask = LOVE_UINT32_MAX;
|
||||
uint32 colorWriteMask = LOVE_UINT32_MAX;
|
||||
|
||||
GLuint boundFramebuffers[2];
|
||||
|
||||
|
||||
@@ -80,31 +80,22 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
||||
|
||||
if (clear)
|
||||
{
|
||||
if (isPixelFormatDepthStencil(format))
|
||||
bool ds = isPixelFormatDepthStencil(format);
|
||||
|
||||
GLbitfield clearflags = ds ? GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT : GL_COLOR_BUFFER_BIT;
|
||||
OpenGL::CleanClearState cleanClearState(clearflags);
|
||||
|
||||
if (ds)
|
||||
{
|
||||
bool hadDepthWrites = gl.hasDepthWrites();
|
||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
||||
gl.setDepthWrites(true);
|
||||
|
||||
uint32 stencilwrite = gl.getStencilWriteMask();
|
||||
if (stencilwrite != LOVE_UINT32_MAX)
|
||||
gl.setStencilWriteMask(LOVE_UINT32_MAX);
|
||||
|
||||
gl.clearDepth(1.0);
|
||||
glClearStencil(0);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
if (!hadDepthWrites)
|
||||
gl.setDepthWrites(hadDepthWrites);
|
||||
|
||||
if (stencilwrite != LOVE_UINT32_MAX)
|
||||
gl.setStencilWriteMask(stencilwrite);
|
||||
}
|
||||
else
|
||||
{
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
glClear(clearflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -167,25 +158,23 @@ static GLenum newRenderbuffer(int width, int height, int &samples, PixelFormat p
|
||||
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
if (isPixelFormatDepthStencil(pixelformat))
|
||||
{
|
||||
bool hadDepthWrites = gl.hasDepthWrites();
|
||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
||||
gl.setDepthWrites(true);
|
||||
bool ds = isPixelFormatDepthStencil(pixelformat);
|
||||
|
||||
GLbitfield clearflags = ds ? GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT : GL_COLOR_BUFFER_BIT;
|
||||
OpenGL::CleanClearState cleanClearState(clearflags);
|
||||
|
||||
if (ds)
|
||||
{
|
||||
gl.clearDepth(1.0);
|
||||
glClearStencil(0);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
if (!hadDepthWrites)
|
||||
gl.setDepthWrites(hadDepthWrites);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Initialize the buffer to transparent black.
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
glClear(clearflags);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user