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 };
if(linkProgram(shaders, 2))
{
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)
info:shader: 0: 7 1 'a_Color'
info:shader: 1: 10 1 'a_Position'
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]
I/testgame:shader(30865): 0: -1 -1 ''
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/testgame:shader(30865): 1: -1 -1 ''
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?