2
$\begingroup$

I have been reading the OpenGL documentation but it is not clear to me how to achieve the following.

Say we have an array of strings. Each string in the array is a valid relative path to an image file (.png, .jpeg...)

We have a method that can read and store into a GLubyte array the image information of each file.

We want to allocate the needed memory for the textures, and save said information into a texture array. However there's no guarantee that the textures are the same dimensions.

$\endgroup$
0

1 Answer 1

3
$\begingroup$

The memory layout of a (2D) array texture is pretty similar to a 3D texture, with the individual image layers stored one after the other in a big 3D-array of pixels. So that's also how you set them. You either load each individual image into a big GLubyte array one after the other and set it with glTex(Sub)Image3D or you load each image into its own GLubyte array and transmit that to the texture with glTexSubImage3D one after the other (or any other more complex process involving buffers or whatever, but you get the idea).

So much to the theory. The problem here is the part where you say

However there's no guarantee that the textures are the same dimensions.

This contradicts with how array textures work. As the corresponding documentation you link to says:

An Array Texture is a Texture where each mipmap level contains an array of images of the same size.

So the individual layers of an array texture have to be the same size. Simplifyingly said, an array texture is really just a 3D texture without filtering along the z-axis. So you can't get different-sized textures into such a regular box of pixels.

There's a few options you have here, though:

  • You could scale every image to a common size, depending on how different they really are and what rescaling means to your quality and/or memory demands.

  • You could just drop using array textures and implement whatever you want to do with normal 2D textures and a likely more complicated process on the CPU side.

  • You could use Bindless Textures. This is a rather modern non-core feature (only usable through extensions yet) that is really flexible and allows you to access textures in a shader by using a unique GPU handle (a 64-bit ID, so to say). This allows you to use whatever and how many textures you want in a shader, depending on some arbitrarily input value (even a vertex attribute).

    In this case you wouldn't just a have access to a continuous array of N textures, rather than the wealth of all the textures you have allocated. You would just use normal independent 2D textures and use their respective texture handles rather than an array index. Of course this comes with a few limitations and intricacies, too. But more about that in the corresponding documentation.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.