Если вы хотите получить информацию об индексах подпрограмм, вы должны использовать glGetActiveSubroutineUniformiv
:
GLint no_of_subroutines;
glGetActiveSubroutineUniformiv(
shaderProgram, GL_FRAGMENT_SHADER,
0, // Index of the subroutine uniform, but NOT the location of the uniform variable
GL_NUM_COMPATIBLE_SUBROUTINES, &no_of_subroutines);
std::vector<GLint> sub_routines( no_of_subroutines );
glGetActiveSubroutineUniformiv(
shaderProgram, GL_FRAGMENT_SHADER,
0, // Index of the subroutine uniform, but NOT the location of the uniform variable
GL_COMPATIBLE_SUBROUTINES, sub_routines.data());
Имя подпрограммы, которая соответствует индексу подпрограммы, может бытьget by glGetActiveSubroutineName
.
Но я рекомендую использовать спецификатор макета для указания индексов подпрограммы в коде шейдера - см. Подпрограмма шейдера - Спецификация In-Shader :
subroutine vec4 colorRedBlue();
layout(index = 1) subroutine (colorRedBlue)
vec4 redColor()
{
return vec4(1.0, 0.0, 0.0, 1.0);
}
layout(index = 2) subroutine (colorRedBlue)
vec4 blueColor()
{
return vec4(0.0, 0.0, 1.0, 1.0);
}
layout(location = 0) subroutine uniform colorRedBlue myRedBlueSelection;
Обратите внимание, что все подпрограммы для всех подпрограмм unifroms одного этапа шейдера должны быть установлены одновременно, с помощью glUniformSubroutinesuiv
.В вашем случае это не так уж важно, потому что есть только 1 форма подпрограммы.Эта операция применяется к текущей шейдерной программе (glUsePrgram
).
Количество индексов, которые вы должны передать в glUniformSubroutinesuiv
, должно соответствовать номеру GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS
, но не номеру GL_ACTIVE_SUBROUTINE_UNIFORM
- см. glGetProgramStageiv
:
GLint nLocationCount = 0;
glGetProgramStageiv(
program, GL_FRAGMENT_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, &nLocationCount );
std::vector<GLuint> sub_routines( nLocationCount, 0 );
Glint redBlueSelection_location = 0;
sub_routines[redBlueSelection_location] = 1; // index of 'redColor` or `blueColor`
glUniformSubroutinesuiv(
GL_FRAGMENT_SHADER, (GLsizei)sub_routines.size(), sub_routines.data() );