SinisterMJ
SinisterMJ

Reputation: 3509

glGetAttribLocation returns not found

I have code trying to upload data into an OpenGL shader, but when I call glGetAttribLocation() going for the array of data I am looking for, it always returns -1 as location (thus not found). I have no idea how to debug this issue in the first place, since the variables are in the code (albeit the vertex shader only passes it on to the geometry shader).

Can someone help me figure out why the glGetAttribLocation returns not found? Other items, like worldMatrix for example, when using glGetUniformLocation(), work just fine.

C++ Code trying to get the attribute id:

for (unsigned int i = 0; i < _nNumCameras; ++i) {
    const auto glName = "texcoords[" + std::to_string(i) + "]";
    const auto location = glGetAttribLocation(id(), glName.c_str());
    if (location == -1) {
        continue;
    }

Vertex Shader:

#version 430
#define NUM_CAMERAS 3
uniform mat4 worldMatrix;
uniform mat4 viewProjMatrix;

layout(location = 0)in vec3 position;
layout(location = 1)in vec3 normal;
layout(location = 2)in float radius;

in vec2 texcoords[NUM_CAMERAS];
in uint cameraIds[NUM_CAMERAS];

out vec4 gl_Position;
out VS_OUT {
    vec2 v_texCoords[NUM_CAMERAS];
    vec3 v_normal;
    uint cameraIDs[NUM_CAMERAS];
} vs_out;

void main()
{    
    gl_Position.xyz = position.xyz;
    gl_Position.w = 1;
    gl_Position = worldMatrix * gl_Position;
    gl_Position = viewProjMatrix * gl_Position;
    vs_out.v_texCoords = texcoords;
    vs_out.cameraIDs = cameraIds;
    vs_out.v_normal = normal;
}

Geometry Shader:

#version 430
#define NUM_CAMERAS 3
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;

out VS_OUT {
    vec2 v_texCoords[NUM_CAMERAS];
    vec3 v_normal;
    uint cameraIDs[NUM_CAMERAS];
} gs_in[];

out GS_OUT {
    vec2 v_texcoord;
} gs_out;

flat out uint camera_id_unique;

void main() {
    // Code selecting best camera texture
    ...
    ///

    gl_Position = gl_in[0].gl_Position; 
    gs_out.v_texcoord = gs_in[0].v_texCoords[camera_id_unique];
    EmitVertex();
        
    gl_Position = gl_in[1].gl_Position;
    gs_out.v_texcoord = gs_in[1].v_texCoords[camera_id_unique];   
    EmitVertex();
    
    gl_Position = gl_in[2].gl_Position; 
    gs_out.v_texcoord = gs_in[2].v_texCoords[camera_id_unique];  
    EmitVertex();
    
    EndPrimitive();
}

Fragment Shader:

#version 430
#define NUM_CAMERAS 3
uniform sampler2D colorTextures[NUM_CAMERAS];

in GS_OUT {
    vec2 v_texcoord;
} fs_in;

flat in uint camera_id_unique;

out vec4 color;

void main(){
    color = texture(colorTextures[camera_id_unique], fs_in.v_texcoord);
}

Upvotes: 2

Views: 169

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473192

Arrayed program resources work in different ways depending on whether they are arrays of basic types or arrays of structs (or arrays). Resources that are arrays of basic types only expose the entire array as a single resource, whose name is "name[0]" and which has an explicit array size (if you query that property). Other arrayed resources expose separate names for each array element.

Since texcoords is an array of basic types, there is no "texcoords[2]" or "texcoords[1]"; there is only "texcoords[0]". Arrayed attributes are always assigned contiguous locations, the locations for indices 1 and 2 will simply be 1 or 2 plus the location for index 0.

Upvotes: 1

Related Questions