GLSL 子例程未更改

GLSL subroutine is not changed

本文关键字:子例程 GLSL      更新时间:2023-10-16

我已经开始学习GLSL和OpenGL。现在我正在尝试查看 GLSL 子例程的工作原理,所以我在这里有我的片段着色器:

#version 330 core
out vec4 color;
subroutine vec4 ColorFunc();
subroutine (ColorFunc) vec4 colorBlue() {
    return vec4(0.0, 0.0, 1.0, 1.0);
}
subroutine (ColorFunc) vec4 colorGreen() {
    return vec4(0.0, 1.0, 0.0, 1.0);
}
subroutine uniform ColorFunc ColorSelector;
void main() {
    color = ColorSelector();
}

在我加载的应用程序源代码中,编译着色器链接并在开始时启动程序。将创建一个三角形,顶点着色器不会执行任何特殊操作。显示函数(发送给glutDisplayFunc的函数(如下所示:

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glBindVertexArray(TriangleVAO);
    glDrawArrays(GL_TRIANGLES, 0, NumVertices);
    GLint ColorSelectorLoc;
    GLuint colorBlueIndex;
    GLuint colorGreenIndex;
    ColorSelectorLoc = glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "ColorSelector");
    if (ColorSelectorLoc < 0)
    {
        fprintf(stderr, "Error: ColorSelector is not an active subroutine uniform in the shadern");
        exit(EXIT_FAILURE);
    }
    colorBlueIndex = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "colorBlue");
    colorGreenIndex = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "colorGreen");
    GLsizei n;
    glGetProgramStageiv(program, GL_FRAGMENT_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, &n);
    GLuint *indices = new GLuint[n];
    cout << "colorGreen: " << colorBlueIndex;
    indices[ColorSelectorLoc] = colorGreenIndex;
    glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, n, indices);
    delete [] indices;
    glFlush();
}

我期望三角形是绿色的,但它们始终是蓝色的,无论正确检索的ColorSelector的值如何(其值为 0(。 colorBlueIndex为 0,colorGreenIndex为 1。我不知道我错过了什么。

glUniformSubroutinesuiv调用期望n等于活动子例程位置的数量

你可以通过以下方式获得这个:

glGetProgramStage(program, GL_FRAGMENT_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, &n);

查看维基

我发现了问题。子例程的代码必须在 glDrawArray 之前:

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    GLint ColorSelectorLoc;
    GLuint colorBlueIndex;
    GLuint colorGreenIndex;
    ColorSelectorLoc = glGetSubroutineUniformLocation(program, GL_FRAGMENT_SHADER, "ColorSelector");
    if (ColorSelectorLoc < 0)
    {
        fprintf(stderr, "Error: ColorSelector is not an active subroutine uniform in the shadern");
        exit(EXIT_FAILURE);
    }
    colorBlueIndex = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "colorBlue");
    colorGreenIndex = glGetSubroutineIndex(program, GL_FRAGMENT_SHADER, "colorGreen");
    GLsizei n;
    glGetProgramStageiv(program, GL_FRAGMENT_SHADER, GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS, &n);
    GLuint *indices = new GLuint[n];
    cout << "colorGreen: " << colorBlueIndex;
    indices[ColorSelectorLoc] = colorGreenIndex;
    glUniformSubroutinesuiv(GL_FRAGMENT_SHADER, n, indices);
    delete [] indices;
    glBindVertexArray(TriangleVAO);
    glDrawArrays(GL_TRIANGLES, 0, NumVertices);
    glFlush();
}