Results 1 to 7 of 7

Thread: glGetAttribLocation returning -1

  1. #1
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    3

    glGetAttribLocation returning -1

    Hello OGL Experts

    I'm currently warming up to OGL3.2 / GLSL 1.5 in C#, using OpenTK Wrapper which is close enough to the real API to make me think my issue is more an OpenGL issue than an OpenTK one.

    I have created a small vertex shader & fragment shader. My vertex shader has 3 input (color, normal, and of course, vertex) and 2 output (color, normal), which are used in my fragment shader.

    My issue, in short, is that the following code (after linking of the "ShaderProgram", to which I attached my vertex and fragment shader)

    Code :
    int positionLocation = GL.GetAttribLocation(pipeline.ShaderProgram, "in_position");
                int colorLocation = GL.GetAttribLocation(pipeline.ShaderProgram, "in_color");
                int normalLocation = GL.GetAttribLocation(pipeline.ShaderProgram, "in_normal");

    returns :

    positionLocation = 0
    colorLocation = 1
    normalLocation = -1

    The shader program compiled successfully, and glError contains "no error"...

    The vertex shader program is as follow:

    Code :
    #version 150
     
    precision highp float;
     
    uniform mat4 projection_matrix;
    uniform mat4 modelview_matrix;
     
    in vec3 in_position;
    in vec3 in_color;
    in vec3 in_normal;
     
    out vec3 normal;
    out vec3 color;
     
    void main(void)
    {
      //works only for orthogonal modelview
      normal = (modelview_matrix * vec4(in_normal, 0)).xyz;
     
      //send color information to fragment shader
      color = in_color;
     
      gl_Position = projection_matrix * modelview_matrix * vec4(in_position, 1);
    }

    So, a quite simple shader, and of course "in_normal" is there...

    Also, if I don't call EnableVertexAttribArray(normalLocation), then the code runs fine, the vertex and colors are correct. Of course, not the normals...

    Is there anything I need to set up to have more than 2 attribs?

    Thanks!

  2. #2
    Senior Member OpenGL Pro Ilian Dinev's Avatar
    Join Date
    Jan 2008
    Location
    Watford, UK
    Posts
    1,294

    Re: glGetAttribLocation returning -1

    This can only happen if in the frag-shader you're not _really_ using the "vec3 normal". Compilers can optimize-out its use, like in:
    Code :
     ...
      glFragColor = vec4(normal,1);
      glFragColor = vec4(1,2,3,4); // now "normal" gets optimized-out
    }

  3. #3
    Senior Member OpenGL Pro dletozeun's Avatar
    Join Date
    Jan 2006
    Location
    FRANCE
    Posts
    1,367

    Re: glGetAttribLocation returning -1

    Ilian is right, you are using "in_normal" to compute "normal" but then "normal" is not used for the computation of vertex shader output data. So the clever compiler just has discarded it at compilation time!

  4. #4
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    3

    Re: glGetAttribLocation returning -1

    Thank you Ilian and Dletozeun!

    Quote Originally Posted by dletozeun
    Ilian is right, you are using "in_normal" to compute "normal" but then "normal" is not used for the computation of vertex shader output data. So the clever compiler just has discarded it at compilation time!
    Are you saying I got outsmarted by a Shader Compiler ?!

    I'm not sure I understand : how am I then supposed to give data to that supposedly useless in_normal? Of course, I only use it in the Vertex Shader, not in the Fragment shader, but "normal" is used in the Fragment shader for (poor) light computations, like this :

    Code :
    #version 150
     
    precision highp float;
     
    const vec3 ambient = vec3(0.1, 0.1, 0.1);
    const vec3 lightVecNormalized = normalize(vec3(0.5, 0.5, 2));
    const vec3 lightColor = vec3(0.9, 0.9, 0.7);
     
    in vec3 normal;
    in vec3 color;
     
    out vec4 gl_FragColor; 
     
    void main(void)
    {
      float diffuse = clamp(dot(lightVecNormalized, normalize(normal)), 0.0, 1.0);
      gl_FragColor = normalize(vec4(color + ambient + diffuse * lightColor,1.0));
    }

    So, in the fragment shader, I use "normal" ... and since "normal" is an input, it must come from the vertex shader, and it's computed there from the "in_normal". In that regard, WHO is that compiler to flag "in_normal" as useless?

    More importantly, what's the key difference between "in_color" and "in_normal" ? "in_color" is even less used in the Vertex Shader, but it gets a proper location...

  5. #5
    Senior Member OpenGL Pro Ilian Dinev's Avatar
    Join Date
    Jan 2008
    Location
    Watford, UK
    Posts
    1,294

    Re: glGetAttribLocation returning -1

    The code looks alright, and "normal" is really used :S. Maybe we're missing something.
    I generally use glBindAttribLoc instead of letting the linker decide.

  6. #6
    Junior Member Newbie
    Join Date
    Oct 2009
    Posts
    3

    Re: glGetAttribLocation returning -1

    Illian,

    Out of sheer desperation, I added this before Linking my shader:

    Code :
    GL.BindAttribLocation(shaderProgram, 0, "in_position");
    GL.BindAttribLocation(shaderProgram, 1, "in_color");
    GL.BindAttribLocation(shaderProgram, 2, "in_normal");

    And now, normalLocation gets the proper value, which is 2.

    I feel that somehow, this shouldn't be necessary, a linker should be able to count inputs from 0 to 2 Is that some kind of bug in the linker? I thought I read somewhere in the specs that if no binding has been done, one will be provided anyway.

    Thanks for the hint!

    Guillaume

  7. #7
    Senior Member OpenGL Pro dletozeun's Avatar
    Join Date
    Jan 2006
    Location
    FRANCE
    Posts
    1,367

    Re: glGetAttribLocation returning -1

    Oh my mistake! Sorry. I missed the "in vec3 normal" ... So "normal" is used actually.

    Binding an attribute name to a generic attribute index does not mean that your shaders are ok. Actually, you can bind any attribute name to a generic attribute index, including names that are not used in any vertex shader. Thus, the fact that Opengl did not bind the "normal" attribute is either a driver bug or something is wrong in the shader and Opengl has thrown a compile or link error. Have you checked that?

Similar Threads

  1. Transform-feedback / glGetAttribLocation
    By art-ganseforth in forum OpenGL: Basic Coding
    Replies: 14
    Last Post: 10-03-2018, 04:54 PM
  2. glGetAttribLocation on separate shader objects
    By imported_Anteru in forum OpenGL: Basic Coding
    Replies: 0
    Last Post: 01-24-2012, 11:22 AM
  3. glGetAttribLocation and a -1 return value?
    By Mars_999 in forum OpenGL: Basic Coding
    Replies: 7
    Last Post: 02-11-2009, 02:35 AM
  4. Returning to state
    By dt in forum OpenGL: Basic Coding
    Replies: 3
    Last Post: 02-24-2005, 06:40 AM
  5. returning to glut
    By saian in forum OpenGL: Linux
    Replies: 1
    Last Post: 03-21-2002, 03:15 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean