glCopyTexSubImage2D

Started by
9 comments, last by rJie 14 years, 2 months ago
I want to copy the color buffer that size is 800*600 to a texture that size is 256*256 how should I do?
Advertisement
Typically, you cannot just blit/copy a texture or buffer of one size to a texture or buffer of a different size. A resizing operation requires the buffer or texture to be drawn to some offscreen or backbuffer, from which the new resized image can be fetched.

Whatever you might need a smaller texture for, I recommend you to use a Frame Buffer Object (FBO) to create an offscreen rendering bufer:
OpenGL FrameBuffer Object 101
These can have a texture attached to them, which will receive the pixels you have drawn to the buffer. Then you'll simply need a 800x600 FBO, your previous color buffer, with a texture bound to it. This texture can then be drawn to a 256x256 FBO, with a smaller texture bound to it. This smaller texture will then contain your resulting image.

Note that for any resizing operation like this, you'll probably want at least linear minification filtering. Mipmapping would probably be a good idea in this case as well. Call the function given here after unbinding your larger FBO:
OpenGL Wiki: Automatic mipmap generation
You'll need to set your minification filter to GL_LINEAR_MIPMAP_LINEAR of course.

If you are using an older version of OpenGL without FBO support (pre 2.0 gets tricky on extensions here), you should use the same principle as I described above. Only you'll need to handle the copying from the framebuffer to a texture yourself, using glCopyTexSubImage2D. Simply create mipmaps for the larger texture and use that to draw to a smaller section of the screen.

If you run into any problems or anything is unclear, let us know.

Regards,
Ignifex
Thank you,Ignifex.
I want to achieve the water refraction. I have to draw scene again if use a FBO.
So I wound like to simply copy a texture from backbuffer use to refract
If I understand you correctly, you are saying that, when first drawing the scene to an FBO for use in your refraction pass, you'll need to draw it again later?

You could use the result of what you have drawn on the FBO and render this entire texture to the backbuffer again, correct? Basically, you draw everything to your "final" FBO you used to draw to the backbuffer and then use the color texture generated to "render" that to the backbuffer. This FBO would of course require a depth buffer, much like the backbuffer.

The FBO then works exactly like the backbuffer, with the added gain that anything you render is readable for a second pass to another FBO. This technique is actually quite common, as it also allows support for multisampling and HDR rendering.
sorry,My english isn't very good.But you said are similar to me.

I have draw scene once use a FBO for finish reflection texture.
Then I draw scene to the backbuffer again, and copy all pixel to a texture that used for blend with reflection as the refraction.
I use glCopyTexSubImage2D to copy pixel so that I have to create a texture as large as backbuffer.
Now it have a problem if the viewport is changed. I have to recreate the texture.

So I think that I can copy to a fixed size texture from backbuffer like m_plD3DDevice->StretchRect of d3d
The copying from the backbuffer to the texture using glCopyTexSubImage2D is quite expensive and it is exactly this operation that can be avoided by using an FBO. The copying is done for you, to the texture that you bind to the FBO.

If you need to resize your viewport, you can just recreate your FBO, including the texture. Make sure to properly delete is as well, or you video memory will get full at some point.

So basically, you create an FBO with the same width and height as your backbuffer and viewport.
It is correctly that using glCopyTexSubImage2D is quite expensive.But I think that it is more expensive if I draw the scene twice to the backbuffer and a FBO.So I only draw once to backbuffer and a copy of the texture.
You do not need to redraw your scene to the backbuffer. You can use the texture attached to the FBO to render the outcome of what you rendered before.

  • Render to an FBO A, with a color texture C attached.
  • Render this C to another FBO B, with your 256x256 texure attached. This will result your resized texture.
  • Use your resized texture, possibly to do more rendering to FBO A.
  • Render texture C to the backbuffer. This means that what you rendered to FBO A earlier is then visible on the backbuffer.
  • This is a way to. But the texture C have to resize the same if resize the backbuffer, otherwise the backbuffer's pixel will be hazy when draw the texture C to the backbuffer.
    Yes, normally you'll need to recreate the texture when you resize your viewport. If you want to do this a lot, say more than 10 times a minute, then you might decide to make the texture and FBO bigger than your viewport and thus use only the part that you need. If it becomes even bigger again, you can always do a resize.

    Most games take a long time to resize to a different screenresolution, even in windowed mode. For my simpler applications this delay is hardly noticeable though, so I assume recreating the FBO and texture does not take too long (on my desktop and older laptop that is).

    This topic is closed to new replies.

    Advertisement