PDA

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



HanWu
12-28-2006, 12:53 AM
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.

Zengar
12-28-2006, 02:52 AM
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...

k_szczech
12-28-2006, 03:07 AM
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

HanWu
12-28-2006, 09:45 PM
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.

k_szczech
12-29-2006, 12:04 AM
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.

HanWu
12-29-2006, 12:19 AM
How about using glReadPixels? Say our client area is width X height.

Code:

glViewport(0,0,2*width, 2*height);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
///
render scene;
///
glReadPixels(0, 0, 2*width, 2*height,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.

Zengar
12-29-2006, 12:29 AM
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).

HanWu
12-29-2006, 12:41 AM
I will try the method that suggested by you. Thank guys.

HanWu
01-03-2007, 09:09 PM
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 100*100, so the maximun tile size is 100*100 right?

Zengar
01-03-2007, 10:14 PM
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.

HanWu
01-04-2007, 12:02 AM
Hi Zengar, thanks a lot. I will work on it now.