1
\$\begingroup\$

I've been using TextureArray's in my current Project; However, I have come to the problem of OpenGL 4.2 functions not being on the present Mac software when ported over. Due to only version 4.1 of OpenGL being supported.

All my problems stem from the single function. glTexStorage3D which is the only function not supported.

This is how it currently works on my OpenGL 4.2 capable machine. (and works wonderfully I might add.)

1.) I allocate the memory beforehand with glTexStorage3D.

glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D_ARRAY, _texture);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 255, GL_RGBA8, 16, 16, _maxLayerCount);

2.) Then per image I would load it into the before allocated memory block with the following.

glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, _layerCount, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr());

3.) Success.

How would I go about mimicking this functionality pre OpenGL 4.2 without using Immutable Storage? Aka (glTexStorage3D).

I've tried stuffing all my images into a horizontal single image and then loading that into just glTexImage3D with no success. Am I missing something?

Additional Note: I prefer to use TextureArray's for my project in order to avoid rendering artifacts I had using a TextureAtlas. It's simplicity during shaders is also a big plus.

\$\endgroup\$
2
\$\begingroup\$

Without immutable storage you can just specify a texture array using glTexImage3D.

I note that you say you've tried this but it didn't work; it would have been helpful if you had given us the code that didn't work, as you clearly have an error in it which we may have been able to help you with.

That aside, there is another way which is minimally invasive and will work for you with just a single line of code changed; from:

glTexStorage3D(GL_TEXTURE_2D_ARRAY, 255, GL_RGBA8, 16, 16, _maxLayerCount);

To:

glTexImage3D (GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 16, 16,
    _maxLayerCount, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

Like glTexStorage3D, glTexImage3D with a NULL data pointer will reserve storage for the texture, but in this case without the constraint that the texture be immutable (you'll also need to make an additional glTexImage3D call for each submip if you want to mipmap the texture).

From the documentation:

data may be a null pointer. In this case texture memory is allocated to accommodate a texture of width width, height height, and depth depth. You can then download subtextures to initialize this texture memory.

Once you have that done you can just load the individual array slices using glTexSubImage3D in exactly the same way as you are doing so now.

\$\endgroup\$
  • \$\begingroup\$ Thank you! It works perfectly! This is exactly what I was looking for. I must not have seen the NULL method of allocating storage. \$\endgroup\$ – John Apr 18 '15 at 17:19
  • \$\begingroup\$ @John - it doesn't seem to have percolated the general consciousness; I've seen code where people allocate dummy buffers for this, or otherwise go to great lengths, but yet this has been valid usage since IIRC GL 1.2 \$\endgroup\$ – Maximus Minimus Apr 18 '15 at 17:32
  • \$\begingroup\$ How interesting. I know in my case I searched many sites looking for a solution over a weeks time before finally giving up and asking here; During that time I don't believe I once saw I solution like this. Many just opt for the 4.2 Method as it's the "modern way". \$\endgroup\$ – John Apr 18 '15 at 17:35
  • \$\begingroup\$ @John - what's neat about this is that you can still use glTexStorage in cases where 4.2 or higher (or ARB_texture_storage) are available, and with minimal code changes. \$\endgroup\$ – Maximus Minimus Apr 18 '15 at 17:40
  • \$\begingroup\$ Very true! I'll be sure to show this to people I know. I for sure love the quick and easy solution. Thank you for your help and time. StackExchange seems to be a wonderful resource because of people like you. \$\endgroup\$ – John Apr 18 '15 at 17:45
1
\$\begingroup\$

Texture arrays have been part of the OpenGL core context for as long as there's been a core context; ever since OpenGL 3.0. Pretty much every desktop computer sold within the last six years will support OpenGL 3.0 or later. Ultra-mobility laptops more than three years old might be problematic, but anything more recent or more beefy than that should be completely fine. So there's how you support it under OpenGL pre-4.2; do exactly what you're already doing, as long as you have 3.0 or later.

You only need to think about alternate implementations if you're trying to support OpenGL 2.1. But even in 2.1, texture arrays were available in many drivers as an extension, so few changes might be required to your texture handling: EXT_texture_array.

But honestly, the differences in the rendering pipeline between OpenGL 4.x and OpenGL 2.1 are huge -- texture arrays will be the least of your problems if you're really trying to support both in a single program. Probably better off picking one or the other, and running with it.

\$\endgroup\$
  • \$\begingroup\$ I understand what you're saying but I think you've missed the point. Texture Array's have been there for a long time but I don't know how to use them without using glTextureStorage3D which is a OpenGl 4.2 feature. See the bottom of this page opengl.org/sdk/docs/man/html/glTexStorage3D.xhtml \$\endgroup\$ – John Apr 18 '15 at 15:44
  • \$\begingroup\$ Ah, yes; I'd missed the core thrust of your question; I was focused too much on the line with the question mark on it. :) \$\endgroup\$ – Trevor Powell Apr 19 '15 at 7:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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