Downsampling Displaybuffer to FBO is Failing to Downsample

Started by troycorbinz, December 01, 2012, 05:18:12

Previous topic - Next topic

troycorbinz

Hi all, thanks for looking.  :)

I am trying to take a screenshot of a Multi-sampled display. From what I've read, I need to blit it to a standard FBO, which will perform the downsample, and then I can render my FBO to a file. Unfortunately, the screenshot is mostly black with several thumbnail like images at the bottom which I assume are the samples. Here is the relevant code:

Creating the FBO:


Buffer = ByteBuffer.allocateDirect(1*4).order(ByteOrder.nativeOrder()).asIntBuffer(); // allocate a 1 int byte buffer
		glGenFramebuffersEXT( Buffer );
		FBOID = Buffer.get();
		glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, FBOID );
		ColorTexture = glGenTextures();
		
		glBindTexture( GL_TEXTURE_2D, ColorTexture );
		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SizeX, SizeY, 0, GL_RGBA, GL_INT, (java.nio.ByteBuffer) null);
		glFramebufferTexture2DEXT(
				GL_FRAMEBUFFER_EXT,
				GL_COLOR_ATTACHMENT0_EXT,
				GL_TEXTURE_2D,
				ColorTexture,
				0);
		
		int error = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );

		DepthID = glGenRenderbuffersEXT();
		glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, DepthID );
		glRenderbufferStorageEXT(
				GL_RENDERBUFFER_EXT,
				GL_DEPTH_COMPONENT24,
				SizeX,
				SizeY);
		glFramebufferRenderbufferEXT(
				GL_FRAMEBUFFER_EXT,
				GL_DEPTH_ATTACHMENT_EXT,
				GL_RENDERBUFFER_EXT,
				DepthID);
		
		int error = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );


Blitting from the Display Buffer to my FBO:


int width = Display.getDisplayMode().getWidth();
		int height= Display.getDisplayMode().getHeight();
		int bpp = Display.getDisplayMode().getBitsPerPixel();
		FBO buffer = new FBO(width,height); // Create the FBO we'll use for our screenshot
		glBindFramebufferEXT(EXTFramebufferBlit.GL_READ_FRAMEBUFFER_EXT, 0); // Read from the Display Buffer
		glBindFramebufferEXT(EXTFramebufferBlit.GL_DRAW_FRAMEBUFFER_EXT, buffer.getFBO());
		EXTFramebufferBlit.glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
		ByteBuffer bbuffer = BufferUtils.createByteBuffer(width * height * bpp);
		glReadBuffer(buffer.getFBO()); // Assigns the FBOID we got earlier
		glReadPixels(0, 0, width, height, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, bbuffer );


I've tried a number of variations, including rendering the screen directly onto the FBO, but the result is the same. And as you can see, I am not creating the Color Buffer of the FBO with glRenderbufferStorageMultisampleEXT, so it should not be multisampled, correct?

How can I go about downsampling the FBO so that I get a good glReadPixels for a screenshot? Thanks for looking and thanks for any help you can provide. BTW, this is using LWJGL 2.8.5.

spasi

You cannot use BlitFramebufferEXT to resolve a window-system provided MSAA framebuffer. The source framebuffer has to be an FBO with multisampled renderbuffer(s) attached. In your case, it'd be best to render to a multisampled FBO, blit to the window framebuffer (which should be single-sampled), then do the ReadPixels from that.

troycorbinz

Thanks for the advice. What blit do I need to use to go from the MSAA FBO to the window framebuffer? Or is BlitFrameBufferEXT fine with window framebuffers that are not multisampled?

spasi

BlitFrameBufferEXT. It works on window framebuffers, except on multisampled ones. So, bind READ_FRAMEBUFFER_EXT to the multisampled FBO, DRAW_FRAMEBUFFER_EXT to 0 and do the blit.

troycorbinz