glGetUniformIndices не возвращает правильный индекс - PullRequest
4 голосов
/ 10 января 2012

Я пытаюсь научиться использовать единообразные объекты буфера, читая OpenGL Superbible 5. У меня есть единообразный блок в моем шейдере:

layout(std140) uniform SkeletonBlock  
{  
    vec3 position[64];  
    vec4 orientation[64];  
} Skeleton;

Теперь мой код для получения индекса:

const GLchar* uniformNames[2] =
{
    "SkeletonBlock.position",
    "SkeletonBlock.orientation"
};

GLuint uniformIndex[2];
glGetUniformIndices(shaderProgram, 2, uniformNames, uniformIndex);

По какой-то причине этот звонок дает мне действительно высокий индекс (4294967295, последовательно), и я не уверен почему. Я чувствую, что упускаю что-то очевидное. OpenGL сообщает об одном активном унифицированном блоке, который является правильным, из максимально допустимого значения 15. Флажки ошибок не активны ни до, ни после этого раздела кода. Любые предложения, где это может пойти не так?

Ответы [ 3 ]

2 голосов
/ 20 января 2012
layout(std140) uniform SkeletonBlock  
{  
    vec3 position[64];  
    vec4 orientation[64];  
} Skeleton;

Вот как это определение гласит:

  • Существует унифицированный блок с именем SkeletonBlock.
  • Он содержит массив из 64 vec3 s, называемый position, за которым следует массив из 64 vec4 с именем orientation.
  • Имя для всех его членов в GLSL определяется идентификатором Skeleton.

Обратите внимание на последнюю часть.В GLSL и только в GLSL массив position идентифицируется как Skeleton.position.В C ++ массив идентифицируется либо SkeletonBlock.position, либо SkeletonBlock.position[0].Дело в том, что из кода C ++ вы используете имя блока SkeletonBlock в качестве префикса, а не имя экземпляра Skeleton.

Блок SkeletonBlock имеет индекс, который можетзапросить с glGetUniformBlockIndex (обратите внимание на использование слова «Блок» и отсутствие множественности на «Индекс»).Отдельные члены униформы также имеют индексы, но они являются индексами в списке униформы.И эти переменные должны быть названы правильно.Если унифицированный блок имеет имя экземпляра, то перед членами унифицированного блока должен стоять префикс имя блока , а не имя экземпляра.

Если вы передаете эти имена в функцию OpenGLи не получая действительные индексы, то, скорее всего, у вас ошибка драйвера.

1 голос
/ 10 января 2012

Я верю, что вы хотите

const GLchar* uniformNames[2] =
{
    "Skeleton.position",
    "Skeleton.orientation"
};

Поскольку семантика языка стиля C (такого как GLSL) имеет его, вы объявляете переменную типа uniform SkeletonBlock с именем Skeleton. Следовательно, "SkeletonBlock.position" имеет вид <typename>.<member>, где вы хотите <variable>.<member>.

Документы OpenGL говорят, что вы получите GL_INVALID_INDEX от glGetUniformIndices(), если дадите ему неправильное унифицированное имя. Было бы разумно проверить каждый из возвращенных индексов по этому поводу. Держу пари, что GL_INVALID_INDEX == -1.

Кроме того, это число 4294967295 является беззнаковой интерпретацией 32-битного -1 (дополнение к двум).

0 голосов
/ 21 декабря 2015

Вы, вероятно, столкнетесь с этим, если в исходный код GLSL шейдера не ссылаются (то есть используют) переменную блочного блока. Компилятор исходного кода шейдера вообще удалит переменную из шейдера в качестве оптимизации. Затем при вызове glGetUniformIndices будет возвращено GL_INVALID_INDEX.

...