Attaching multiple shaders of the same type -- confusing (or contradictory?) docs

Hello,
I was trying to figure out whether I’m allowed to attach multiple shader objects of the same type (such as GL_FRAGMENT_SHADER) to a single program object. The OpenGL ES 2.0 reference appears to contradict itself on the matter, however:

From glAttachShader:
Multiple shader objects of the same type may not be attached to a single program object.

But from glUseProgram:
A program object will contain executables that will run on the vertex and fragment processors if it contains one or more shader objects of type GL_VERTEX_SHADER and one or more shader objects of type GL_FRAGMENT_SHADER that have all been successfully compiled and linked.

I’ve only tested it on Broadcoms OpenGL ES 2.0 implementation so far, and it seems to allow attaching multiple shaders to a single program object. However, if some implementations do not support that, I cannot use it, of course.

Regards,
Jonathan Ringstad

Hi Jonathan,

I don’t see how attaching multiple shader objects of the same type to a single program object can work. When you call glUseProgram() there is no parameter that specifies which fragment or vertex shader to use. How did you do this on the Broadcom platform? I suspect that Broadcom’s driver is just not reporting the error.
Did you call glGetError() after the glAttachShader() call?

I agree the documentation for glUseProgram() is misleading and should be corrected.

Regards, Clay

I don’t see how attaching multiple shader objects of the same type to a single program object can work. When you call glUseProgram() there is no parameter that specifies which fragment or vertex shader to use.

I was imagining it to work similar to how linking C objects would work; you could define functions in one object, then declare and use them in another:

lib.vsh:


float calculate_this_or_that(float input){
    ...
}

main.vsh:


float calculate_this_or_that(float input);
void main(void){
    float result = calculate_this_or_that(2.0f);
}

Linking them together in one program object would then enable main.vsh to use calculate_this_or_that() from lib.vsh. I found some random quotes through google searches that suggested it would work like this (in desktop OpenGL), but I haven’t tried whether it actually works myself yet – perhaps when I attached the second shader to the program object, it simply replaced the first one.

If it doesn’t work like this, how is this problem typically solved? Creating a small pre-processor that can include functions from libraries into a given shader source prior to compilation?

Regards,
Jonathan Ringstad

Yes, in OpenGL ES, when you attach the second shader to the program object, it would simply replace the first one.

The usual solution is to include functions in the source before compiling, as you said, or you can compile multiple versions of the program and select one with glUseProgram() when you are ready to render.

On some platforms, it’s possible to use pre-compiled binary shaders to eliminate the time to compile the programs from your run-time, but this is not supported well on most platforms.

Regards, Clay

Thank you for the clarification, I appreciate your time.

I have also filed a bug against the OpenGL ES 2.0 “Man Pages & Other Documentation” component, asking for disambiguation of the previously cited text.

Regards,
Jonathan Ringstad

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.