Using multiple GL_COLOR_ATTACHMENT in the shader

Hello,

i’ve tried using the multiple GL_COLOR_ATTACHMENT in the FBO to render more than 1 texture at once (as in an MRT) but using shader version 120.

my questions are:

does it work with this version? if so how?

I’m currently using the following:

  • Create 2 FBOs:
    • multisampledFBO
    • finalFBO (2 render buffers)
        glBindFramebuffer(GL_FRAMEBUFFER, multisampledFbo);

        glBindRenderbuffer(GL_RENDERBUFFER, color1RenderBuffer);
        glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color1RenderBuffer);
        
        glBindRenderbuffer(GL_RENDERBUFFER, color1RenderBuffer);
        glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, color2RenderBuffer);

        // ATTACH TEXTURE 1
		glBindFramebuffer(GL_FRAMEBUFFER, finalFbo);
        glBindTexture(GL_TEXTURE_2D, textureColor);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer) null);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColor, 0);

        // ATTACH TEXTURE 2
		glBindFramebuffer(GL_FRAMEBUFFER, finalFbo);
        glBindTexture(GL_TEXTURE_2D, textureDepth);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (ByteBuffer) null);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textureDepth, 0);
  • Render all objects to a multisampledFBO using the frag shader #1:
varying out vec4 outColor1;
varying out vec4 outColor2;

void main (void){
    ...
	outColor1 = vec4(1.0, 0.0, 0.0, 1.0);
	outColor2 = vec4(1.0, 1.0, 0.0, 1.0);
}
  • Copy multisampledFBO to a FinalFBO
        glBindFramebuffer(GL_READ_FRAMEBUFFER, multisampledFbo);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, finalFbo);
        glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
  • And then render everything to a quad using the frag shader #2:
uniform sampler2D texture1;
uniform sampler2D texture2;

void main (void){
	vec4 color1  = texture2D(texture1, vTex);
	vec4 color2   = texture2D(texture1, vTex);
	gl_FragColor = color1; //This works fine
	gl_FragColor = color2; //This renders out black
}

so I’m assuming I can’t render more than 1 output color channel in the shader #1.

or is there anything I am missing?

regards,
Jakes

User-defined fragment shader outputs were added in GLSL 1.3. In previous versions, if you want to write to colour attachments other than attachment zero, you need to write to gl_FragData[] rather than gl_FragColor.

…or in 1.20 + EXT_gpu_shader4, but as written (without any #version declaration) frag shader #1 should not compile.

When you declare user varying outs, you need to bind the locations (which indirect into the draw buffer array.) In later shading language versions you can declare a location layout, but in 1.20 you need to use glBindFragDataLocation (see also glGetFragDataLocation.)

It also looks like you expect glBlitFramebuffer to copy from two read attachments into two draw attachments, but it doesn’t do that. It reads from the single READ_BUFFER and writes to the array of DRAW_BUFFERS. If you want to copy from two color attachments, you need two blits with appropriate state changes.

Yes, thank you, as I am still using version 120, I can’t use layout uniform inputs, so gl_fragData is really what I need, but for some reason the color result isn’t going into the texture I defined as being the second one I attached to the FBO.

that is my issue.
I’m ataching them this way, is this correct:

        //Attach first texture
        glActiveTexture(GL_TEXTURE0); 
        glBindTexture(GL_TEXTURE_2D, texture1);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
            
        //Attach second texture    
        glActiveTexture(GL_TEXTURE1); 
        glBindTexture(GL_TEXTURE_2D, texture2);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

        glBindFramebuffer(GL_FRAMEBUFFER, 0);

Yes, it might be the issue here.
So I need to add something here:

	public void renderFrameBufferToTextureColor() {
        glBindFramebuffer(GL_READ_FRAMEBUFFER, multisampledFbo);
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, finalFbo);
        glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
        
        //render fist one to texture1 - works fine
        glActiveTexture(GL_TEXTURE0); 
        glBindTexture(GL_TEXTURE_2D, texture1);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        
        //?? How do I render the contents of color attachment 1 to texture 2??
        glActiveTexture(GL_TEXTURE1); 
        glBindTexture(GL_TEXTURE_2D, texture2);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

        glBindFramebuffer(GL_FRAMEBUFFER, 0);
	}

You need to call glDrawBuffers to direct the fragment outputs to the appropriate color attachments. If you set a breakpoint on your draw and inspect the GL state, this should become obvious.

Whatever you’re doing with glActiveTexture and glTexEnv has no impact at all on framebuffer state.

To anyone who may need it:

the issue was when blitting the RenderBuffer, I wasn’t passing the color attachment parameter.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.