MODERN OPENGL не может изменить юниформ-значение между вызовами glDrawArrays

EDIT: мне удалось решить проблему, переустановив PyOpenGL с помощью pip. Эта же программа теперь работает как положено. Спасибо за ваши усилия.

Вопрос полностью переписан и уточнен.

Проблема заключается не в (хотя и странных) подходах к созданию и связыванию текстур, как объясняется в комментариях.

Моя реальная проблема заключается в том, что юниформ-переменные в шейдерах не обновляют свои значения при изменении (да, изменении вне шейдера) между вызовами glDrawArrays(). Я проверил это, используя разные типы униформ, разные значения и проверяя их значения путем рендеринга в текстуру.

Похоже, что значения униформы блокируются, как только вызывается glDrawArrays(). После этого я могу изменить их снова только после очистки буфера цвета.

Я готов вознаградить за любое работающее решение. Публикация любого исходного кода, на мой взгляд, бесполезна, так как проблема, похоже, НЕ в коде.

Любые предложения приветствуются.


person xXliolauXx    schedule 31.01.2016    source источник
comment
Как вы проверяете значение? Можете ли вы создать минимально воспроизводимый пример?   -  person Colonel Thirty Two    schedule 31.01.2016
comment
Я проверил значения несколькими способами, включая использование переданного значения в качестве цвета или использование его внутри оператора if. Я постараюсь отфильтровать все лишнее, чтобы привести соответствующий пример.   -  person xXliolauXx    schedule 31.01.2016
comment
Ваша проблема не в опубликованном коде. В связанном коде есть очевидные проблемы, но соответствующий код необходимо разместить в самом вопросе. Опять же, это было бы очень похоже на то, о чем здесь спрашивали много раз. Вы путаете понятия текстурных блоков и текстурных идентификаторов (имен). См., например, мой ответ здесь: stackoverflow.com/q/30006525/3530129. Или для более подробного объяснения, которое охватывает дополнительные концепции: stackoverflow.com/q/30960403/3530129.   -  person Reto Koradi    schedule 01.02.2016
comment
@Reto Koradi Спасибо за вклад, я прочитал другие ответы и соответствующим образом изменил свою программу. Насколько я понимаю, теперь я должен иметь возможность переключаться между текстурами, просто обновляя значение в форме tex, она по-прежнему рисует одну и ту же текстуру для всех вызовов glDrawArrays. Тем не менее, любая помощь приветствуется.   -  person xXliolauXx    schedule 01.02.2016
comment
@Reto Koradi, кстати, я все еще думаю, что проблема заключается в том, что я не могу изменить значение Uniforms между вызовами glDrawArrays(). Что заставляет меня так думать, так это тот факт, что текстура переключается (хотя и для всех вызовов отрисовки), когда я изменяю значение, которое изначально передается в форму tex.   -  person xXliolauXx    schedule 01.02.2016
comment
К сожалению, проблема почти наверняка кроется в вашем коде, если только у вас нет действительно странной ошибки в вашей системе. OpenGL очень непостоянен, и, возможно, что-то, что имеет лишь отдаленное отношение, искажает состояние, так что по какой-то причине обновление юниформа не выполняется ожидаемым образом, может быть привязана неправильная программа или неправильное местоположение юниформы и т. д., которые все очень трудно диагностировать без фактического кода. Даже если это настоящая ошибка в ваших драйверах OpenGL, ее очень сложно локализовать без работающего исходного кода.   -  person dognotdog    schedule 03.02.2016
comment
PS: Судя по тому, как вы это изложили, в вашей покадровой настройке происходит что-то, отличающееся от цикла, который вы опубликовали ранее. Возможно, ваш код чертежа для каждой модели изменяет что-то, что препятствует обновлению униформы.   -  person dognotdog    schedule 03.02.2016
comment
@dognotdog Хорошо, тогда я пройду через это и отфильтрую все звонки ogl ... Немного, это придется подождать до полудня. Спасибо за ваши старания.   -  person xXliolauXx    schedule 03.02.2016


Ответы (1)


Вы можете обновлять униформу между вызовами отрисовки, для этого они и предназначены.

Глядя на вставленный код, и как указано в комментариях, строки 167..169 должны работать случайно для небольших texId, но вы действительно должны изменить

glUniform1i(textureUnif, model.texId)
glActiveTexture(GL_TEXTURE0+model.texId)
glBindTexture(GL_TEXTURE_2D, model.texId)

to

glUniform1i(textureUnif, 0)
glActiveTexture(GL_TEXTURE0)
glBindTexture(GL_TEXTURE_2D, model.texId)

хотя, поскольку все, что вы используете, это GL_TEXTURE0, вам действительно нужен только вызов glBindTexture() на каждой итерации цикла. Униформа текстуры должна содержать блок текстуры, в этом случае шейдер не имеет понятия идентификатора текстуры.

Конечно, так как это OpenGL, часто бывает трудно найти ошибки. Что вы вообще пытаетесь нарисовать? Скриншоты были бы кстати.

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

person dognotdog    schedule 01.02.2016
comment
Я вознагражу награду за ваш ответ, хотя он не совсем решил проблему, но он хороший. Было бы стыдно тратить 50 повторений;) - person xXliolauXx; 09.02.2016