mirror of
https://github.com/love2d/love.git
synced 2026-08-17 11:00:31 +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;
|
flags |= GL_COLOR_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 stencilwrites = gl.getStencilWriteMask();
|
|
||||||
|
|
||||||
if (stencil.hasValue)
|
if (stencil.hasValue)
|
||||||
{
|
{
|
||||||
if (stencilwrites != LOVE_UINT32_MAX)
|
|
||||||
gl.setStencilWriteMask(LOVE_UINT32_MAX);
|
|
||||||
|
|
||||||
glClearStencil(stencil.value);
|
glClearStencil(stencil.value);
|
||||||
flags |= GL_STENCIL_BUFFER_BIT;
|
flags |= GL_STENCIL_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hadDepthWrites = gl.hasDepthWrites();
|
|
||||||
|
|
||||||
if (depth.hasValue)
|
if (depth.hasValue)
|
||||||
{
|
{
|
||||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
|
||||||
gl.setDepthWrites(true);
|
|
||||||
|
|
||||||
gl.clearDepth(depth.value);
|
gl.clearDepth(depth.value);
|
||||||
flags |= GL_DEPTH_BUFFER_BIT;
|
flags |= GL_DEPTH_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags != 0)
|
if (flags != 0)
|
||||||
|
{
|
||||||
|
OpenGL::CleanClearState cs(flags);
|
||||||
glClear(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)
|
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;
|
GLbitfield flags = 0;
|
||||||
|
|
||||||
uint32 stencilwrites = gl.getStencilWriteMask();
|
|
||||||
|
|
||||||
if (stencil.hasValue)
|
if (stencil.hasValue)
|
||||||
{
|
{
|
||||||
if (stencilwrites != LOVE_UINT32_MAX)
|
|
||||||
gl.setStencilWriteMask(LOVE_UINT32_MAX);
|
|
||||||
|
|
||||||
glClearStencil(stencil.value);
|
glClearStencil(stencil.value);
|
||||||
flags |= GL_STENCIL_BUFFER_BIT;
|
flags |= GL_STENCIL_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hadDepthWrites = gl.hasDepthWrites();
|
|
||||||
|
|
||||||
if (depth.hasValue)
|
if (depth.hasValue)
|
||||||
{
|
{
|
||||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
|
||||||
gl.setDepthWrites(true);
|
|
||||||
|
|
||||||
gl.clearDepth(depth.value);
|
gl.clearDepth(depth.value);
|
||||||
flags |= GL_DEPTH_BUFFER_BIT;
|
flags |= GL_DEPTH_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags != 0)
|
if (flags != 0)
|
||||||
|
{
|
||||||
|
OpenGL::CleanClearState cs(flags);
|
||||||
glClear(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)
|
if (gl.bugs.clearRequiresDriverTextureStateUpdate && Shader::current)
|
||||||
{
|
{
|
||||||
@@ -1568,7 +1542,11 @@ void Graphics::setColorMask(ColorChannelMask mask)
|
|||||||
{
|
{
|
||||||
flushBatchedDraws();
|
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;
|
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()
|
OpenGL::OpenGL()
|
||||||
: stats()
|
: stats()
|
||||||
|
, bugs()
|
||||||
, contextInitialized(false)
|
, contextInitialized(false)
|
||||||
, pixelShaderHighpSupported(false)
|
, pixelShaderHighpSupported(false)
|
||||||
, baseVertexSupported(false)
|
, baseVertexSupported(false)
|
||||||
, maxAnisotropy(1.0f)
|
, maxAnisotropy(1.0f)
|
||||||
|
, maxLODBias(0.0f)
|
||||||
, max2DTextureSize(0)
|
, max2DTextureSize(0)
|
||||||
, max3DTextureSize(0)
|
, max3DTextureSize(0)
|
||||||
, maxCubeTextureSize(0)
|
, maxCubeTextureSize(0)
|
||||||
@@ -284,6 +321,7 @@ void OpenGL::setupContext()
|
|||||||
|
|
||||||
setDepthWrites(state.depthWritesEnabled);
|
setDepthWrites(state.depthWritesEnabled);
|
||||||
setStencilWriteMask(state.stencilWriteMask);
|
setStencilWriteMask(state.stencilWriteMask);
|
||||||
|
setColorWriteMask(state.colorWriteMask);
|
||||||
|
|
||||||
createDefaultTexture();
|
createDefaultTexture();
|
||||||
|
|
||||||
@@ -1125,6 +1163,17 @@ uint32 OpenGL::getStencilWriteMask() const
|
|||||||
return state.stencilWriteMask;
|
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)
|
void OpenGL::useProgram(GLuint program)
|
||||||
{
|
{
|
||||||
glUseProgram(program);
|
glUseProgram(program);
|
||||||
|
|||||||
@@ -124,6 +124,21 @@ public:
|
|||||||
~TempDebugGroup();
|
~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
|
struct Stats
|
||||||
{
|
{
|
||||||
int shaderSwitches;
|
int shaderSwitches;
|
||||||
@@ -301,6 +316,9 @@ public:
|
|||||||
void setStencilWriteMask(uint32 mask);
|
void setStencilWriteMask(uint32 mask);
|
||||||
uint32 getStencilWriteMask() const;
|
uint32 getStencilWriteMask() const;
|
||||||
|
|
||||||
|
void setColorWriteMask(uint32 mask);
|
||||||
|
uint32 getColorWriteMask() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls glUseProgram.
|
* Calls glUseProgram.
|
||||||
**/
|
**/
|
||||||
@@ -528,6 +546,7 @@ private:
|
|||||||
|
|
||||||
bool depthWritesEnabled = true;
|
bool depthWritesEnabled = true;
|
||||||
uint32 stencilWriteMask = LOVE_UINT32_MAX;
|
uint32 stencilWriteMask = LOVE_UINT32_MAX;
|
||||||
|
uint32 colorWriteMask = LOVE_UINT32_MAX;
|
||||||
|
|
||||||
GLuint boundFramebuffers[2];
|
GLuint boundFramebuffers[2];
|
||||||
|
|
||||||
|
|||||||
@@ -80,31 +80,22 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
|||||||
|
|
||||||
if (clear)
|
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);
|
gl.clearDepth(1.0);
|
||||||
glClearStencil(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
|
else
|
||||||
{
|
{
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
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 (status == GL_FRAMEBUFFER_COMPLETE)
|
||||||
{
|
{
|
||||||
if (isPixelFormatDepthStencil(pixelformat))
|
bool ds = isPixelFormatDepthStencil(pixelformat);
|
||||||
{
|
|
||||||
bool hadDepthWrites = gl.hasDepthWrites();
|
|
||||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
|
||||||
gl.setDepthWrites(true);
|
|
||||||
|
|
||||||
|
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);
|
gl.clearDepth(1.0);
|
||||||
glClearStencil(0);
|
glClearStencil(0);
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
||||||
|
|
||||||
if (!hadDepthWrites)
|
|
||||||
gl.setDepthWrites(hadDepthWrites);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Initialize the buffer to transparent black.
|
// Initialize the buffer to transparent black.
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glClear(clearflags);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user