Jump to content
  • Advertisement
Sign in to follow this  
hannesp

OpenGL Bind single CUBE_MAP_ARRAY entry

This topic is 1416 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys,

 

After reading posts in this board nearly daily for a long time (thanks a lot!), it's finally time to get active and ask a question by myself.

 

I'm using some cubemap textures to do IBL in my deferred renderer. After exceeding texture unit limits I decided to use cubemap array textures. Writing a render target wrapper didn't make any problems, so currently I'm able to render to every single cube layer-face in my cubemap array texture just fine. However, it's important for me to have those maps dynamic and with mipmaps. The simplest way would be to use glGenerateMipmap(GL_TEXTURE_CUBE_MAP_ARRAY), which is working great - but with a big deficite: If the array texture is large, the call takes a large, constant and unnessesary amount of time, because mipmaps for all entries are computed at once.

 

I need to generate mipmaps for single entries of the array texture. And by that I don't mean the layer-faces (2D textures), but the cubemaps (for seamless filtering).

So basically I want to do bind a single entry of the array and generate mipmaps. Currently I'm trying to achieve just this with the following code:

glBindImageTexture(0, cubeMapArrayRenderTarget.getCubeMapArray().getTextureID(), 0, false, probe.getIndex(), GL_READ_WRITE, GL_RGBA8);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);

This doesn't do anything. In fact, glGetInteger(GL_TEXTURE_BINDING_CUBE_MAP) doesn't return anything (0) after the call. Just to check every possible way of functioning, I tried to bind the layer-faces and generate mipmaps for the 2D textures with the (propably?)following code:

for (int i = 0; i < 6; i++) {
glBindImageTexture(0, cubeMapArrayRenderTarget.getCubeMapArray().getTextureID(), 0, false, 6*probe.getIndex() +i, GL_READ_WRITE, GL_RGBA8);
}

Doesn't work either. In fact, this call doesnt't even change bindings - checked with glGetInteger(GL_TEXTURE_BINDING_2D). It seems that the call has NO effect on anything.

 

While the opengl documentation states, that some interfaces might use layers and some might use layer-faces, I simply am not sure about glBindImageTexture - my guess would be if I use a cubemap texture, the bound layer will be a cubemap. The documentation on the internet about and the community around cubemap arrays is very sparse... so, is there anybody who is able to use a cubemap array in my demanded way? And if so, could you please provide some working code snippets?

 

Further information: I check for errors, there are none. I use proper texture filtering, everything complete. The format should be okay because I only use RGBA8. I use Java 8, the latest 2.xx lwjgl lib and OpenGL 4.4.

 

I hope I provided enough information - and thanks in advance!

 

Hannes

Share this post


Link to post
Share on other sites
Advertisement

It's not possible to restrict which layers of the cube map array should have their mipmaps generated. The only GL state that affects glGenerateMipmap is the currently bound texture on the texture target you specify, the bound texture's base level (GL_TEXTURE_BASE_LEVEL), and the bound texture's max level (GL_TEXTURE_MAX_LEVEL). So calling glGenerateMipmap will generate mip maps for the entire texture. Calling glBindImageTexture only binds specific mip level/face/target/slice to the image units used by GLSL shaders (for image load-store) and doesn't interact with anything else.

 

How many cube maps are you actually using in any single draw call? OpenGL has a minimum of 16 texture units (I think?), so assuming you're using 4 - 6 units for other texture maps such as diffuse, specular, normals, etc, do you really need 10 - 12 cube maps for a single draw call?

Edited by Xycaleth

Share this post


Link to post
Share on other sites

Thank you for your reply :)

 

Okay, that's kind of bad news, I think. And is it somehow possible to bind layers of my array to the cubemap target? Maybe with texture views or anything else? - It would be very nice for my project if there is a way.

 

I don't need my environment maps for the per-object first pass of the deferred rendering but rather in a fullscreen post effect. And therefore I need ... let's say all of my environment maps available. I had a rough prototype working with a very ugly and bloated set of hard coded cubemap samplers, even more ugly if-else-return-sampler-statements and somewhen exceeded the limit of I think 32 simoultanious used units.

 

If the automatic cubemap generation isn't possible - which is a pity, because a bunch of single cubemaps is so much more convenient for no reason.... - I would tend to implement the mipmapping by myself. But because my lifetime is somehow limited, I wanted to ask first :)

Share this post


Link to post
Share on other sites

And is it somehow possible to bind layers of my array to the cubemap target? Maybe with texture views or anything else? - It would be very nice for my project if there is a way.

 

I hadn't thought about texture views! I think that could work. If you create a texture view with the new target being a plain cube map and the original target being your cube map array, you might be able to just generate mip maps for a single cube map at a time. Something like this perhaps:

GLuint cubeMapView;
glTextureView(cubeMapView, GL_TEXTURE_CUBE_MAP, cubeMapArray, GL_TEXTURE_CUBE_MAP_ARRAY, <texture format>, 0, <num mip levels>, <layer which holds the cubemap to generate mipmaps for>, 1);
glBindTexture(cubeMapView, GL_TEXTURE_CUBE_MAP);
glGenerateMipMap(GL_TEXTURE_CUBE_MAP); // Should only generate mip maps for a single cube map in your cube map array
Edited by Xycaleth

Share this post


Link to post
Share on other sites

IT WORKS!

 

How dumb I was for not testing it immediately. Guess I was to curious about how to do it "officially".

 

Using a cubemap texture view works in the following mannor in this case - note that you have to use layer-faces, not layers! This means the source layer is six times the index. And the layer count is 6, because the cube map has six faces, therefore six layers in the means of layer-faces.

 

glTextureView(cubeMapView, GL_TEXTURE_CUBE_MAP, cubeMapArrayRenderTarget.getCubeMapArray().getTextureID(), GL_RGBA8, 0, mipMapLevelCount, 6*index, 6);

EDIT: For your interest: takes roughly 0.4ms for a 512x512 cubemap with my setup. GTX 770. No differences in speed compared to a regular cubemap mipmapping step without array and view.

 

EDIT2: THANKS for your help, Xycaleth!

Edited by hannesp

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!