How to use glCopyImageSubData?

Hi! I want to copy a texture from a framebuffer object to a cubemap texture but I don’t understand how glCopyImageSubData work if someone can help me it would be nice thanks.

1 Like

glCopyImageSubData copies pixel data from one texture to another. So either the framebuffer object in your example is irrelevant, or you really want to use glCopyTexSubImage which copies from the current read framebuffer attachment to the given image.

In any case, given two textures, the use of glCopyImageSubData seems pretty obvious. It treats a cubemap as a 6-layer image, so you would select a face to copy to via the depth parameter. What exactly is the problem you’re having?

I tried this :

for (unsigned int i = 0; i < 6; i++) {
                glCheck(glCopyImageSubData(textures[i]->m_texture, GL_TEXTURE_2D, 0, 0, 0, 0, m_texture, GL_TEXTURE_CUBE_MAP,0,0,0,i,width,height,1));
            }

But it doesn’t work I’ve a GL_INVALID_OPERATION error.

I also tried to copy the texture to an sf::Image an then copy the sf::Image to the cubemap but that doesn’t work too.

It’s ok I’ve solved my problem but copying the texture to an sf::Image and then copying the sf::Image to my other texture.

This will be very slow and you’re doing the work twice. As Alfonse_Reinheart pointed it, you should consider glCopyTexSubImage.

Why are you copying in the first place? If you’re rendering a cube map, normally you’d do that by binding the faces of the cube map to a FBO then rendering to it.

If you are copying you certainly don’t want to do it through client memory (i.e. sf::Image). Either use glCopyImageSubData (copy from one texture/renderbuffer to another) or glCopyTexSubImage (copy from a framebuffer to a texture), or possibly glBlitFramebuffer (copy from the read framebuffer to the draw framebuffer). In the (rare) case where you need to copy the data as bytes (e.g. re-interpret values from normalised to integer, use texture data as a vertex attribute, or whatever), use a pixel buffer object as the intermediate storage so that the data doesn’t need to leave GPU memory.

Why are you copying in the first place? If you’re rendering a cube map, normally you’d do that by binding the faces of the cube map to a FBO then rendering to it.

I don’t want to bind a cubemap texture to an FBO because we need a geometry shader to select the layer to render to, but how to bind a cube map face to an FBO ? A cube map is a texture which have 6 images, not 6 textures. Or can we bind a 2D texture as a cubemap face ?

If you are copying you certainly don’t want to do it through client memory (i.e. sf::Image ). Either use glCopyImageSubData (copy from one texture/renderbuffer to another)

That doesn’t work it seems I can’t copy a 2D texture into a cubemap Texture.

Use glFramebufferTexture2D or glFramebufferTextureLayer to attach a single face of a cube map to a FBO. For glFramebufferTexture2D, the textarget parameter should be one of the face-specific targets (GL_TEXTURE_CUBE_MAP_POSITIVE_X etc). For glFramebufferTextureLayer, the layer parameter identifies the face.

Are you using GL_TEXTURE_CUBE_MAP or one of the face targets? The latter aren’t valid for glCopyImageSubData; you need to use the srcZ/dstZ parameters to select the face.

Also, bear in mind that the formats must be compatible (same number of bits per pixel, samples, etc); it doesn’t perform format conversions.

glGetTexImage+glTexSubImage via a PBO is another option which avoids a round-trip to CPU memory.

I do this, I set i (the face number) for dstZ but that doesn’t work. (invalid operation)

I think I’ll attach a cubemap to my FBO texture and draw to it.

Have you allocated the storage for the texture with glTexImage2D or glTexStorage2D? glCopyImageSubData replaces existing data; it won’t allocate the storage.

Have you allocated the storage for the texture with glTexImage2D or glTexStorage2D? glCopyImageSubData replaces existing data; it won’t allocate the storage.

Ha no. But I decided to don’t copy data and using a cubemap attached to an FBO instead.