Подпрограмма GLSL не изменена

Я начал изучать 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 shader\n");
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. Я не знаю, что мне не хватает.

0

Решение

glUniformSubroutinesuiv звонок ожидает n быть равным количеству активных мест подпрограммы

Вы можете получить это с:

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

увидеть вики

1

Другие решения

Я нашел проблему. Код подпрограммы должен идти перед glDrawArrays:

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 shader\n");
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();
}
0

По вопросам рекламы [email protected]