How to save an image which the size is 2 times larger than the size of client area ?

I am working on a function that can save the current view to a bitmap file. I use the glReadPixels function to read a block of data from the framebuffer and later output it to a bitmap file. Now I want to save an image which the size is 2 times larger than the size of client area. Anyone know how to do it? Thanks.

You could scale the image, but this is probably not what you want… You could also render the scene four times, selecting different zones every time, so that you get four zoomed image parts at the end. Then you can combine them in one image.

Or use a FBO that is larger then the client area…

  1. Create texture 2x bigger than client area
  2. Render to this texture instead of client area (use EXT_framebuffer_object extension - you can find some ready to use classes over the internet, like this one: http://www.gamedev.net/reference/programming/features/fbo2/))
  3. use glGetTexImage to copy texture contents to system memory and save to file

If we don’t want to use OpenGL extension function due to the reason that not every graphic card support this function. Any other solution? Thanks.

You can use pbuffer instad of FBO - it is supported on many older GPU’s but it’s more difficult to use (it’s actually a separate rendering context that, by default, does not share any textures or other object with main context - you would have to enable texture sharing).
The fail-safe solution is what Zengar suggested - render 4 quarters of image separately and copy each one of them to some buffer in system memory - then combine the image and save it.

How about using glReadPixels? Say our client area is width X height.

Code:

glViewport(0,0,2width, 2height);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
///
render scene;
///
glReadPixels(0, 0, 2width, 2height,GL_BGR,GL_UNSIGNED_BYTE, data);

If we specified the width and height which is 2 times the client area. Will those block of pixel that fall outside of the client area be read? Thanks.

You will most probably get an error becase ReadPixels can’t read more then there is (obviously). If it is sufficient for you, read the image with ReadPixels and scale it up. The quality will be bad of course. If you want native rendered scaled image without the use of extensions, then you should use the approach I suggested above (with tiling).

I will try the method that suggested by you. Thank guys.

Originally posted by Zengar:
You will most probably get an error becase ReadPixels can’t read more then there is (obviously). If it is sufficient for you, read the image with ReadPixels and scale it up. The quality will be bad of course. If you want native rendered scaled image without the use of extensions, then you should use the approach I suggested above (with tiling).
One thing I would like to confirm with you. Isn’t it the maximun size of each tile is limited by the window size? If say the user resize the opengl window to 100100, so the maximun tile size is 100100 right?

Yes, that’s true… But since you want an image that is 4 times bigger, this should be not an issue for you - if the user resizes the window, the client area changes it’s size. If you want fixed image size, then use pbuffers, they are supported on almost all hardware today.

Hi Zengar, thanks a lot. I will work on it now.