Передача юниформы вершинному шейдеру приводит к тому, что он не отображает четырехугольник.

Я работаю над 2D-проектом с использованием OpenGL 3.2, и у меня есть следующий очень простой вершинный шейдер.

#version 150

in vec2 pos;

void main() { 
    gl_Position = vec4(pos.x, pos.y, 0, 1); 
}

Затем, используя массив и индексный буфер, я рисую на экране простой четырехугольник, и все работает нормально. Проблема возникает, когда я хочу передать матрицу преобразования. Это происходит из класса 2D-камер, поэтому можно добиться поворота экрана и масштабирования. что я обнаружил, так это то, что как только я передаю матрицу 4x4 как униформу, все перестает отображаться (или быть видимым).

Пройдясь по коду, я вижу, что когда дело доходит до обновления униформы, передаваемая матрица представляет собой идентификационную матрицу 4x4, как и ожидалось, потому что камера пока не делает ничего особенного. Я ожидаю, что применение единичной матрицы должно привести к тому же результату, как если бы она вообще не умножалась.

Обновленный шейдер выглядит следующим образом:

#version 150

in vec2 pos;
uniform mat4 MVP;

void main() { 
    gl_Position = MVP * vec4(pos.x, pos.y, 0, 1); 
}

Униформа обновляется с помощью glUniformMatrix4fv(mvpPos, 1, GL_FALSE, &m[0][0]);

Я в недоумении, почему это происходит, поэтому буду признателен за любую идею. Я знаю, что код не опубликован, но я рад опубликовать любые конкретные части, на которые нужно обратить внимание, и я не хотел засорять первоначальный вопрос стеной, возможно, не относящегося к делу кода.

Обновление: я протестировал объявление mat4 непосредственно в шейдере со значениями матрицы идентичности. Замена MVP этой матрицей означает, что она работает, что указывает на проблему в обновлении униформы через glUniformMatrix4fv.


person Zammalad    schedule 26.09.2014    source источник


Ответы (2)


Проблема в том, что вы устанавливаете значение в неправильном месте. Вы должны вызвать glGetUniformLocation вместо передачи 0 в первый аргумент вызов glUniform*.

i.e.

GLint mvpLocation = glGetUniformLocation(program, "MVP");
// ...
glUniformMatrix4fv(mvpLocation, 1, GL_FALSE, &m[0][0]);
person cobbal    schedule 26.09.2014
comment
На самом деле я сохраняю единое местоположение и передаю переменную. Я просто использовал 0 в примере для простоты, так как это то, что в любом случае передается при отладке. - person Zammalad; 26.09.2014
comment
Ой. Тогда это странно, ваш код выглядит довольно безобидным для меня. Несколько вещей, в которых нужно быть уверенным: убедитесь, что вы ловите любые ошибки компиляции шейдера. проверьте наличие glGetErrors. убедитесь, что m имеет тип GLFloat и является непрерывным. Если вы сделали все это, вы можете попробовать отправить значения из MVP во фрагментный шейдер, чтобы вы могли отлаживать их как цвета. Кроме того, боюсь, я ничем не могу помочь. - person cobbal; 26.09.2014

Проведя дополнительное расследование с использованием glGetError() и gluErrorString(), я обнаружил, что он выдает GL_INVALID_OPERATION. К сожалению, это немного расплывчато, но мне посчастливилось встретить кого-то еще, у кого была такая же проблема.

Это было так же просто, как я забыл привязать программу перед вызовом обновления униформы, поскольку раньше я делал это только при рендеринге, и мне не нужно было использовать шейдер в каких-либо обновлениях.

person Zammalad    schedule 26.09.2014