Почему glGetSubroutineIndex возвращает одно и то же значение для другой функции? - PullRequest
0 голосов
/ 19 октября 2018

У меня есть фрагментный шейдер, который должен работать с 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();
}

, когда я cout glGetSubroutineIndex(shaderProgram, GL_FRAGMENT_SHADER, "redColor"); и glGetSubroutineIndex(shaderProgram, GL_FRAGMENT_SHADER, "blueColor");

, они совпадают:4294967295

Почему они совпадают?Что я сделал не так?

1 Ответ

0 голосов
/ 19 октября 2018

Если вы хотите получить информацию об индексах подпрограмм, вы должны использовать 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() );
...