PDA

View Full Version : Shader subroutines: when to call glGetSubroutineUniformLocation()?



sam_thedancer
04-27-2013, 02:33 AM
Greetings:
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,
Sam

tonyo_au
04-27-2013, 02:55 AM
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.

sam_thedancer
04-27-2013, 09:40 AM
Thanks, tonyo_au.
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?

Thanks again.

Alfonse Reinheart
04-27-2013, 06:44 PM
Neither `Func_1` nor `Type_1` are uniforms. The uniforms here are `func_1`, `func_2`, and `func_3`. `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 (http://www.opengl.org/registry/specs/ARB/explicit_uniform_location.txt), you can set subroutine indices and subroutine uniform locations manually in the shader, so you don't have to query them.

sam_thedancer
04-27-2013, 10:10 PM
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?

Alfonse Reinheart
04-27-2013, 11:38 PM
It's the function you mentioned: glUniformSubroutine. I just wrote it backwards.

sam_thedancer
04-28-2013, 04:46 AM
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.