PDA

View Full Version : GL_TEXTURE_2D_ARRAY help



JohnMcJohnson
08-15-2014, 07:56 PM
I don't really understand how to use the GL_TEXTURE_2D_ARRAY properly. I need to use it to texture various tiles. The code is mostly for testing stuff right now. This code works to the point where if I activate a texture and modify the fragment shader to use a regular 2d texture instead of an array it will draw everything correctly.

From what I understand you only need to load the images correctly then I can use them in the fragement shader without calling glActiveTexture or anything. I don't know, the example code I've seen shows it used like that.

Vertex Shader:

#version 430 core

layout (location=0) in vec4 position;
layout (location=3) in vec2 st;
layout (location=5) in float tex;
out VS_OUT{
vec2 st;
float tex;
}vs_out;
layout (location=1) uniform mat4 mv_matrix;
layout (location=2) uniform mat4 proj_matrix;
void main(void){
if (tex!=0){
vs_out.tex=tex;
vs_out.st=st;
gl_Position=position;//proj_matrix*mv_matrix*position;
}
}

Fragment Shader:

layout (binding=0) uniform sampler2DArray tex_object;
out vec4 color;
in VS_OUT
{
vec2 st;
float tex;
}fs_in;

//1.0 for testing purposes. st values seem to be correct
void main(void){
color=texture(tex_object,vec3(fs_in.st,1.0));
}

Relevant C++ code:



glEnable(GL_TEXTURE_RECTANGLE_NV);
SDL_Texture* image = NULL;
GLuint TextureID = 0;
TextureIDArray = 99999;


glBindTexture(GL_TEXTURE_2D_ARRAY, TextureIDArray);
glTexStorage3D(GL_TEXTURE_2D_ARRAY, 8, GL_RGBA, TILE_SIZE, TILE_SIZE, 100);

//Textures.push_back()
image = IMG_LoadTexture(csdl_setup->GetRenderer(), "...png");//1
if (image == NULL){
std::cout << "Error: Couldn't Load file "<< std::endl;
}
Images.push_back(image);
image = IMG_LoadTexture(csdl_setup->GetRenderer(), "...");//2
Images.push_back(image);
image = IMG_LoadTexture(csdl_setup->GetRenderer(), "...");//3
Images.push_back(image);
image = IMG_LoadTexture(csdl_setup->GetRenderer(), "...");//4
Images.push_back(image);
LoadGLTexture("...png", &TextureID);//0 this is unused actually
TextureID++;
LoadGLTexture("...png", &TextureID));//1
TextureID++;
LoadGLTexture("...png", &TextureID);//2
TextureID++;
LoadGLTexture("...png", &TextureID);//3
TextureID++;
LoadGLTexture("...png", &TextureID);//4
TextureID++;
LoadGLTexture("...png", &TextureID);//5
}

void CLoadedImages::LoadGLTexture(std::string FilePath, GLuint*TextureID){
SDL_Surface* Surface = IMG_Load(FilePath.c_str());

glGenTextures(1, TextureID);

int Mode = GL_RGB;

if (Surface->format->BytesPerPixel == 4) {
Mode = GL_RGBA;
}
if (*TextureID < 3){
glBindTexture(GL_TEXTURE_2D_ARRAY, TextureIDArray);
//GLenum target,GLint level, GLint xoffset, yoffset,zoffset, GLsizei width, h, d, GLEnum format, GLenum type, *data
GLfloat temp = *TextureID *1.0;
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0,
0, 0, temp,
TILE_SIZE, TILE_SIZE, 1,
Mode, GL_UNSIGNED_BYTE, Surface->pixels);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
else{


glBindTexture(GL_TEXTURE_2D, *TextureID);
glTexImage2D(GL_TEXTURE_2D, 0, Mode, Surface->w, Surface->h, 0, Mode, GL_UNSIGNED_BYTE, Surface->pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

}
SDL_FreeSurface(Surface);

}

JohnMcJohnson
08-17-2014, 04:29 PM
I downloaded an OpenGL debugger (GLIntercept), fixed up the file loading code(not quite sure what I was doing with that old loading code.) a bit, and then used glTexImage3D instead of glTexStorage3D and it worked fine.