# glGetActiveAttrib on Android NDK

In my code-base I need to link the vertex declarations from a mesh to the attributes of a shader. To do this I retrieve all the attribute names after linking the shader. I use the following code (with some added debug info since it's not really working):

int shaders[] = { m_ps, m_vs };
{
ASSERT(glIsProgram(m_program) == GL_TRUE, "program is invalid");

int attrCount = 0;
GL_CHECKED(glGetProgramiv(m_program, GL_ACTIVE_ATTRIBUTES, &attrCount));

int maxAttrLength = 0;
GL_CHECKED(glGetProgramiv(m_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttrLength));

LOG_INFO("shader", "got %d attributes for '%s' (%d) (maxlen: %d)", attrCount, name, m_program, maxAttrLength);

m_attrs.reserve(attrCount);

GLsizei attrLength = -1;
GLint attrSize = -1;
GLenum attrType = 0;

char tmp[256];
for(int i = 0; i < attrCount; i++)
{
tmp[0] = 0;
GL_CHECKED(glGetActiveAttrib(m_program, GLuint(i), sizeof(tmp), &attrLength, &attrSize, &attrType, tmp));
LOG_INFO("shader", "%d: %d %d '%s'", i, attrLength, attrSize, tmp);
m_attrs.append(String(tmp, attrLength));
}
}


GL_CHECKED is a macro that calls the function and calls glGetError() to see if something went wrong. This code works perfectly on Windows 7 using ANGLE and gives this this output:

info:shader: got 2 attributes for 'static/simplecolor.glsl' (3) (maxlen: 11)


But on my Nexus 7 (1st gen) I get the following (the errors are the output from the GL_CHECKED macro):

I/testgame:shader(30865): got 2 attributes for 'static/simplecolor.glsl' (3) (maxlen: 11)
E/testgame:gl(30865): 'glGetActiveAttrib(m_program, GLuint(i), sizeof(tmp), &attrLength, &attrSize, &attrType, tmp)' failed: INVALID_VALUE [jni/src/../../../../src/Game/Asset/ShaderAsset.cpp:50]
E/testgame:gl(30865): 'glGetActiveAttrib(m_program, GLuint(i), sizeof(tmp), &attrLength, &attrSize, &attrType, tmp)' failed: INVALID_VALUE [jni/src/../../../../src/Game/Asset/ShaderAsset.cpp:50]


I.e. the call to glGetActiveAttrib gives me an INVALID_VALUE. The opengl docs says this about the possible errors:

GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.

This is not the case, I added an ASSERT to make sure glIsProgram(m_program) == GL_TRUE, and it doesn't trigger.

GL_INVALID_OPERATION is generated if program is not a program object.

Different error.

GL_INVALID_VALUE is generated if index is greater than or equal to the number of active attribute variables in program.

i is 0 and 1, and the number of active attribute variables are 2, so this isn't the case.

GL_INVALID_VALUE is generated if bufSize is less than 0.

Well, it's not zero, it's 256.

Does anyone have an idea what's causing this? Am I just lucky that it works in ANGLE, or is the nvidia tegra driver wrong?

After lots of trial and error I found that calling glDetachShader(...) on the vertex shader before glGetActiveAttrib(...) will lead to the results I saw. I can't find anything about this in the docs, so I assume it's implementation specific.