Hi! I’m trying to use texture arrays (OpenGL 4.4, GTX 980, Win 10) to make it so I don’t have to bind textures each frame, but the fragment shader always outputs a black pixel. Does anyone know what I’m doing wrong? It was working fine with normal textures. Here is my current code (simplified to just show necessary parts, the full code can be found here)
- Fragment Shader (GLSL)
#version 440 core
in vec2 TexCoords;
out vec4 color;
layout (binding=0) uniform sampler2DArray textureArray;
layout (location=1) uniform int layer;
void main()
{
color = vec4(texture(textureArray, vec3(TexCoords.xy, layer)));
}
- Initialize Texture Array
glGenTextures(1, &arrayTexture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, arrayTexture);
glTexStorage3D(GL_TEXTURE_2D_ARRAY,
5, //5 mipmaps
GL_RGB, //Internal format
1024, 1024, //width,height
256 //Number of layers
);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- For each unique texture, upload it using glTexSubImage3D
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, arrayTexture);
if (!texture->loaded) texture->loadImageData();
glTexSubImage3D(GL_TEXTURE_2D_ARRAY,
0, //Mipmap number
0, 0, currentSpotInArrayTexture, //xoffset, yoffset, zoffset
1024, 1024, 1, //width, height, depth
GL_RGB, //format
GL_UNSIGNED_BYTE, //type
texture->image); //pointer to data
texture->freeImageData();
texture->textureArrayLocation = currentSpotInArrayTexture;
currentSpotInArrayTexture++;
- Once all the textures are uploaded, generate mipmaps
glBindTexture(GL_TEXTURE_2D_ARRAY, arrayTexture);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D_ARRAY);
- In the render loop, for each mesh, set the shader’s layer uniform (explicitly set at location 1) to the location of that mesh’s texture, and bind it (only binding it every frame for testing purposes)
glActiveTexture(GL_TEXTURE0);
glUniform1i(1, textures->at(i).textureArrayLocation);
glBindTexture(GL_TEXTURE_2D_ARRAY, arrayTexture);