Почему существует несколько способов передачи VAO в программу GLSL? - PullRequest
6 голосов
/ 01 января 2012

Пример кода:

1. glGenBuffers(1, &VboId);
2. glBindBuffer(GL_ARRAY_BUFFER, VboId);
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
5. glEnableVertexAttribArray(0);

Таким образом, «0» в строках 4 (первый аргумент) и 5 ​​относится к произвольному идентификатору / местоположению, которое мы выбрали.В GLSL, если мы хотим сослаться на эти данные, мы просто должны обратиться к одному и тому же идентификатору:

layout(location=0) in vec4 in_Position;

Однако в другом примере программы я видел, как это делается по-другому, без ссылкив «расположение мест».Вместо этого мы делаем что-то вроде этого:

1. glGenBuffers(1, &VboId);
2. glBindBuffer(GL_ARRAY_BUFFER, VboId);
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
5. glBindAttribLocation(shaderProgramHandle, 0, "in_position");
6. glEnableVertexAttribArray(0);

Мы добавили дополнительный шаг (5), где мы, кажется, привязываем указатель этого атрибута к определенной переменной в конкретной программе.И затем в нашем GLSL мы просто пишем это вместо:

in vec3 in_position;

Без ссылки на местоположение.

Если я не ошибаюсь, эти 2 программы, по сути, делают одно и то же... так почему разница?Каковы плюсы и минусы каждого метода?

(я только начал изучать OpenGL 3.x)

1 Ответ

16 голосов
/ 01 января 2012

Нет такой вещи, как передача VAO в шейдер.VAO просто устанавливает, как атрибуты вершин извлекаются из буферных объектов для рендеринга.

Второй пример ничего не делает, если shaderProgramHandle еще не был связан.glBindAttribLocation местоположение работает только до привязки программы.После того, как программа была связана, вы не можете изменить, откуда она получает свои атрибуты.

В любом случае, ваш реальный вопрос заключается в том, почему некоторые люди используют glBindAttribLocation(..., 0) вместо того, чтобы вставлять layout(location = X) в свои шейдеры.Причина очень проста: синтаксис layout(location) является (относительно) новым.glBindAttribLocation восходит к самой первой версии интерфейса OpenGL GLSL, еще в расширении ARB_vertex_shader, примерно в 2003 году.layout(location) происходит от более недавнего ARB_explicit_attrib_location, который является только ядром в GL 3.3 и выше.3.3 вышла только в 2010 году. Естественно, больше материала расскажет о старом.

«За и против» каждого из них вполне очевидны.С чисто практической точки зрения, layout(location), будучи новым, требует более свежих драйверов (хотя он не требует GL 3.3. Аппаратное обеспечение NVIDIA 6xxx + поддерживает ARB_explicit_attrib_location, несмотря на то, что оно только 2.1).glBindAttribLocation работает в исходном коде, а layout(location) встроен в сам шейдер GLSL.Поэтому, если вам нужно решить, какие атрибуты используют какие индексы во время выполнения, сделать это с layout(location) намного сложнее, чем без него.Но если, как и большинство людей, вы хотите управлять ими из шейдера, то layout(location) - это то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...