glGetActiveAttrib on Android NDK

Posted by user408952 on Game Development See other posts from Game Development or by user408952
Published on 2014-05-30T19:21:29Z Indexed on 2014/05/30 22:11 UTC
Read the original article Hit count: 309

Filed under:
|
|

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?

© Game Development or respective owner

Related posts about android

Related posts about opengl-es2