I am learning shader subroutines and wrote a toy program along the lines of one in the shading language cookbook (I also referred to the recent red book edn.). The program seems to run fine.
In the application program in the initialization routine, I get my two subroutine function indexes with two calls to glGetSubroutineIndex(). Then, in the drawing routine:
glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &firstSubroutineIndex);
// Enable vertex attribute arrays and drawing statement for object1
glUniformSubroutinesuiv( GL_VERTEX_SHADER, 1, &secondSubroutineIndex);
// Enable vertex attribute arrays and drawing statement for object2
So, here’s my question:
I don’t seem to need glGetSubroutineUniformLocation(), which the cookbook makes no use of, but which the RB seems to indicate as needed. What gives? Do we need the subroutine uniform location or not? Maybe for some cases we do…
Thanks in advance for your clarification,
glGetSubroutineUniformLocation is used to know which index is assoicate with which subroutine uniform. The first index is not necessarily the index of the first subroutine uniform. If I remember correctly nVidia do them in order and AMD do them reverse order (but it can change at any time). If you only have one subroutine uniform then you don’t have a problem knowing the index.
I think I see what you mean and there’s a bit in the RB which seems to indicate something similar. But I have a follow-up question in that case.
So, a subroutine can be of multiple types. Here’s the relevant extract from the RB:
subroutine void Type_1();
subroutine void Type_2();
subroutine void Type_3();
subroutine (Type_1, Type_2) Func_1();
subroutine (Type_1, Type_3) Func_2();
subroutine uniform Type_1 func_1;
subroutine uniform Type_2 func_2;
subroutine uniform Type_3 func_3;
So, in this case if I want to call subroutine Func_1, I need to specify if Type_1 (uniform variable func_1) or Type_2 (uniform func_2). Therefore, I need to set the uniform as well, not just the subroutine index. Makes sense.
But glGetSubroutineUniformLocation() only gets a uniform location. But how do I set it? In other words, e.g., above how would I specify subroutine Func_1 of, say, Type_1?
Type_1 are uniforms. The uniforms here are
glGetSubroutineUniformLocation retrieves the index in the array of values for that particular uniform. The location is just the index, not the actual subroutine. Just like for regular uniforms, the location is the value you need to specify the uniform’s actual data, not the data itself.
Setting those uniforms requires getting the uniform locations, then building an array, where at each location you specify the proper value. Then you use
glSubroutineUniforms to set those uniforms.
If you have explicit_uniform_location, you can set subroutine indices and subroutine uniform locations manually in the shader, so you don’t have to query them.
Thank you, Alfonse.
However, I can’t find the command glSubroutineUniforms() in the 4.x docs. Can you say again how to set a uniform?
It’s the function you mentioned: glUniformSubroutine. I just wrote it backwards.
Thanks again, Alfonse.
I was actually confused by your initial response but that was because I was missing the point that glUniformSubroutine() takes as parameter an array indexed by subroutine uniforms with values equal to the chosen subroutine index. The example at the bottom of the RB page also clarifies this.