If you want to pass multiple cubemap shadowmaps to a shader, and you dont know in advance how many exactly then cubemap arrays are a good solution. They work like a 3D texture, where each layer is a cubemap. In the fragment shader you can create a sampler for them like this:
uniform samplerCubeArray cubeMapArray;
You bind the array texture to it in the following way:
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, m_PointLightDepthMaps.m_DepthTexture);
You can sample from the samplerCubeArray in the way like you would from a cubemap, but in this case your vector gets a fourth element, which is the layer to sample from. E.g.:
texture(cubeMapArray, vec4(dir, 3)).r
would sample from the fourth cubemap in the array. To create yourself a cubemap array which works as a depth texture you can use the following template:
void Renderer::initCubemapDepthMap(CubemapDepthMap& map)
{
glGenTextures(1, &map.m_DepthTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, map.m_DepthTexture);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glTexImage3D(
GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_DEPTH_COMPONENT, m_ShadowCubeMapResolution, m_ShadowCubeMapResolution, 6 * m_MaxPointLights + 6 * m_MaxSpotLights, 0,
GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, 0);
glGenFramebuffers(1, &map.m_FrameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, map.m_FrameBuffer);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, map.m_DepthTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
const int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!\n";
throw 0;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Note that you need to use GL_TEXTURE_CUBE_MAP_ARRAY as your texture type, and you need to use glTexImage3D. When calling glTexImage3D the number of layers is the number of cubemaps you need times 6, because each cubemap face is allocated like a separate layer. You don't need to take this into account when you sample it in the fragment shader!
When rendering the shadowmap you bind the buffer like you would any other buffer. And when you pass the depth texture to the shader you pass the whole cubemap array, no need to mess with separate layers.