GL_ACTIVE_ATTRIBUTES always returns 0 attribs, but they still work... how ?

Started by
4 comments, last by JohnnyCode 8 years, 8 months ago

Hello!

I am using the following code while loading my shaders, before linking... The 3 glBindAttribLocation calls at the beginning do all the job (they actually work), but the following listing does not show any attribs, because glGetProgramiv (_program, GL_ACTIVE_ATTRIBUTES, &numActiveAttribs) always returns 0 (zero) in the variable passed by reference. How can that be? My attribs are definitely working, otherwise I would not be able to see my shading and textures, etc... So, why does glGetProgramiv with GL_ACTIVE_ATTRIBUTES behave so strange? Can anybody help with fixing it please? Thanks in advance!



    glBindAttribLocation (_program, GLKVertexAttribPosition,    "position");
    glBindAttribLocation (_program, GLKVertexAttribNormal,      "normal");
    glBindAttribLocation (_program, GLKVertexAttribTexCoord0,   "texcoord0");
    
    NSLog(@"Listing all bindAttribs:");
    
    GLint numActiveAttribs = -1;
    GLint maxAttribNameLength = -1;
    
    glGetProgramiv (_program, GL_ACTIVE_ATTRIBUTES, &numActiveAttribs);
    glGetProgramiv (_program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribNameLength);
    
    for (int i = 0; i < numActiveAttribs; ++i) {
        
        int nameLength = -1, size = -1;
        GLenum type = GL_ZERO;
        char name[maxAttribNameLength];
        glGetActiveAttrib (_program, i, maxAttribNameLength, &nameLength, &size, &type, name);
        GLuint location = glGetAttribLocation(_program, name);
        NSLog (@"%i: %s", location, name);
    }

Advertisement

You say you are doing this before calling glLinkProgram()? That would be your bug. Attributes aren't active until after linking.

Attribute variables have arbitrary names and obtain their values through numbered generic vertex attributes. An attribute variable is considered active if it is determined during the link operation that it may be accessed during program execution. Therefore, program should have previously been the target of a call to glLinkProgram, but it is not necessary for it to have been linked successfully. (source)


You can however assign them explicit locations before linking, via glBindAttribLocation().

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]


You can however assign them explicit locations before linking, via glBindAttribLocation()

Thank you for your answer. The problem is that I want to know the names of the atrtibutes prior to binding, because I want to determine the set of bound attribs in runtime when loading the shader, so that I could link the attributes with my params later on rendering stage. Therefore I need to know the names of the locations of attributes.
Say, I have a shader which receives everything except normals or everything except texture coords. A call to glBindAttribLocation would then complain that it cannot find a named attribute 'normal' or 'texcoord0' if the are not used in the shader code itself. So, how do I know which attribs (with their respective names) to bind when loading and building the shader without parsing the shader code manually?

To be more specific, I get the following:


Program link log: WARNING: Could not find vertex shader attribute 'normal' to match BindAttributeLocation request.

(I am not using the 'normal' attribute in the shader here, for example)

The program still compiles and links and works, but I wanted to get rid of those annoying warnings, and not just silence them, but to get rid of the cause.


So, how do I know which attribs (with their respective names) to bind when loading and building the shader without parsing the shader code manually?

Do exactly what you showed in the first post, but call glLinkProgram() first.

You won't have the warnings if you don't call glBindAttribLocation(), and the linking step will assign default locations to all attributes.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

If it is viable in your case of designing, you should consider some cpu-side data describing particular shaders you plan to use, or incorporate some construction technique for shaders if you want it more arbitrary-ready.

In opengl there are calls that operate only on the current state, and there is no workaround.

This topic is closed to new replies.

Advertisement