简体   繁体   中英

Is it possible to create a Texture2D_Array off several Texture2D objs in OpenGL?

About my intend:

I have an image stack and for several reasons I need them all to be separate 2D-textures. Then for some composed display I need like 5-10 of them to be fused together in one display (perfect for Texture2d_Array). My idea was to take the already uploaded 2D textures and form them into a Texture2d-array. Is that possible with the functions that OpenGL gives me?

Remark: I want to avoid re-loading the image data and for efficientcy reasons the already created mip-maps are very useful and should be retained. Therefore actions like "Get data off Tex2d create new Tex2Darray-layer" are stupid.

If that fails, my fallback would be to have around 10 samplers in my Shader and add/average them together before display.

Anything is possible! Well, almost anything...

Depending on the OpenGL version you have available, there are a few options you can consider. This is if you really need to copy the data. Of course by far the best option would be to load the texture data into an array texture in the first place, and avoid the extra copy.

glCopyImageSubData()

The glCopyImageSubData() is a very direct match for the functionality you want. The only downside is that it's only available in OpenGL 4.3 and later.

glCopyTexImage2D()

I'm mentioning this just for completeness sake, in case somebody looks at this answer for a slightly different use case. glCopyTexImage2D() can generally be used to copy texture data by setting up the source texture as an FBO attachment.

But it turns out that it does not support GL_TEXTURE_2D_ARRAY , so it can't be used to copy from a regular texture to an array texture. The other direction would work.

glBlitFramebuffer()

glBlitFramebuffer() is available in OpenGL 3.0 and later, and can be used to copy almost any kind of framebuffer/texture data.

To copy from texture to texture, you create two FBOs. You bind one of them as GL_READ_FRAMEBUFFER , and attach the source texture to it. You bind the second one as GL_DRAW_FRAMEBUFFER , and attach the target texture to it. Then you call glBlitFramebuffer() .

You might be able to bypass your limitation to have each texture in a separate 2D texture using a combination of the following two techniques:

glTextureView()

Create a single texture array and then use glTextureView() (core in OpenGL 4.3+) to create separate 2D textures which behave exactly as your currently existing ones. The difference compared to the functions outlined by Reto Koradi is that texture views do not duplicate memory on the GPU which might be more efficient depending on your needs.

However, you cannot use this function to map several existing 2D textures together into a new 2D array as you requested. The reason for that is simply because there is not enough control over GPU memory mapping in OpenGL, although this would be possible in theory at least in some cases (given that the size of each slice is dividable by the page size of your GPU's memory controller).

Texture Atlas

You don't necessarily need to create a new texture array with the exact set of 2D texture slices for each of your special use cases, but instead bind the large texture array containing all textures to a single (or multiple) sampler(s) and pass it along with an array of slice indices (selecting only your textures you need) to your shader. This option is obviously only feasible if you are willing/able to change the shader source code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM