为什么 glGetSubroutineIndex returns 不同函数的值相同?
Why glGetSubroutineIndex returns the same value for different function?
我有一个片段着色器应该操作 2 种颜色 - 红色和蓝色。
#version 460 core
layout (location = 0) out vec4 outColor;
subroutine vec4 colorRedBlue();
subroutine (colorRedBlue)
vec4 redColor()
{
return vec4(1.0, 0.0, 0.0, 1.0);
}
subroutine (colorRedBlue)
vec4 blueColor()
{
return vec4(0.0, 0.0, 1.0, 1.0);
}
subroutine uniform colorRedBlue myRedBlueSelection;
void main()
{
outColor = myRedBlueSelection();
}
当我计算出 glGetSubroutineIndex(shaderProgram, GL_FRAGMENT_SHADER, "redColor");
和 glGetSubroutineIndex(shaderProgram, GL_FRAGMENT_SHADER, "blueColor");
它们是相同的数字:4294967295
为什么它们是相同的数字?我做错了什么?
如果您想检索有关子程序索引的信息,您必须使用 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());
子程序索引对应的子程序名可以通过glGetActiveSubroutineName
获取。
但我建议使用布局限定符在着色器代码中指定子例程索引 - 参见 Shader Subroutine - In-shader specification:
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;
注意,一个着色器阶段的所有子例程统一体的所有子例程必须由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() );
我有一个片段着色器应该操作 2 种颜色 - 红色和蓝色。
#version 460 core
layout (location = 0) out vec4 outColor;
subroutine vec4 colorRedBlue();
subroutine (colorRedBlue)
vec4 redColor()
{
return vec4(1.0, 0.0, 0.0, 1.0);
}
subroutine (colorRedBlue)
vec4 blueColor()
{
return vec4(0.0, 0.0, 1.0, 1.0);
}
subroutine uniform colorRedBlue myRedBlueSelection;
void main()
{
outColor = myRedBlueSelection();
}
当我计算出 glGetSubroutineIndex(shaderProgram, GL_FRAGMENT_SHADER, "redColor");
和 glGetSubroutineIndex(shaderProgram, GL_FRAGMENT_SHADER, "blueColor");
它们是相同的数字:4294967295
为什么它们是相同的数字?我做错了什么?
如果您想检索有关子程序索引的信息,您必须使用 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());
子程序索引对应的子程序名可以通过glGetActiveSubroutineName
获取。
但我建议使用布局限定符在着色器代码中指定子例程索引 - 参见 Shader Subroutine - In-shader specification:
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;
注意,一个着色器阶段的所有子例程统一体的所有子例程必须由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() );