Когда это связано с ВАО?

Я изучаю OpenGL в течение трех дней, и я могу сделать что-то полезное, но мне нравится копировать вставку, не зная, что я делаю. Я серьезно думаю, что мне не хватает базового понимания того, когда именно это (VBO, атрибуты …) привязаны к объекту вершинного массива (VAO) и не нашли никаких ресурсов, которые подробно разъясняют эти аспекты.

В частности, это некоторые из моих проблем. Если я создаю ВАО:

GLuint vao; glGenVertexArrays(1, &vao); 

может ли что-нибудь связать его, прежде чем я свяжу VAO? (если я создаю VBO сейчас, это связано с VAO?)

 glBindVertexArray(vao); 

После связывания VAO, если я создаю VBO:

 GLuint vbo; glGenBuffers(1, &vbo); 

это связано с ВАО? Или это происходит, когда я связываю его?

 glBindVertexArray(vbo); 

Или, может быть, когда я что-то копирую?

Если я получаю местоположение атрибута:

 att = glGetAttribLocation(program_id, "name"); 

это связано с ВАО? Или это происходит после включения:

 glEnableVertexAttribArray(att); 

… или после установки:

 glVertexAttribPointer(att, ...); 

?

Я думаю, что EBO ведут себя так же, как VBOs, поэтому я надеюсь, что применяются те же «правила».

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

Теперь о развязывании:

Если я «привяжу» VBO к VAO, а затем отвяжу VBO, он будет отсоединен от VAO?

Если у меня есть VBO, связанный с несколькими VAO, что произойдет, когда я отвяжу VBO?

И об освобождении ресурсов:

Что происходит, когда я удаляю VBO? Удаляется ли из всех ВАО? Или у них все еще есть «болтающиеся ссылки» на этот VBO?

И о программах:

IIUC Я могу повторно использовать VBOs между программами. Однако, если VAO связывают атрибуты и VBOs, а атрибуты принимают программный параметр, могу ли я повторно использовать VAO между программами? Почему атрибуты принимают параметр программы вообще?

А насчет отладки:

Есть ли способ распечатать конечный автомат OpenGL? Мне хотелось бы узнать, какие программы были связаны между собой, с какими шейдерами, в которых существуют VAO, какие VBOs привязаны к каким VAO, какие атрибуты связаны с VAO и VBOs, были ли они установлены? разрешены ли они? какая форма существует …

И о розыгрыше звонков:

Предположим, кто-то дает мне ВАО, и я должен его нарисовать. Есть ли способ узнать, следует ли мне звонить glDrawArrays или glDrawElements? Могу ли я как-то запросить эту информацию из ВАО? Может быть, наряду с размерами моих VBOs, хранящихся там?

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

Главное, чтобы понять, что VAO – это совокупность состояний . У него нет данных. Это VBOs, которые владеют данными вершин. С другой стороны, VAO содержит все состояние, используемое для описания того, откуда получает вызов draw от его атрибутов вершин. Это включает в себя для каждого атрибута:

  • Если он включен.
  • Какой буфер хранит атрибут.
  • На каком смещении в буфере начинаются данные.
  • Интервал между последующими атрибутами (иначе говоря, шаг).
  • Тип данных.
  • Количество компонентов.

Плюс один раз:

  • Какой буфер массива элементов связан.

Сопоставляя это для вызовов API, следующие вызовы меняют состояние, отслеживаемое связанным в настоящее время VAO:

  • glEnableVertexAttribArray(...)
  • glDisableVertexAttribArray(...)
  • glVertexAttribPointer(...)
  • glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)

Обратите внимание, что это не включает текущую привязку GL_ARRAY_BUFFER . Буфер, используемый для каждого атрибута, отслеживается косвенно, основываясь на том, какой буфер был привязан при glVertexAttribPointer() для конкретного атрибута.

Это должно заложить основу для конкретных вопросов:

Если я создаю VAO, может ли что-нибудь связать его, прежде чем я свяжу VAO?

Нет. VAO необходимо связать, прежде чем вы сможете изменить любое состояние, сохраненное в нем.

(если я создаю VBO сейчас, это связано с VAO?)

Нет. Вы можете связать VBO, прежде чем связывать VAO, и заполнить VBO данными, используя glBufferData() . VBO – это, по сути, просто немой контейнер данных. Но любая настройка атрибутов вершин, отслеживаемая в VAO, может быть выполнена только после привязки VAO.

Если я получаю местоположение атрибута, он связан с VAO?

Нет, glGetAttribLocation() делает только то, что предлагает название, которое получает местоположение атрибута. Он не меняет никакого состояния. Вы будете использовать расположение атрибутов для вызовов типа glEnableVertexAttribArray() и glVertexAttribPointer() .

Или это происходит после включения его … или после его установки

Связь атрибута с данным VBO устанавливается, когда вы вызываете glVertexAttribPointer() то время как данный VBO связан.

Я думаю, что EBO ведут себя так же, как VBOs, поэтому я надеюсь, что применяются те же «правила».

