Jump to content
  • Advertisement
Sign in to follow this  
rJie

glCopyTexSubImage2D

This topic is 3126 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I want to copy the color buffer that size is 800*600 to a texture that size is 256*256 how should I do?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

    Share this post


    Link to post
    Share on other sites
    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.

    Share this post


    Link to post
    Share on other sites
    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).

    Share this post


    Link to post
    Share on other sites
    Sign in to follow this  

    • Advertisement
    ×

    Important Information

    By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

    We are the game development community.

    Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

    Sign me up!