OpenGL ES 2.0 несколько мешей?(просто примеры из реального мира) - PullRequest
7 голосов
/ 25 октября 2010

Я немного запутался в этом вопросе.

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

И я схожу с ума от этого: Как разместить и управлять несколькими объектами (сетками) с OpenGL ES 2.x?

Теоретически кажется простым.У вас есть Вершинный шейдер (vsh) и Фрагментный шейдер (fsh), затем вы связываете обе программы с одной Программой (glGenProgram, glUseProgram, ...).В каждом цикле рендеринга эта Программа будет выполнять свой VSH для каждой вершины, а после этого будет выполнять FSH для каждого «пикселя» этого 3d-объекта и, наконец, отправлять окончательный результат в буфер (очевидно, без разговоров о каждой вершине,растеризация и другие шаги в конвейере).

ОК, кажется простым ...

Все это вызывается вызовом функции рисования (glDrawArrays или glDrawElements).

ОК, снова.

Теперь все приходит в замешательство.А если у вас есть несколько объектов для рендеринга?

Давайте поговорим о примере из реального мира.Представьте, что у вас есть пейзаж с деревьями и персонаж.Трава ландшафта имеет одну текстуру, деревья имеют текстуру ствола и листьев (Атлас текстур) и, наконец, персонаж имеет другую текстуру (Атлас текстур) и тоже анимирован.

После представления этой сцены мойВопрос прост: как вы это организуете?

Вы создаете отдельную Программу (с одним VSH и FSH) для каждого элемента на сцене?Как Программа для рельефа травы и почвы, Программа для деревьев и Программа для персонажа?

Я пробовал это, но ... когда я создаю несколько Программ и пытаюсь использовать glVertexAttribPointer ()текстуры и цвета объектов вступают в конфликт друг с другом.Поскольку расположение атрибутов, индексов первой Программы повторяется во второй Программе.

Позвольте мне объяснить, я использовал glGetAttribLocation () в одном классе, который управляет полом сцены, поэтому ядро ​​OpenGLвернул мне индекс 0,1 и 2 для атрибутов вершин.После того, как в классе деревьев я создал другую Программу, другие шейдеры, и после повторного использования glGetAttribLocation () в это время ядро ​​OpenGL возвращает с индексами 0, 1, 2 и 3.

После вВ цикле рендеринга я начал устанавливать первую Программу с помощью glUseProgram () и внес изменения в атрибуты ее вершин с помощью glVertexAttribPointer () и, наконец, вызова glDrawElements ().После этого снова вызовите glUseProgram () для второй Программы и снова используйте glVertexAttribPointer () и, наконец, glDrawElements ().Но в этот момент все вступает в конфликт, потому что атрибуты индексов вершин второй Программы также влияют на вершины первой Программы.

Я много чего перепробовал, много искал, спросилмного ... я усталЯ не могу найти, что не так.

Поэтому я начал думать, что все делаю неправильно!

Теперь я повторяю свой вопрос еще раз: как работать с несколькими сетками (с разнымитекстуры и поведение) в OpenGL ES 2.x?Используете несколько программ?Как?

Ответы [ 2 ]

2 голосов
/ 26 октября 2010

Чтобы нарисовать несколько сеток, просто вызовите glDrawElements / glDrawArrays несколько раз.Если эти сетки требуют разных шейдеров, просто установите их.ОДИН, и активна только ОДНА шейдерная программа.

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

0 голосов
/ 26 октября 2010

Спасибо за ответ,

Но я думаю, что вы просто повторяете мои собственные слова ... о методах Draw, об одной активной программе, обо всем.

Что угодно.

Дело в том, что твои слова дают мне понимание!Вы сказали: «вам нужно сбросить все атрибуты вершин и указатели».

Ну ... не совсем сброшено, но то, что я не обновлял ВСЕ атрибуты вершин в цикле рендеринга, например, координаты текстуры.Я обновлял только те атрибуты, которые меняются.И когда я очистил буферы, я потерял старые значения.

Теперь я начинаю обновлять ВСЕ атрибуты, независимо от того, изменяются они или нет, все работает!

Видите, что у меня было раньшеэто:

glCreateProgram();
...
glAttachShader();
glAttachShader();
...
glLinkProgram();
glUseProgram();
...
glGetAttribLocation();
glVertexAttribPointer();
glEnableVertexAttribArray();
...
glDrawElements();

Я повторил процесс для второй Программы, но просто несколько раз вызвал glVertexAttribPointer ().

Теперь у меня есть вызов glVertexAttribPointer () для ALLАтрибуты.

Меня сводило с ума то, что если я удалил Первый блок кода в первую Программу, вся вторая Программа работала нормально.Если я удалил Второй блок кода во вторую Программу, первый работал нормально.

Теперь кажется таким очевидным.Конечно, если VSH является операцией для каждой вершины, он будет работать с нулевым значением, если я не обновлю ВСЕ атрибуты и униформу.Я думаю, что OpenGL больше похож на 3D-движок, который работает с трехмерными объектами, имеет сцену, где вы размещаете свои объекты, устанавливаете освещение.Но не ... OpenGL просто знает о треугольниках, линиях и точках, не более того.Теперь я думаю по-другому.

В любом случае, смысл в том, что теперь я могу двигаться вперед!

Спасибо

...