Help with FBO once again!

Hi all!

this must been an easy one… I keep having GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT error when attaching the buffers:


			/// Color buffer.
			glGenRenderbuffersEXT(1, &m_FrameBufferId);
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_FrameBufferId);
			glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, 16, GL_RGBA, m_Width, m_Height);
			OPENGL_CHECK_FRAME_BUFFER_STATUS();
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
			
			/// Depth buffer.
			glGenRenderbuffersEXT(1, &m_DepthBufferId);
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_DepthBufferId);
			glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, 16, GL_DEPTH_COMPONENT24, m_Width, m_Height);
			OPENGL_CHECK_FRAME_BUFFER_STATUS();
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

			/// Attach buffers.
			glGenFramebuffersEXT(1, &m_MultiSampleId);
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_MultiSampleId);
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_DepthBufferId);
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_FrameBufferId);
			OPENGL_CHECK_FRAME_BUFFER_STATUS();
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

I just can see what im doing wrong here…

Are you sure your card supports 16 samples?

int maxsamples;
glGetIntegerv(GL_MAX_SAMPLES_EXT,&maxsamples);

N.

yes yes indeed… it returned 8… so i changed the glRenderbufferStorageMultisampleEXT parameter to 8 and tadam, it worked!!!

I thought glRenderbufferStorageMultisampleEXT was going to set this variable… I have to set this before building the gl window right? if yes, why is the parameter even there?

since you seem to have all the answers under your sleeves :slight_smile: do I absolutly need 2 blits when using multisampling and want to draw into the main frame buffer as well?


	if (b_MultiSample)
	{
		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_MultiSampleId);
		glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_BufferId);
		glBlitFramebufferEXT(0, 0, m_Width, m_Height, 0, 0, m_Width, m_Height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
		
		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_BufferId);
		glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
		glBlitFramebufferEXT(0, 0, m_Width, m_Height, 0, 0, m_Width, m_Height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);

		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
		glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
	}
	else
	{
		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_BufferId);
		glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
		glBlitFramebufferEXT(0, 0, m_Width, m_Height, 0, 0, m_Width, m_Height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
	}

thx again

I’m not sure what you mean here. glRenderbufferStorageMultisampleEXT does set the sample count to the value you provide it with. GL_MAX_SAMPLES_EXT is just a read only implementation dependent value indicating your graphics cards multisampling capability. AFAIK you can create a non multisampled gl window and still create multisampled renderbuffers.

You can blit from an fbo to the main frame buffer in one pass. As long as the dimensions of the fbo and the frame buffer are equal and you use GL_NEAREST you shouldn’t run into problems. For all other cases, check here.

N.

GL_MAX_SAMPLES_EXT is just a read only implementation dependent value indicating your graphics cards multisampling capability.

you are rigth, my mistake.

You can blit from an fbo to the main frame buffer in one pass.

I was refering at the example I provide with the mutlisampled enable above… I doubt it but I m wondering if there is any way to blit only once and still have the same result.

thx nico… still digging!

Well, I have no idea what m_BufferId is. From what I can tell, you’re drawing to a m_MultiSampleId buffer. Then you’re blitting from m_MultiSampleId to m_BufferId. And finally you’re blitting from m_BufferId to your window provided frame buffer.

It’s possible to blit directly from m_MultiSampleId to your window provided frame buffer. In that case m_BufferId is left untouched.


glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_MultiSampleId);
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
glBlitFramebufferEXT(0, 0, m_Width, m_Height, 0, 0, m_Width, m_Height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);

It’s not possible to blit from m_MultiSampleId to both m_BufferId and your window provided frame buffer in a single call.

N.

the result wanted is a RTT multisampled and have the window frame buffer with the same result.


void PBuffer::Set()
{
	if (m_FrameBufferId == 0)
	{
		glGenFramebuffersEXT(1, &m_FrameBufferId);
		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_FrameBufferId);

		/// Color texture.
		AX6_RENDERER()->GenerateTexture(m_ColorTexture);
		glGenerateMipmapEXT(m_ColorTexture->GetDimension());
		AX6_RENDERER()->DisableTexture(m_ColorTexture);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, m_ColorTexture->GetDimension(), m_ColorTexture->GetId(), 0);
		AX6_OPENGL_CHECK_FRAME_BUFFER_STATUS();

		/// Depth texture.
		AX6_RENDERER()->GenerateTexture(m_DepthTexture);
		glGenerateMipmapEXT(m_DepthTexture->GetDimension());
		AX6_RENDERER()->DisableTexture(m_DepthTexture);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, m_DepthTexture->GetDimension(), m_DepthTexture->GetId(), 0);
		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, m_DepthTexture->GetDimension(), m_DepthTexture->GetId(), 0);
		AX6_OPENGL_CHECK_FRAME_BUFFER_STATUS();

		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

		if (b_MultiSampled)
		{
			if (m_MultiSamples > AX6_RENDERER()->GetMaxMultiSamples())
				m_MultiSamples = AX6_RENDERER()->GetMaxMultiSamples();

			/// Color buffer.
			glGenRenderbuffersEXT(1, &m_ColorBufferId);
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_ColorBufferId);
			glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_MultiSamples, GL_RGBA, m_Width, m_Height);
			AX6_OPENGL_CHECK_FRAME_BUFFER_STATUS();
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

			/// Depth buffer.
			glGenRenderbuffersEXT(1, &m_DepthBufferId);
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_DepthBufferId);
			glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, m_MultiSamples, GL_DEPTH_COMPONENT24, m_Width, m_Height);
			AX6_OPENGL_CHECK_FRAME_BUFFER_STATUS();
			glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

			/// Attach buffers.
			glGenFramebuffersEXT(1, &m_MultiBufferId);
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_MultiBufferId);
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_DepthBufferId);
			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_ColorBufferId);
			AX6_OPENGL_CHECK_FRAME_BUFFER_STATUS();
			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
		}
	}
	else
	{
		if (b_MultiSampled)
			glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_MultiBufferId);
		else
			glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_FrameBufferId);
	}
}

void PBuffer::Unset()
{
	if (b_MultiSampled)
	{
		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_MultiBufferId);
		glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_FrameBufferId);
		glBlitFramebufferEXT(0, 0, m_Width, m_Height, 0, 0, m_Width, m_Height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);

		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_FrameBufferId);
		glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
		glBlitFramebufferEXT(0, 0, m_Width, m_Height, 0, 0, m_Width, m_Height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
	}
	else
	{
		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_FrameBufferId);
		glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
		glBlitFramebufferEXT(0, 0, m_Width, m_Height, 0, 0, m_Width, m_Height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
		glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
	}
}

I think I got it pretty much nailed down… thx to you!