How to efficiently copy texture1 to texture?

I want to copy texture 1 to texture2. The stupidest way is copying tex1 data from the GPU to the CPU, and then copying the CPU data to the GPU. The stupid code is as follows:

float *data = new float[width*height*4]; glBindTexture(GL_TEXTURE_2D, tex1); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, data); glBindTexture(GL_TEXTURE_2D, tex2]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, data); 

As I know, it must exist in a method that supports copying data from tex GPUs to tex GPUs without a processor involved. I am considering using FBO to render tex1 quad to tex2. But for some reason, I think it's still naive. So what is the most efficient way to implement this?

+8
opengl textures
source share
1 answer

If you have OpenGL 4.3 support, there is a direct glCopyImageSubData for this purpose:

 glCopyImageSubData(tex1, GL_TEXTURE_2D, 0, 0, 0, 0, tex2, GL_TEXTURE_2D, 0, 0, 0, 0, width, height, 1); 

Of course, this requires that the destination texture be already selected with an image of the appropriate size and format (using a simple glTexImage2D(..., nullptr) , and maybe even better than glTexStorage2D if you have GL 4).


If you donโ€™t have this, then rendering one texture to another using FBO might be the best approach. In the end, you donโ€™t even need to display the original texture. You can simply attach both textures to FBO and add a one-color application to another using glBlitFramebuffer (the core with OpenGL 3 or with the GL_EXT_framebuffer_blit extension in 2.x, almost anywhere where FBOs are in the first place):

 glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, tex2, 0); glDrawBuffer(GL_COLOR_ATTACHMENT1); glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST); 

Of course, if you do this several times, it might be a good idea to keep this FBO alive. And similarly, it also requires that the destination texture image has the appropriate size and format in advance. Or you can also use Michael's suggestion to combine the source texture with FBO and the good old glCopyTex(Sub)Image2D into the target texture. It is necessary to evaluate what is better (if any).


And if you donโ€™t even have this, you can still use your approach to read one texture and write this data to another. But instead of using processor memory as a temporary buffer, use a pixel buffer object (PBO) (kernel with OpenGL 2.1). You will still have an extra copy, but at least it will (or most likely will) be a copy of the GPU-GPU.

+11
source share

All Articles