В основном, но не полностью. Связывание GL_ELEMENT_ARRAY_BUFFER является частью состояния, хранящегося в VAO. Это имеет смысл, потому что для вызова рисования используется только один буфер массива элементов (в то время как атрибуты вершин могут поступать из нескольких разных буферов массивов), и нет отдельного вызова, который указывает «использовать данные индекса из текущего буфера массива связанных элементов », например, glVertexAttribPointer() указывает« использовать данные вершин из текущего связанного буфера массива ». Вместо этого это происходит неявно, когда вы вызываете glDrawElements() . Следовательно, буфер массива элементов должен быть привязан во время вызова рисования, и это связывание является частью состояния VAO.

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

Верный. Униформа связана с шейдерными программами, а не с VAO.

Если я «привяжу» VBO к VAO, а затем отвяжу VBO, он будет отсоединен от VAO?

Нет. Я считаю, что это уже объяснено выше.

Если у меня есть VBO, связанный с несколькими VAO, что произойдет, когда я отвяжу VBO?

Поскольку ничего не происходит с одним VAO, все еще ничего с несколькими VAO.

Что происходит, когда я удаляю VBO? Удаляется ли из всех ВАО? Или у них все еще есть «болтающиеся ссылки» на этот VBO?

Это один из темных углов OpenGL. Если вы можете читать точные правила удаления для всех типов объектов (они не все одинаковые), вы достигли продвинутого уровня … В этом случае VBO автоматически не привязано от текущего связанного VAO , но не от других VAO которые в настоящее время не связаны. Если другие VAO имеют ссылки на VBO, VBO останется в живых до тех пор, пока все эти привязки не будут сломаны или удалены VAO.

Однако, если VAO связывают атрибуты и VBOs, а атрибуты принимают программный параметр, могу ли я повторно использовать VAO между программами?

Да, вы можете использовать VAO для нескольких программ. Состояние программы и состояние VAO являются независимыми. Расположение атрибута вершины в программе указывает, какой атрибут вершин используется для источника значений для каждого attribute / переменной в вершинном шейдере.

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

Есть ли способ распечатать конечный автомат OpenGL?

Существуют glGet*() которые позволяют получить почти все текущее состояние OpenGL. Не удобно, но все это доступно. Многие платформы / вендоры также предоставляют инструменты разработчика, которые позволяют вам смотреть в состояние OpenGL в определенный момент выполнения вашей программы.

Предположим, кто-то дает мне ВАО, и я должен его нарисовать. Есть ли способ узнать, следует ли мне звонить glDrawArrays или glDrawElements?

Это необычный сценарий. В большинстве случаев вы создаете VAO, чтобы вы знали, как его рисовать. Или, если кто-то другой создал его, вы попросите их нарисовать его. Но если вам это действительно нужно, вы можете получить glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, ...) связанный буфер массива элементов с помощью glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, ...) .

таблицу VAO можно найти в разделе « Государственные таблицы» спецификации

в коде psuedo это выглядит так:

 struct VAO{ GL_INT element_array_binding; //IBO used for glDrawElements and friends char* label;//for debugging struct{//per attribute values bool enabled; //whether to use a VBO for it //corresponding to the values passed into glVertexAttribPointer call int size; unsigned int stride; GL_ENUM type; bool normalized; bool integer; //unconverted integers bool long; //double precision void* offset; int bufferBinding;//GL_ARRAY_BUFFER bound at time of glVertexAttribPointer call int attributeDiviser; //as used for instancing } attributes[MAX_VERTEX_ATTRIBS]; }; 

В частности, отсутствует состояние программы (которое связано, равномерные значения и т. Д.),

  • Как установить GLUT и OpenGL в Visual Studio 2012?
  • Вращение объекта вокруг неподвижной точки с помощью glMultMatrix
  • как включить вертикальную синхронизацию в opengl?
  • OpenGL определяет положение вершин в пикселях
  • как я должен обрабатывать (морфинг) 4D-объекты в opengl?
  • GCC, строение и встроенный GLSL?
  • Можно ли вращать объект вокруг своей оси, а не вокруг оси базовой оси?
  • Что делает glLoadIdentity () в OpenGL?
  • Нарисуйте прямоугольник на qglwidget в определенное время
  • Как использовать glOrtho () в OpenGL?
  • Как отключить или обойти ускорение аппаратной графики (Prism) в JavaFX
  • Interesting Posts

    Как заставить Mac перейти в состояние грязного выключения при каждом отключении питания?

    appSettings vs applicationSettings. appSettings устарел?

    Как удалить элемент из списка по индексу в Python?

    BadImageFormatException. Это произойдет при работе в режиме 64 бит с установленными 32-битными клиентскими компонентами Oracle

    Как доказать, что файл не подделан?

    Выберите диалог папки WPF

    Объединение двух выражений (выражение <Func >)

    Как экспортировать адреса электронной почты из Apple Mail?

    Как я могу использовать / создать динамический шаблон для компиляции динамического компонента с угловым 2.0?

    Почему почтовые клиенты не используют непосредственно SMTP-сервер получателя

    Не удалось загрузить Google в iframe в fancybox

    Пользовательский вид annotations в SDK Google Maps

    Что за и против: положить javascript в голову и поставить перед телом закрыть

    Как разбить систему Linux?

    Доступ к глобальной статической переменной из другого файла в C

    Давайте будем гением компьютера.