I have tried the code in opengl wiki about the creation of texture array. Array Texture - OpenGL Wiki
GLuint texture = 0;
GLsizei width = 2;
GLsizei height = 2;
GLsizei layerCount = 2;
GLsizei mipLevelCount = 1;
// Read you texels here. In the current example, we have 2*2*2 = 8 texels, with each texel being 4 GLubytes.
GLubyte texels[32] =
{
// Texels for first image.
0, 0, 0, 255,
255, 0, 0, 255,
0, 255, 0, 255,
0, 0, 255, 255,
// Texels for second image.
255, 255, 255, 255,
255, 255, 0, 255,
0, 255, 255, 255,
255, 0, 255, 255,
};
glGenTextures(1,&texture);
glBindTexture(GL_TEXTURE_2D_ARRAY,texture);
// Allocate the storage.
glTexStorage3D(GL_TEXTURE_2D_ARRAY, mipLevelCount, GL_RGBA8, width, height, layerCount);
// Upload pixel data.
// The first 0 refers to the mipmap level (level 0, since there's only 1)
// The following 2 zeroes refers to the x and y offsets in case you only want to specify a subrectangle.
// The final 0 refers to the layer index offset (we start from index 0 and have 2 levels).
// Altogether you can specify a 3D box subset of the overall texture, but only one mip level at a time.
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, width, height, layerCount, GL_RGBA, GL_UNSIGNED_BYTE, texels);
// Always set reasonable texture parameters
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);
The feature seems to be suitable to be used to access multiple texture without keep binding different textures during the draw loop.
However I fail to access these texture in the glsl code and it seems that the wiki did not provide a suitable answer for it. (I mean, a regular texture is feed into the frame shader through uniform, but the same way does not work for an aaray texture) I use SOIL to load images from files but I do not think that is the problem, cause SOIL works fine when I use regular 2D texture.
My code is like this
// Load textures
GLuint texturesArray;
glGenTextures(1, &texturesArray);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, texturesArray);
glTexStorage3D(
GL_TEXTURE_2D_ARRAY,
1, //1 mipmap. No LOD
GL_RGBA,
800, 600, //size
2 //amount of texures in this;
);
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);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_MIRRORED_REPEAT);
int width, height;
unsigned char* image;
glUniform1i(glGetUniformLocation(shaderProgram, "texKitten"), 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, texturesArray);
image = SOIL_load_image("sample.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexSubImage3D(
GL_TEXTURE_2D_ARRAY,
0,
0, 0,
0, //index
width, height,
1, //depth
GL_RGBA, GL_UNSIGNED_BYTE,
image);
SOIL_free_image_data(image);
// cout << width << " " << height << endl;
image = SOIL_load_image("sample2.png", &width, &height, 0, SOIL_LOAD_RGB);
glTexSubImage3D(
GL_TEXTURE_2D_ARRAY,
0,
0, 0,
1, //index
width, height,
1, //depth
GL_RGBA, GL_UNSIGNED_BYTE,
image);
SOIL_free_image_data(image);
Does anyone use this feature and try to use it before?
Would you mind to give me some advice on how to make it work?