Skip to content

Commit

Permalink
opengl: fix clearing integer format Canvases.
Browse files Browse the repository at this point in the history
  • Loading branch information
slime73 committed Oct 9, 2023
1 parent b8cbb62 commit 2789e5e
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 13 deletions.
24 changes: 24 additions & 0 deletions src/modules/graphics/opengl/Graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,30 @@ void Graphics::endPass(bool presenting)

void Graphics::clear(OptionalColorD c, OptionalInt stencil, OptionalDouble depth)
{
if (c.hasValue)
{
bool hasintegerformat = false;

const auto &rts = states.back().renderTargets;
for (const auto &rt : rts.colors)
{
if (rt.texture.get() && isPixelFormatInteger(rt.texture->getPixelFormat()))
hasintegerformat = true;
}

// This variant of clear() uses glClear() which can't clear integer formats,
// so we switch to the MRT variant if needed.
if (hasintegerformat)
{
std::vector<OptionalColorD> colors(rts.colors.size());
for (size_t i = 0; i < colors.size(); i++)
colors[i] = c;

clear(colors, stencil, depth);
return;
}
}

if (c.hasValue || stencil.hasValue || depth.hasValue)
flushBatchedDraws();

Expand Down
57 changes: 44 additions & 13 deletions src/modules/graphics/opengl/Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,21 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
gl.framebufferTexture(attachment, texType, texture, mip, layer, face);
}

if (clear)
if (clear && isPixelFormatInteger(format))
{
PixelFormatType datatype = getPixelFormatInfo(format).dataType;
if (datatype == PIXELFORMATTYPE_SINT)
{
const GLint carray[] = { 0, 0, 0, 0 };
glClearBufferiv(GL_COLOR, 0, carray);
}
else
{
const GLuint carray[] = { 0, 0, 0, 0 };
glClearBufferuiv(GL_COLOR, 0, carray);
}
}
else if (clear)
{
bool ds = isPixelFormatDepthStencil(format);

Expand Down Expand Up @@ -158,23 +172,40 @@ static GLenum newRenderbuffer(int width, int height, int &samples, PixelFormat p

if (status == GL_FRAMEBUFFER_COMPLETE)
{
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)
if (isPixelFormatInteger(pixelformat))
{
gl.clearDepth(1.0);
glClearStencil(0);
PixelFormatType datatype = getPixelFormatInfo(pixelformat).dataType;
if (datatype == PIXELFORMATTYPE_SINT)
{
const GLint carray[] = { 0, 0, 0, 0 };
glClearBufferiv(GL_COLOR, 0, carray);
}
else
{
const GLuint carray[] = { 0, 0, 0, 0 };
glClearBufferuiv(GL_COLOR, 0, carray);
}
}
else
{
// Initialize the buffer to transparent black.
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
bool ds = isPixelFormatDepthStencil(pixelformat);

glClear(clearflags);
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);
}
else
{
// Initialize the buffer to transparent black.
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}

glClear(clearflags);
}
}
else
{
Expand Down

0 comments on commit 2789e5e

Please sign in to comment.