Is it possible to create a Texture2D_Array from multiple Texture2D objects in OpenGL?

About my intention:

I have a stack of images and for several reasons I need them all to be separate 2D textures. Then for some composite display I need 5-10 of them to be combined in one display (perfect for Texture2d_Array). My idea was to take the already loaded 2D textures and shape them into a Texture2d array. Is this possible with the features that OpenGL gives me?

Note. I want to avoid reloading the image data and for efficiency reasons the already created mipmaps are very useful and should be saved. Therefore, actions such as "Get data from Tex2d, create a new Tex2Darray layer" are silly.

If that fails, my failure will be 10 probes in my shader and add / average them together before rendering.

+3


source to share


2 answers


Everything is possible! Well, almost everything ...

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

glCopyImageSubData()

glCopyImageSubData()

- this is a very exact match of the required functionality. The only drawback is that it is only available in OpenGL 4.3 and later.

glCopyTexImage2D()



I'm only mentioning this for the sake of completeness, in case someone looks at this answer for a slightly different use case. glCopyTexImage2D()

can usually be used to copy texture data by setting the original texture as an FBO application.

But it turns out it doesn't support GL_TEXTURE_2D_ARRAY

, so it can't be used to copy from a regular texture to an array texture. Another direction will work.

glBlitFramebuffer()

glBlitFramebuffer()

is available in OpenGL 3.0 and later and can be used to copy almost any framebuffer / texture data.

To copy from texture to texture, you create two FBOs. You link one of them like you GL_READ_FRAMEBUFFER

attach the original texture to it. You bind the second one like GL_DRAW_FRAMEBUFFER

and attach the target texture to it. Then you call glBlitFramebuffer()

.

+3


source


You may be able to work around your limitations to have each texture in a separate 2D texture using a combination of the following two methods:

glTextureView()

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



However, you cannot use this feature to map multiple existing 2D textures together into a new 2D array at your request. The reason for this is that there is not enough control over GPU memory mapping in OpenGL, although this is possible in theory, at least in some cases (given that the size of each slice is divided by the page size of your GPU memory controller).

Texture Atlas

You don't need to create a new texture array with an exact set of 2D texture slices for each of your special use cases, but instead bind a large texture array containing all textures to one (or more) samplers (s) and pass it along with the slice index array (select only your textures that you need) into your shader. This option is obviously only possible if you want / can change the shader source code.

+1


source







All Articles