Matthew Hoggan
Matthew Hoggan

Reputation: 7604

GLSL 4.5: Why is my "in" variable for Color Not Being Found by glGetAttribLocation

Here is the vertex shader

#version 450

in vec3 iPosition;
in vec4 iColor;

out vec4 oColor;

uniform mat4 uMVP;

void main()
{
  oColor = iColor;
  gl_Position = uMVP * vec4(iPosition, 1.0);
}

Here is the fragment shader

#version 450

in vec4 iColor;

out vec4 oColor;

void main()
{
  oColor = iColor;
}

Short of pasting all my code, here is what I have done:

  1. 1) I have glGetError after every call to a Open GL function call. I get no errors until I call glGetAttribLocation on the iColor variable in the vertex shader.

  2. I have the following code after right after calling glCompileShader and glLinkProgram respectivly:


GLint isCompiled = 0;
glGetShaderiv(m_fragmentShader, GL_COMPILE_STATUS, &isCompiled); GL_CALL
if(isCompiled == GL_FALSE) {
  GLint maxLength = 0;
  glGetShaderiv(m_fragmentShader, GL_INFO_LOG_LENGTH, &maxLength); GL_CALL
  std::vector<GLchar> errorLog(maxLength);
  glGetShaderInfoLog(m_fragmentShader, maxLength, &maxLength, &errorLog[0]);
  GL_CALL
  std::stringstream out;
  std::copy(errorLog.begin(), errorLog.end(), std::ostream_iterator<char>(
    out, ""));
  qDebug() << out.str().c_str();
  glDeleteShader(m_fragmentShader); GL_CALL
  QCoreApplication::exit(-1);
}

 GLint isLinked = 0;
 glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, (int *)&isLinked);
 if(isLinked == GL_FALSE) {
   GLint maxLength = 0;
   glGetProgramiv(m_shaderProgram, GL_INFO_LOG_LENGTH, &maxLength); GL_CALL
   std::vector<GLchar> infoLog(maxLength);
   glGetProgramInfoLog(m_shaderProgram, maxLength, &maxLength, &infoLog[0]);
   GL_CALL
   std::stringstream out;
   std::copy(infoLog.begin(), infoLog.end(), std::ostream_iterator<char>(
     out, ""));
   qDebug() << out.str().c_str();
   glDeleteProgram(m_shaderProgram); GL_CALL
   glDeleteShader(m_vertexShader); GL_CALL
   glDeleteShader(m_fragmentShader); GL_CALL
   QCoreApplication::exit(-1);
 }
  1. I have tried to change the version back to 150 but that gives the same error. I know that some implementations will optimize out variables. But I am clearly using this one to determine the color.

  2. I intend to go back in version control history and see what change brought about this error but that might take me a bit.

If it helps here is the simplified version of the draw function:

void Spline::draw()                          
{ 
  glUseProgram(m_shaderProgram); GL_CALL     

  GLint posAttrib = glGetAttribLocation(m_shaderProgram, "iPosition"); GL_CALL
  GLint colAttrib = glGetAttribLocation(m_shaderProgram, "iColor"); GL_CALL

  glBindBuffer(GL_ARRAY_BUFFER, m_vbo); GL_CALL 
  std::size_t stride = verts::traits::stride;

  std::size_t dimension1 = verts::datum_type::internal_type1::dimension; 
  std::size_t byte_offset1 = verts::traits::type1_byte_offset;
  glEnableVertexAttribArray(posAttrib); GL_CALL 
  glVertexAttribPointer(posAttrib, dimension1, GL_FLOAT, GL_FALSE,
    stride, (void*)byte_offset1); GL_CALL    

  std::size_t dimension2 = verts::datum_type::internal_type2::dimension; 
  std::size_t byte_offset2 = verts::traits::type2_byte_offset;
  glEnableVertexAttribArray(colAttrib); GL_CALL 
  glVertexAttribPointer(colAttrib, dimension2, GL_FLOAT, GL_FALSE,
    stride, (void*)byte_offset2); GL_CALL    

  opengl_math::matrix_4X4<float, opengl_math::column> model(
    opengl_math::identity);                  
  opengl_math::matrix_4X4<float, opengl_math::column> view =
    opengl_math::look_at<float, opengl_math::column>(
      opengl_math::point_3d<float>(0.0f, 0.0f, 20.0f),
      opengl_math::point_3d<float>(0.0f, 0.0f, 0.0f),
      opengl_math::vector_3d<float>(0.0f, 1.0f, 0.0f));

  GLint uniMVP = glGetUniformLocation(m_shaderProgram, "uMVP"); GL_CALL
  glUniformMatrix4fv(uniMVP, 1, GL_FALSE,    
    (m_projection * view * model).to_gl_matrix()); GL_CALL

  glDrawArrays(GL_LINE_STRIP, 0, m_vertexAttrib.get_attribute_count());
  GL_CALL
}

Upvotes: 0

Views: 87

Answers (1)

BDL
BDL

Reputation: 22174

You are using iColor as input name in both shader stages. Since fragment shader attributes cannot be queried, you have to make sure that name are unique through the shader. You can do this by using the following code:

Vertex:

#version 450

in vec3 iPosition;
in vec4 iColor;

out vec4 xColor;

uniform mat4 uMVP;

void main()
{
    xColor = iColor;
    gl_Position = uMVP * vec4(iPosition, 1.0);
}

Fragment:

#version 450

in vec4 xColor;

out vec4 oColor;

void main()
{
    oColor = xColor;
}

Upvotes: 3

Related Questions