good way to debug glGetUniformLocation

I was wondering if there was a good way to debug glGetUniformLocation. I try to get a uniform variable and get a -1 back. Why would loc3 not be found? Here’s my code:

C++

  
    char *loc_strings[] = {"loc0", "loc1", "loc2", "loc3",
			   "loc4", "loc5", "loc6", "loc7",
			   "loc8", "loc9", "loc10", "loc11",
			   "loc12", "loc13", "loc14", "loc15"};
    
    int location = glGetUniformLocation(id_, loc_strings[i]);
    if (location == -1) {
      cerr << "Error retrieving " << loc_strings[i] << " for " << i << endl;
      cerr << program_ << endl;
    }
    else {
      // glUniform4f(location, x, y, z, w);
    }

Error message (with shader program)

Error retrieving loc3 for 3
uniform vec4 loc0, loc1, loc2, loc3, loc4;
uniform sampler3D tex0;
uniform sampler3D tex1;
uniform sampler2D tex2;
uniform samplerRECT tex3;

void main()
{
   vec4 t = gl_TexCoord[0];
   vec4 v;
   vec4 c;
   vec4 l = loc0; // {lx, ly, lz, alpha}
   vec4 k = loc1; // {ka, kd, ks, ns}
   vec4 g = loc2; // {1/gradrange, -gradmin/gradrange, 0, 0}
   vec4 n, w;
   v = texture3D(tex0, t.stp);
   n = (v * 2.0) - 1.0; // rescale from [0,1] to [-1,1]
   n.w = dot(n.xyz, n.xyz);
   n.w = inversesqrt(n.w);
   n = n * n.w; // n = n / length(normal)
   n.w = dot(l.xyz, n.xyz); // calculate angle between light and normal
   n.w = clamp(abs(n.w), 0.0, 1.0); // two-sided lighting, n.w = abs(cos(angle))
   w = k; // w.x = weight*ka, w.y = weight*kd, w.z = weight*ks
   w.x = k.x - w.y; // w.x = ka - kd * weight 
   w.x = w.x + k.y; // w.x = ka + kd - kd*weight 
   n.z = power(n.w, k.w); // n.z = abs(cos(angle))^ns 
   n.w = (n.w * w.y) + w.x; // n.w = abs(cos(angle))*kd+ka
   n.z = w.z * n.z; // n.z = weight*ks*abs(cos(angle))^ns 
   v.x = texture3D(tex1, t.stp);
   c = texture2D(tex2, v.wx);
   n.z = n.z * c.w;
   c.xyz = (c.xyzz * n.w) + n.z;
   gl_FragColor = c;
}

You have loc3 defined in shader but you don’t use it anywhere, so shader compiler removes it during optimization.

I’m familiar with that, but do you know why it sometimes return that it is found and crash calling glUniform4f or glUniform1i? I call glUniform* if it does not return -1 and seg faults. Why would it return a valid location and segfault setting it?

Sorry, that was a bad question. What I mean was, other times I get a positive number back and it segfaults setting calling glUniform* at that location.

In glGetUniformLocation you pass shader id, but glUniform works on currently bound shader. Can this be the cause?

I looked at that, but it seems that the last shader called is the bound one when a uniform variable is being set. It still segfaults at glUniform1i when I set a texture here:

    /* get the variable and texture locations */
    char *tex_strings[] = {"tex0", "tex1", "tex2", "tex3",
			   "tex4", "tex5", "tex6", "tex7",
			   "tex8", "tex9", "tex10", "tex11",
			   "tex12", "tex13", "tex14", "tex15"};
    for (int i = 0; i < MAX_SHADER_UNIFORMS; i++) {
      int location = glGetUniformLocation(id_, tex_strings[i]);
      if (location != -1) { // able to get that link
	//cerr << glUniform1i << endl;
	glUniform1i(location, GL_TEXTURE0 + i);
      }
    }

I don’t understand why if this shader is the active one and the glGetUniformLocation returns true, it segfaults.

When you set sampler uniforms, you need to specify index of the texture unit not corresponding enum so the correct call would be glUniform1i(location,i);