glClearBufferiv not clearing fbo attachment

Hi,

I have the following situation: I have created a custom FBO and attached 2 color buffers to it:

//1st Color buffer

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);

//2nd Color buffer

glTexImage2D(GL_TEXTURE_2D, 0, GL_R32I, width, height, 0, GL_RED_INTEGER, GL_INT, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, texId, 0);

And bound them with glDrawBuffers

GLenum buffers[]{ GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
glDrawBuffers(2, buffers)

I am using the 2nd color buffer write Ids to from one of the fragment shader (there are other shaders used in the render pass, but they don’t write to the second buffer):

//mesh_shader.frag
#version 330 core

layout(location = 0) out vec4 FragColor;
layout(location = 1) out int Id;
...
Id = -50 //Checking that I can write to it.

I am able to successfully write to the 2nd color buffer, however I am not able to clear it. I want to clear all of the values in that buffer to -1 so I can easily distinguish valid Ids.
I am using glClearBuffer to do this:

//Clearing 1st Color buffer
static const float[] = {0.0f, 0.0f, 0.0f, 0.0f,};
glClearBufferfv(GL_COLOR, 0, clear_color)

//Clearing 2nd Color buffer
static const GLint clear_int = { -1, -1, -1, -1 };
glClearBufferiv(GL_COLOR, 1, &clear_int[0])

When I read from the 2nd Color buffer using the mouse position, I get -50 when I am over geometry rendered by mesh_shader.frag (like I should), but random numbers ( like: 1057630335, 1057423894, etc) for the rest of the scene.

It seems that glClearBufferiv hasn’t cleared the buffer.

All of my gl function calls are wrapped a macro which checks glGetError(), but I am not getting any errors. Everything else is working appart from clearing the 2nd Color buffer.

Does anyone have any idea what is going wrong? Any help will be greatly appreciated!

On reason glClear() related APIs might not perform the clear operation for a pixel/region is that they honor certain fragment tests:

For instance, try disabling scissor test and make sure that the color buffer writemask is fully enabled for that buffer.

Also, I’m no C++ guru, but there appear to be some possible errors in your clear snippet. Did you mean to do something like this?:

//Clearing 1st Color buffer
static const float clear_color[] = {0.0f, 0.0f, 0.0f, 0.0f,};
glClearBufferfv(GL_COLOR, 0, clear_color)

//Clearing 2nd Color buffer
static const GLint clear_int[] = { -1, -1, -1, -1 };
glClearBufferiv(GL_COLOR, 1, clear_int)

Note addition of clear_color name on COLOR0 clear color, change of clear_int to be array, and change of clear_int arg to glClearBufferiv().

Yes, that’s the problem (or at least “a” problem). Here on Linux with GCC, your clear_int decl results in this error:

tst2.cpp: In function 'int main()':
tst2.cpp:6:24: error: scalar object 'clear_int' requires one element in initializer
     static const GLint clear_int = { -1, -1, -1, -1 };
                        ^~~~~~~~~

You’re declaring a single int, not an int[4].

What compiler did you use that accepted your syntax?

Hi,

Thank you for answering. That was just an issue the snippet. My actual code didn’t have this.

I tried your suggestion with disabling the scissor test and making sure that buffer write mask is full enabled, but that didn’t work. I am still getting the same random numbers.

I also tried disabling all rendering, but still clearing the framebuffer every frame - this actually worked and I was able to get -1 when reading from the buffer. So glClearBufferiv works.

I managed to narrow down the exact shader that is causing problems:

//Vertex Shader
#version 330 core

layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;

out vec3 Color;

uniform mat4 Projection;
uniform mat4 View;

void main()
{
	gl_Position = Projection * View * vec4(aPos, 1.0);
	Color = aColor;
}

//Fragment Shader
#version 330 core

layout(location = 0) out vec4 FragColor;

in vec3 Color;

void main()
{
	FragColor = vec4(Color, 1.0f);
}

It’s dead simple and is used to draw a sphere around the camera.

When the sphere is drawn glDepthMask(GL_FALSE) is called. Could this be causing this shader to write to the second color attachment?

Potentially. Not the shader itself. But the rasterization process in general.

What glDrawBuffers() setting do you have active when you are rasterizing to your “2 COLOR” FBO with this “1 COLOR output” shader program? It should only contain GL_COLOR_ATTACHMENT0.

While the man page I linked to isn’t the GL spec, it mentions this and what happens if violated: