& quot; Сгенерирована ошибка GL_INVALID_VALUE. & quot; связывая только один унифицированный блок

У меня есть некоторые проблемы с привязкой объекта единого буфера к нескольким шейдерам.

Выполнение следующего кода:

for(auto& shaderIter : shaderHandler.getShaderPrograms()){
shaderIter.second->bind();
GLuint programID = shaderIter.second->programId();
GLuint index = glFuncs->glGetUniformBlockIndex(programID, "MatrixUBO");
glFuncs->glUniformBlockBinding(programID, index, UBO_MATRICES_BINDING_POINT);
shaderIter.second->release();
}

вызывает сообщение об ошибке

QOpenGLDebugMessage("APISource", 1281, "GL_INVALID_VALUE error generated. Uniform block index exceeds the maximum supported uniform buffers.", "HighSeverity", "ErrorType")

Тип шейдерных программ — QOpenGLShaderProgram. Я использую вершинные, геометрические, фрагментные и вычислительные шейдеры с этими шейдерными программами.

Значение GL_MAX_{VERTEX, FRAGMENT, GEOMETRY}_UNIFORM_BLOCKS составляет 14. Выход index для каждой программы 0, за исключением одной, где это 4294967295.

0

Решение

Невозможно привязать унифицированный блочный буфер к вычислительному шейдеру. Вот почему выходной индекс 4294967295 для программы шейдера с вычислительным шейдером.

РЕДАКТИРОВАТЬ: потому что 4294967295 является значением GL_INVALID_INDEX.

У меня есть два возможных решения:

  1. Разделите список шейдерных программ на две части. Первый для всех шейдеров рендеринга и второй для всех вычислительных шейдеров. После этого просто перебирайте рендеринг.
  2. Запросите каждый шейдер, если это вычислительный шейдер, и просто сделайте привязку для рендеринга шейдеров. Но я не знаю, есть ли возможность доступа к информации, если это рендеринг или вычислительный шейдер.

РЕДАКТИРОВАТЬ: Существует возможность получить QList всех шейдеров, связанных с шейдерной программой, и можно проверить тип каждого шейдера. Поэтому я изменил код на следующий, который работает для меня.

for(auto& shaderProgramIter : shaderHandler.getShaderPrograms()){
bool isComputeShader = false;
for(auto& shaderIter : shaderProgramIter.second->shaders())
{
if(shaderIter->shaderType() == QOpenGLShader::Compute)
isComputeShader = true;
}
if(!isComputeShader)
{
shaderProgramIter.second->bind();
GLuint programID = shaderProgramIter.second->programId();
GLuint index = glFuncs->glGetUniformBlockIndex(programID, "MatrixUBO");
glFuncs->glUniformBlockBinding(programID, index, UBO_MATRICES_BINDING_POINT);
shaderProgramIter.second->release();
}
}
0

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