Конфликт при использовании двух или более шейдеров с разным количеством атрибутов - PullRequest
3 голосов
/ 14 марта 2012

Я пытаюсь реализовать сбор (используя цвета и readPixels) в моей программе WebGL. Когда я запускаю свою программу, я создаю отдельную программу ShaderProgram. Один для затенения по фонгу, а другой просто придает фигурам цвет, который будет использоваться для определения, по какой фигуре щелкнули.

Фонг шейдер имеет 2 атрибута. Положение вершины и вершина нормальная. У выбора просто есть позиция.

Теперь я обнаружил, что по какой-то странной причине, когда оба этих шейдера существуют в одной и той же программе, а я использую комплектующий, мой вызов drawArray, похоже, завершается неудачно. Последнее, что должно произойти, это мой вызов gl.vertexAttribPointer. Я возился и обнаружил, что когда я проверяю активные массивы атрибутов, используя: gl.getVertexAttrib (индекс, gl.VERTEX_ATTRIB_ARRAY_ENABLED);

оба 0,1 возвращают true (это когда шейдер выбора активен с помощью gl.useProgram (picking))

Теперь, если я отключу 1 с помощью gl.disableVertexAttribArray (1); Все снова работает. Другое исправление - сначала рисовать с помощью шейдера Phong, а затем использовать шейдер выбора, и это каким-то волшебным образом делает все нормально. Я предполагаю, что в этом случае при подключении моего буфера нормалей вершин при использовании шейдера phong он каким-то образом остается, когда я затем переключаюсь на шейдер выбора и вызов drawArray работает.

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

Я также безуспешно пытался создавать шейдерные программы в другом порядке.

Ответы [ 3 ]

3 голосов
/ 15 марта 2012

Как вы, наверное, поняли, useProgram ни на что не влияет, кроме программы (кода шейдера), которая должна быть запущена при следующем вызове отрисовки. Вы должны убедиться, что включены только атрибуты, используемые текущей программой.

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

1 голос
/ 14 марта 2012

Трудно сказать, не видя ваш код, но ... WebGL требует, чтобы все атрибуты, к которым будет осуществляться доступ, имели достаточно данных, чтобы удовлетворить вызов отрисовки. Итак, если вы устанавливаете 2 атрибута, каждый из которых имеет 3 вершины данных, и рисуете 3 вершины, то переключаете шейдеры и настраиваете атрибут 1 с 6 вершинами, оставляя второй атрибут только с 3 вершинами, а затем пытайтесь рисовать с 6 вершинами, если В настоящее время рисование с доступом к обоим атрибутам WebGL завершится неудачно.

Если вы запускаете Chrome 19, он должен сообщить вам в консоли JavaScript, была ли это проблема.

1 голос
/ 14 марта 2012

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

Многие люди попадают в неправильное и плохое привычка, чтобы предположить, что когда-то было что-то вродеинициализация "с OpenGL.Это не вариант.Вы должны установить все состояние, необходимое для какой-либо операции рисования, непосредственно перед этой операцией рисования, а в идеале также вернуть настройки после завершения.Это означает: после связывания шейдера вы также должны включить и связать необходимые входные данные шейдера, или атрибуты вершины.

...